MDL-40006 searchableselector does not work in IE or Safari.
[moodle.git] / lib / form / searchableselector.js
CommitLineData
09179b78 1// This file is part of Moodle - http://moodle.org/
2//
3// Moodle is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// Moodle is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
15
16/**
17 * javascript for a searchable select type element
18 *
19 * @package formlib
20 * @copyright 2009 Jerome Mouneyrac
21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22 */
23
24selector = {
25 select: null,
26 input: null,
27 button: null,
0d4075d5
TH
28 goodbrowser: false,
29 alloptions: [],
09179b78 30
31 filter_init: function(strsearch, selectinputid) {
0d4075d5
TH
32 selector.goodbrowser = !(' ' + document.body.className + ' ').match(/ ie | safari /);
33
09179b78 34 // selector.id = selectinputid
35 selector.select = document.getElementById(selectinputid);
36 selector.button = document.getElementById('settingssubmit');
37
0d4075d5
TH
38 // Copy all selector options into a plain array. selector.select.options
39 // is linked live to the document, which causes problems in IE and Safari.
40 for (var i = 0; i < selector.select.options.length; i++) {
41 selector.alloptions[i] = selector.select.options[i];
42 }
43
09179b78 44 // Create a div to hold the search UI.
45 var div = document.createElement('div');
46 div.id = 'searchui';
47
48 // Find the capability search input.
49 var input = document.createElement('input');
50 input.type = 'text';
51 input.id = selectinputid+'_search';
52 selector.input = input;
53
54 // Create a label for the search input.
55 var label = document.createElement('label');
56 label.htmlFor = input.id;
57 label.appendChild(document.createTextNode(strsearch + ' '));
58
59 // Tie it all together
60 div.appendChild(label);
61 div.appendChild(input);
62 selector.select.parentNode.insertBefore(div, selector.select);
0d4075d5 63 input.addEventListener('keyup', selector.filter_change);
09179b78 64 },
65
66 filter_change: function() {
67 var searchtext = selector.input.value.toLowerCase();
0d4075d5
TH
68 var found = false;
69 for (var i = 0; i < selector.alloptions.length; i++) {
70 var option = selector.alloptions[i];
71 if (option.text.toLowerCase().indexOf(searchtext) >= 0) {
72 // The option is matching the search text.
73 selector.set_visible(option, true);
74 found = true;
09179b78 75 } else {
0d4075d5 76 selector.set_visible(option, false);
09179b78 77 }
78 }
03221650 79
0d4075d5
TH
80 if (found) {
81 // No error.
09179b78 82 selector.input.className = "";
0d4075d5
TH
83 } else {
84 // The search didn't find any matching, color the search text in red.
85 selector.input.className = "error";
09179b78 86 }
0d4075d5 87 },
09179b78 88
0d4075d5
TH
89 set_visible: function(element, visible) {
90 if (selector.goodbrowser) {
91 if (visible) {
92 element.style.display = 'block';
93 } else {
94 element.style.display = 'none';
95 element.selected = false;
96 }
97 } else {
98 // This is a deeply evil hack to make the filtering work in IE.
99 // IE ignores display: none; on select options, but wrapping the
100 // option in a span does seem to hide the option.
101 // Thanks http://work.arounds.org/issue/96/option-elements-do-not-hide-in-IE/
102 if (visible) {
103 if (element.parentNode.tagName.toLowerCase() === 'span') {
104 element.parentNode.parentNode.replaceChild(element, element.parentNode); // New, old.
105 }
106 element.enabled = true;
107 } else {
108 if (element.parentNode.tagName.toLowerCase() !== 'span') {
109 var span = document.createElement('span');
110 element.parentNode.replaceChild(span, element); // New, old.
111 span.appendChild(element);
112 span.style.display = 'none';
113 }
114 element.enabled = false;
115 element.selected = false;
116 }
117 }
09179b78 118 }
d3067516 119};