68 var MultiSelectBox = MultiSelectBox || {};
70 if(window.console && console && console.log)
71 MultiSelectBox.dbg = console.log.bind(window.console);
74 function $(id) {
return document.getElementById(
id);}
79 MultiSelectBox.mySelects_ = {};
80 MultiSelectBox.omnis_ = {};
81 MultiSelectBox.isSingleSelect_ = {};
82 MultiSelectBox.lastOptSelect_ = {};
84 MultiSelectBox.selInitBoxHeight_ = {};
85 MultiSelectBox.SEL_INIT_PADDING = 5;
87 MultiSelectBox.requireCtrlMultiClick_ = {};
92 MultiSelectBox.hasClass =
function(ele,cls)
94 return !!ele.className.match(
new RegExp(
'(\\s|^)'+cls+
'(\\s|$)'));
97 MultiSelectBox.addClass =
function(ele,cls)
99 if (!MultiSelectBox.hasClass(ele,cls)) ele.className +=
" "+cls;
102 MultiSelectBox.removeClass =
function(ele,cls)
104 if (MultiSelectBox.hasClass(ele,cls))
106 var reg =
new RegExp(
'(\\s|^)'+cls+
'(\\s|$)');
107 ele.className=ele.className.replace(reg,
'');
111 MultiSelectBox.toggleClass =
function(ele,cls)
114 if (MultiSelectBox.hasClass(ele,cls))
116 var reg =
new RegExp(
'(\\s|^)'+cls+
'(\\s|$)');
117 ele.className=ele.className.replace(reg,
'');
122 ele.className +=
" " + cls;
127 MultiSelectBox.getSelectedIndex =
function(el)
131 var selects = MultiSelectBox.mySelects_[el.getElementsByClassName(
"mySelect")[0].id];
132 for(var i=0;i<selects.length;++i)
133 if(selects[i])
return i;
138 var splits = el.id.split(
'_');
139 return splits[splits.length-1] | 0;
142 MultiSelectBox.getSelectionArray =
function(el)
147 if(el.parentElement.id.indexOf(
"selbox-") == 0)
148 return MultiSelectBox.mySelects_[el.parentElement.id];
150 return MultiSelectBox.mySelects_[el.getElementsByClassName(
"mySelect")[0].id];
154 MultiSelectBox.getSelectedCount =
function(el)
158 var selects = MultiSelectBox.mySelects_[el.getElementsByClassName(
"mySelect")[0].id];
160 for(var i=0;i<selects.length;++i)
161 if(selects[i]) ++cnt;
169 MultiSelectBox.getSelectionElementByIndex =
function(el,i)
171 if(el.parentElement.id.indexOf(
"selbox-") == 0)
172 return document.getElementById(el.parentElement.parentElement.
173 getElementsByClassName(
"mySelect")[0].
id +
176 return document.getElementById(el.getElementsByClassName(
"mySelect")[0].id +
180 MultiSelectBox.setSelectionElementByIndex =
function(el,i,selected)
182 var name = el.getElementsByClassName(
"mySelect")[0].id;
184 if(!MultiSelectBox.isSingleSelect_[name] &&
187 var size = MultiSelectBox.mySelects_[name].length;
188 for (var opt=0; opt<size; opt++)
189 MultiSelectBox.mySelects_[name][opt] = selected?1:0;
193 if(MultiSelectBox.isSingleSelect_[name] &&
196 var size = MultiSelectBox.mySelects_[name].length;
197 for (var opt=0; opt<size; opt++)
198 MultiSelectBox.mySelects_[name][opt] = 0;
200 MultiSelectBox.mySelects_[name][i] = selected?1:0;
204 MultiSelectBox.myOptionSelect =
function(option, index, isSingleSelect, event)
206 var select = option.parentElement;
207 var
id = select.getAttribute(
"id");
208 var selectList = MultiSelectBox.mySelects_[id];
209 var size = select.childNodes.length;
212 MultiSelectBox.dbg(
"Shift click = " + event.shiftKey);
215 MultiSelectBox.dbg(
"Control click = " + event.ctrlKey);
223 if (!selectList || selectList.length!=size)
225 MultiSelectBox.mySelects_[id] = [];
226 MultiSelectBox.lastOptSelect_[id] = -1;
227 selectList=MultiSelectBox.mySelects_[id];
228 for (var opt=0; opt<size; opt++)
233 MultiSelectBox.toggleClass(option,
"optionhighlighted");
234 selectList[index] ^= 1;
237 (MultiSelectBox.requireCtrlMultiClick_[
id] && !event.ctrlKey && !event.shiftKey))
238 for (var opt=0; opt<size; opt++)
241 var cindex = select.childNodes[opt].id.split(
"_");
242 cindex = cindex[cindex.length-1];
244 if(cindex == index)
continue;
245 else if(selectList[cindex] == 1)
247 MultiSelectBox.toggleClass(select.childNodes[opt],
"optionhighlighted");
248 selectList[cindex] = 0;
251 else if(event.shiftKey &&
252 MultiSelectBox.lastOptSelect_[
id] != -1)
259 var lo = MultiSelectBox.lastOptSelect_[id] < index?
260 MultiSelectBox.lastOptSelect_[id]:index;
261 var hi = MultiSelectBox.lastOptSelect_[id] < index?
262 index:MultiSelectBox.lastOptSelect_[id];
266 for (var opt=lo; opt<=hi; opt++)
270 if(selectList[opt] !=
271 selectList[MultiSelectBox.lastOptSelect_[
id]])
275 MultiSelectBox.toggleClass(select.childNodes[opt],
"optionhighlighted");
276 selectList[opt] ^= 1;
281 MultiSelectBox.dbg(selectList);
282 selected = selectList;
283 MultiSelectBox.lastOptSelect_[id] = index;
292 MultiSelectBox.createSelectBox =
function(el,name,title,vals,keys,types,
293 handler,noMultiSelect,mouseOverHandler,iconURLs,mouseDownHandler,
295 requireCtrlMultiClick,titles)
298 { MultiSelectBox.dbg(
"Invalid Element given to MultiSelectBox: " + el);
299 throw new Error(
"Invalid Element given to MultiSelectBox: " + el);
return; }
303 name =
"selbox-" + name;
304 MultiSelectBox.addClass(el,
"multiselectbox");
306 MultiSelectBox.omnis_[name] = el;
307 MultiSelectBox.isSingleSelect_[name] = noMultiSelect;
308 MultiSelectBox.lastOptSelect_[name] = -1;
309 MultiSelectBox.selInitBoxHeight_[name] = 0;
310 MultiSelectBox.requireCtrlMultiClick_[name] = requireCtrlMultiClick;
313 var msW = (!el.offsetWidth?el.style.width.split(
'p')[0]:el.offsetWidth) - 28 - 5 - 16 - 2;
314 var msH = (!el.offsetHeight?el.style.height.split(
'p')[0]:el.offsetHeight) - 40 - 2;
316 el = document.createElement(
"div");
317 MultiSelectBox.omnis_[name].appendChild(el);
323 str +=
"<div id='" + name +
"header' " +
324 "style='margin-top:20px; width:100%; white-space:nowrap; height:21px'><b>";
329 if(!keys) keys = vals;
330 if(!types) types = vals;
333 str +=
"<table cellpadding='0' cellspacing='0'>";
335 str +=
"<div class='mySelect' unselectable='on' id='" +
336 name +
"' style='float:left;" +
337 "width: " + (msW) +
"px;" +
338 "height: " + (msH) +
"px;" +
339 "' name='" + name +
"' " +
342 for (var i = 0; i < keys.length;++i)
344 str +=
"<div class='myOption' " +
345 "id='" + name +
"-option_" + i +
"' " +
346 "onclick='MultiSelectBox.myOptionSelect(this, " + i +
"," +
347 noMultiSelect +
", event); ";
348 if(handler && (typeof handler) ==
"string")
349 str += handler +
"(this,event);";
351 str += handler.name +
"(this,event);";
354 str +=
"onmouseover='";
355 if(mouseOverHandler && (typeof mouseOverHandler) ==
"string")
356 str += mouseOverHandler +
"(this,event);";
357 else if(mouseOverHandler)
358 str += mouseOverHandler.name +
"(this,event);";
361 str +=
"onmousedown='";
362 if(mouseDownHandler && (typeof mouseDownHandler) ==
"string")
363 str += mouseDownHandler +
"(this,event);";
364 else if(mouseDownHandler)
365 str += mouseDownHandler.name +
"(this,event);";
368 str +=
"onmouseup='";
369 if(mouseUpHandler && (typeof mouseUpHandler) ==
"string")
370 str += mouseUpHandler +
"(this,event);";
371 else if(mouseUpHandler)
372 str += mouseUpHandler.name +
"(this,event);";
376 str +=
"title='" + titles[i] +
"' ";
378 str +=
"key-value='" + keys[i] +
"' type-value='" +
380 if(iconURLs && iconURLs[i])
382 if(iconURLs[i][0] !=
'=')
383 str +=
"<img style='width:32px; height:32px; margin: 0px 5px -8px 0;' " +
385 iconURLs[i] +
"' />";
387 str += iconURLs[i].substr(1) +
" - ";
396 str +=
"</td><td valign='top'>";
398 str += MultiSelectBox.makeSearchBar(name);
399 str +=
"</td></table>";
404 var el = document.getElementById(name);
406 el.style.width = 200 +
"px";
412 MultiSelectBox.initMySelectBoxes =
function(clearPreviousSelections)
414 var divs=document.getElementsByClassName(
'mySelect');
415 for (var el=0; el<divs.length; el++)
417 var select = divs[el];
419 var
id = select.getAttribute(
"id");
420 var options = select.childNodes;
421 MultiSelectBox.lastOptSelect_[id] = -1;
422 if (!MultiSelectBox.mySelects_[
id] ||
423 MultiSelectBox.mySelects_[
id].length > options.length)
425 if(!MultiSelectBox.mySelects_[
id] || clearPreviousSelections)
426 MultiSelectBox.mySelects_[id]=[];
427 for (var opt=0; opt<options.length; opt++)
429 if(clearPreviousSelections || opt >= MultiSelectBox.mySelects_.length)
430 MultiSelectBox.mySelects_[id].push(0);
431 options[opt].setAttribute(
"unselectable",
"on");
434 while(MultiSelectBox.mySelects_[
id].length > options.length)
435 MultiSelectBox.mySelects_[id].splice(options.length,1);
439 MultiSelectBox.dbg(
"repaint");
442 for (var opt=MultiSelectBox.mySelects_[
id].length; opt<options.length; opt++)
444 MultiSelectBox.mySelects_[id].push(0);
445 options[opt].setAttribute(
"unselectable",
"on");
449 for (var opt=0; opt < options.length; opt++)
451 if (clearPreviousSelections)
452 MultiSelectBox.mySelects_[id][opt] = 0;
454 if (MultiSelectBox.mySelects_[
id][opt])
457 MultiSelectBox.addClass(options[opt],
"optionhighlighted");
458 options[opt].scrollIntoView();
461 MultiSelectBox.removeClass(options[opt],
"optionhighlighted");
468 MultiSelectBox.showSearch =
function(boxid)
470 var searchBox=$(boxid+
"search");
472 function localPlaceSearchBox()
483 var selRect = $(boxid).getBoundingClientRect();
484 var searchOffsetParent = searchBox.parentElement.children[0].children[1].offsetParent;
487 var searchOffsetParentIsBody = searchOffsetParent == document.body;
490 {
"left": searchOffsetParentIsBody?0:
491 searchOffsetParent.getBoundingClientRect().left,
492 "top": searchOffsetParentIsBody?0:
493 searchOffsetParent.getBoundingClientRect().top
499 var offsetx = selRect.left - offsetRect.left,
500 offsety = selRect.top - offsetRect.top;
503 searchBox.style.position=
"absolute";
504 searchBox.style.top=(offsety)+
"px";
505 searchBox.style.left=(offsetx)+
"px";
506 searchBox.style.width=(selRect.width-margin*2-30)+
"px";
510 if(!MultiSelectBox.selInitBoxHeight_[boxid])
512 MultiSelectBox.selInitBoxHeight_[boxid] = $(boxid).clientHeight;
514 localPlaceSearchBox();
521 $(boxid+
"searchErr").innerHTML =
"";
523 if (MultiSelectBox.toggleClass(searchBox,
"hidden")){
524 $(boxid).style.height = (MultiSelectBox.selInitBoxHeight_[boxid]-47) +
"px";
525 $(boxid).style.paddingTop =
"42px";
529 MultiSelectBox.searchSelect(boxid,searchBox);
532 MultiSelectBox.searchSelect(boxid,null,
'');
533 $(boxid).style.paddingTop = MultiSelectBox.SEL_INIT_PADDING +
"px";
534 $(boxid).style.height = (MultiSelectBox.selInitBoxHeight_[boxid]-10) +
"px";
539 MultiSelectBox.searchTimeout_ = null;
541 MultiSelectBox.searchSelect =
function(id,el,altstr)
544 if (MultiSelectBox.searchTimeout_){
545 clearTimeout(MultiSelectBox.searchTimeout_);
547 MultiSelectBox.searchTimeout_ = setTimeout(
function(){ MultiSelectBox.performSearchSelect(
id,el,altstr); }, 100);
550 MultiSelectBox.performSearchSelect =
function(id,el,altstr)
553 if (altstr !== undefined){
557 searchstr = el.value;
559 MultiSelectBox.searchTimeout_ = null;
560 var select = $(id).childNodes;
562 MultiSelectBox.dbg(
"END OF TIMEOUT FOR : "+searchstr);
565 $(
id+
"searchErr").innerHTML =
"";
567 re =
new RegExp(searchstr,
'i');
570 $(
id+
"searchErr").innerHTML = err.message +
571 " <a href='https://regex101.com/' target='_blank'>(help)</a>";
575 for (var opt=0; opt < select.length; opt++)
577 var option = select[opt];
581 if (option.tagName ==
'INPUT') {
continue; }
582 var html = option.innerHTML;
587 if (MultiSelectBox.hasClass(option,
"hidden"))
588 MultiSelectBox.removeClass(option,
"hidden");
590 option.innerHTML = html = html.replace(
"<b><u>",
"").replace(
"</u></b>",
"");
592 if(searchstr ==
"")
continue;
594 var text = option.textContent;
595 var endOfImgIndex = html.indexOf(
">");
596 var index = text.search(re);
597 var matchedText = (text.match(re) || [[]])[0];
598 var len = matchedText.length;
600 index = html.indexOf(matchedText,endOfImgIndex);
603 MultiSelectBox.addClass(option,
"hidden");
605 option.innerHTML = html.slice(0,index) +
"<b><u>" +
606 html.slice(index,index+len) +
607 "</u></b>" + html.slice(index+len);
611 MultiSelectBox.makeSearchBar =
function(id)
616 while(el = document.getElementById(
id +
"search"))
617 el.parentNode.removeChild(el);
619 var searchBox=document.createElement(
"input");
620 var onchange=
'MultiSelectBox.searchSelect("' +
id +
'",this)';
622 searchBox.setAttribute(
"class",
"hidden");
623 searchBox.setAttribute(
'type',
'text');
624 searchBox.setAttribute(
'id',
id +
"search");
625 searchBox.setAttribute(
"onpaste" , onchange);
626 searchBox.setAttribute(
"oncut" , onchange);
627 searchBox.setAttribute(
"onkeydown" , onchange);
628 searchBox.setAttribute(
"onkeyup" , onchange);
629 searchBox.setAttribute(
"onkeypress", onchange);
630 searchBox.setAttribute(
"onselect" , onchange);
633 var searchErrBox=document.createElement(
"div");
635 searchErrBox.setAttribute(
"class",
"hidden");
636 searchErrBox.setAttribute(
'id',
id +
"searchErr");
637 searchErrBox.style.color=
"red";
638 searchErrBox.style.overflow=
"hidden";
639 searchErrBox.style.height=
"23px";
642 function addSearchBox()
647 if(!MultiSelectBox.mySelects_[
id])
648 MultiSelectBox.mySelects_[id] = [];
657 MultiSelectBox.omnis_[id].appendChild(searchBox);
658 MultiSelectBox.omnis_[id].appendChild(searchErrBox);
661 clearInterval(interval);
665 interval = setInterval( addSearchBox, 50);
667 imgstr =
"<img src='/WebPath/images/windowContentImages/multiselectbox-magnifying-glass.jpg' " +
668 " style='float:left' height='28' width='28' alt='🔍' ";
669 imgstr +=
"onclick = 'MultiSelectBox.showSearch(\"" +
id +
"\");' title='Search' class='searchimg'>";