From 0d4075d51439eb94027ddda2124a9d53ab8a217b Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Sat, 6 Sep 2014 22:27:11 +0100 Subject: [PATCH] MDL-40006 searchableselector does not work in IE or Safari. This fix is a horrible hack, but one I have used for years in tool_editrolesbycap https://github.com/moodleou/moodle-tool_editrolesbycap/blob/master/yui/capabilityformfield/capabilityformfield.js and it seems to be reliable. As an added bonus, I removed the use of YUI2 here. Also, I fixed the related button in quiz to be GET not POST. --- lib/form/searchableselector.js | 75 ++++++++++++++++++++++++---------- mod/quiz/overrides.php | 2 +- 2 files changed, 55 insertions(+), 22 deletions(-) diff --git a/lib/form/searchableselector.js b/lib/form/searchableselector.js index dbd3f5129d3..13632b28ebd 100644 --- a/lib/form/searchableselector.js +++ b/lib/form/searchableselector.js @@ -25,12 +25,22 @@ selector = { select: null, input: null, button: null, + goodbrowser: false, + alloptions: [], filter_init: function(strsearch, selectinputid) { + selector.goodbrowser = !(' ' + document.body.className + ' ').match(/ ie | safari /); + // selector.id = selectinputid selector.select = document.getElementById(selectinputid); selector.button = document.getElementById('settingssubmit'); + // Copy all selector options into a plain array. selector.select.options + // is linked live to the document, which causes problems in IE and Safari. + for (var i = 0; i < selector.select.options.length; i++) { + selector.alloptions[i] = selector.select.options[i]; + } + // Create a div to hold the search UI. var div = document.createElement('div'); div.id = 'searchui'; @@ -50,37 +60,60 @@ selector = { div.appendChild(label); div.appendChild(input); selector.select.parentNode.insertBefore(div, selector.select); - YUI().use('yui2-event', function(Y) { - Y.YUI2.util.Event.addListener(input, 'keyup', selector.filter_change); - }); + input.addEventListener('keyup', selector.filter_change); }, filter_change: function() { var searchtext = selector.input.value.toLowerCase(); - var options = selector.select.options; - var matchingoption = -1; - for (var i = 0; i < options.length; i++) { - var optiontext = options[i].text.toLowerCase(); - if (optiontext.indexOf(searchtext) >= 0) { //the option is matching the search text - options[i].disabled = false; //the option must be visible - options[i].style.display = 'block'; - if (matchingoption == -1) { //we found at least one - matchingoption = i; - } + var found = false; + for (var i = 0; i < selector.alloptions.length; i++) { + var option = selector.alloptions[i]; + if (option.text.toLowerCase().indexOf(searchtext) >= 0) { + // The option is matching the search text. + selector.set_visible(option, true); + found = true; } else { - options[i].disabled = true; - options[i].selected = false; - options[i].style.display = 'none'; + selector.set_visible(option, false); } } - if (matchingoption == -1) { //the search didn't find any matching, color the search text in red - selector.input.className = "error"; - } else { + if (found) { + // No error. selector.input.className = ""; + } else { + // The search didn't find any matching, color the search text in red. + selector.input.className = "error"; } + }, + set_visible: function(element, visible) { + if (selector.goodbrowser) { + if (visible) { + element.style.display = 'block'; + } else { + element.style.display = 'none'; + element.selected = false; + } + } else { + // This is a deeply evil hack to make the filtering work in IE. + // IE ignores display: none; on select options, but wrapping the + // option in a span does seem to hide the option. + // Thanks http://work.arounds.org/issue/96/option-elements-do-not-hide-in-IE/ + if (visible) { + if (element.parentNode.tagName.toLowerCase() === 'span') { + element.parentNode.parentNode.replaceChild(element, element.parentNode); // New, old. + } + element.enabled = true; + } else { + if (element.parentNode.tagName.toLowerCase() !== 'span') { + var span = document.createElement('span'); + element.parentNode.replaceChild(span, element); // New, old. + span.appendChild(element); + span.style.display = 'none'; + } + element.enabled = false; + element.selected = false; + } + } } - }; - diff --git a/mod/quiz/overrides.php b/mod/quiz/overrides.php index 4b904f74e6b..7814b108b0b 100644 --- a/mod/quiz/overrides.php +++ b/mod/quiz/overrides.php @@ -272,7 +272,7 @@ if ($groupmode) { } echo $OUTPUT->single_button($overrideediturl->out(true, array('action' => 'adduser', 'cmid' => $cm->id)), - get_string('addnewuseroverride', 'quiz'), 'post', $options); + get_string('addnewuseroverride', 'quiz'), 'get', $options); } echo html_writer::end_tag('div'); echo html_writer::end_tag('div'); -- 2.43.0