otsdaq_utilities  v2_05_02_indev
MultiSelectBox.js
1 //
5 // To make a Multi-Select Box
6 // create a div element and call in JavaScript...
7 //
8 // MultiSelectBox.createSelectBox(el,name,title,vals)
9 //
10 // This function is called by user to actually create the multi select box
11 // These parameters are optional and can be omitted or set to 0:
12 // keys, types, handler, noMultiSelect,mouseOverHandler,iconURLs,mouseDownHandler,
13 // mouseUpHandler,
14 // requireCtrlMultiClick,titles
15 // Note: handler is the string name of the function (put in quotes).
16 // Note: requireCtrlMultiClick enables CONTROL or SHIFT key selections
17 // - sometimes CONTROL forces right click in browser, so SHIFT is needed
18 //
19 // Can use MultiSelectBox.initMySelectBoxes after manually setting the mySelects_ array
20 //
21 //
22 //
23 // Example selection handler:
24 //
25 // function exampleSelectionHandler(el)
26 // {
27 // var splits = el.id.split('_');
28 // var i = splits[splits.length-1] | 0;
29 // MultiSelectBox.dbg("Chosen element index:",i,
30 // " key:",el.getAttribute("key-value"),
31 // " type:",el.getAttribute("type-value"));
32 // for(var s in MultiSelectBox.mySelects_[el.parentElement.id])
33 // MultiSelectBox.dbg("selected: ",MultiSelectBox.mySelects_[el.parentElement.id][s]);
34 //
35 // }
36 //
37 // Example usage: /WebPath/html/MultiSelectBoxTest.html
38 //
41 
42 
43 //function list:
44 // createSelectBox(el,name,title,vals,keys,types,
45 // handler,noMultiSelect,mouseOverHandler,iconURLs,mouseDownHandler,
46 // mouseUpHandler,
47 // requireCtrlMultiClick,titles)
48 // initMySelectBoxes(clearPreviousSelections)
49 //
50 // hasClass(ele,cls)
51 // addClass(ele,cls)
52 // removeClass(ele,cls)
53 // toggleClass(ele,cls)
54 //
55 // getSelectedIndex(el)
56 // getSelectionArray(el)
57 // getSelectedCount(el)
58 // getSelectionElementByIndex(el,i)
59 // setSelectionElementByIndex(el,i,selected)
60 // myOptionSelect(option, index, isSingleSelect, event)
61 //
62 // showSearch(boxid)
63 // searchSelect(id,el,altstr)
64 // performSearchSelect(id,el,altstr)
65 // makeSearchBar(id)
66 
67 var selected = [];
68 var MultiSelectBox = MultiSelectBox || {}; //define MultiSelectBox namespace
69 
70 if(window.console && console && console.log)
71  MultiSelectBox.dbg = console.log.bind(window.console);
72 //var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
73 
74 function $(id) {return document.getElementById(id);}
75 
77 //global variables
78 
79 MultiSelectBox.mySelects_ = {};
80 MultiSelectBox.omnis_ = {};
81 MultiSelectBox.isSingleSelect_ = {};
82 MultiSelectBox.lastOptSelect_ = {}; //maintain last opt clicked
83 
84 MultiSelectBox.selInitBoxHeight_ = {}; //init with first showing of search box in showSearch()
85 MultiSelectBox.SEL_INIT_PADDING = 5;
86 
87 MultiSelectBox.requireCtrlMultiClick_ = {};
88 
90 //function definitions
91 
92 MultiSelectBox.hasClass = function(ele,cls)
93 {
94  return !!ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
95 } //end hasClass()
96 
97 MultiSelectBox.addClass = function(ele,cls)
98 {
99  if (!MultiSelectBox.hasClass(ele,cls)) ele.className += " "+cls;
100 } //end addClass()
101 
102 MultiSelectBox.removeClass = function(ele,cls)
103 {
104  if (MultiSelectBox.hasClass(ele,cls))
105  {
106  var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
107  ele.className=ele.className.replace(reg,'');
108  }
109 } //end removeClass()
110 
111 MultiSelectBox.toggleClass = function(ele,cls)
112 {
113  //returns true if the element had the class
114  if (MultiSelectBox.hasClass(ele,cls))
115  {
116  var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
117  ele.className=ele.className.replace(reg,'');
118  return true;
119  }
120  else
121  {
122  ele.className += " " + cls;
123  return false;
124  }
125 } //end toggleClass()
126 
127 MultiSelectBox.getSelectedIndex = function(el)
128 {
129  try //try to treat as selection box element first
130  {
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;
134  return -1; //no index selected
135  }
136  catch(e){} // ignore error and treat as selected element now
137 
138  var splits = el.id.split('_');
139  return splits[splits.length-1] | 0;
140 } //end getSelectedIndex()
141 
142 MultiSelectBox.getSelectionArray = function(el)
143 {
144  if(!el) return [];
145 
146  //console.log(el.id);
147  if(el.parentElement.id.indexOf("selbox-") == 0)
148  return MultiSelectBox.mySelects_[el.parentElement.id];
149  else
150  return MultiSelectBox.mySelects_[el.getElementsByClassName("mySelect")[0].id];
151 } //end getSelectionArray()
152 
153 
154 MultiSelectBox.getSelectedCount = function(el)
155 {
156  try //try to treat as selection box element first
157  {
158  var selects = MultiSelectBox.mySelects_[el.getElementsByClassName("mySelect")[0].id];
159  var cnt = 0;
160  for(var i=0;i<selects.length;++i)
161  if(selects[i]) ++cnt;
162  return cnt;
163  }
164  catch(e){} // ignore error and treat as selected element now
165 
166  return 0;
167 } //end getSelectedIndex()
168 
169 MultiSelectBox.getSelectionElementByIndex = function(el,i)
170 {
171  if(el.parentElement.id.indexOf("selbox-") == 0)
172  return document.getElementById(el.parentElement.parentElement.
173  getElementsByClassName("mySelect")[0].id +
174  "-option_" + i);
175  else
176  return document.getElementById(el.getElementsByClassName("mySelect")[0].id +
177  "-option_" + i);
178 } //end getSelectionElementByIndex()
179 
180 MultiSelectBox.setSelectionElementByIndex = function(el,i,selected)
181 {
182  var name = el.getElementsByClassName("mySelect")[0].id;
183 
184  if(!MultiSelectBox.isSingleSelect_[name] &&
185  i == -1) //apply to all
186  {
187  var size = MultiSelectBox.mySelects_[name].length;
188  for (var opt=0; opt<size; opt++)
189  MultiSelectBox.mySelects_[name][opt] = selected?1:0;
190  return;
191  }
192 
193  if(MultiSelectBox.isSingleSelect_[name] &&
194  selected) //if true, only allow one select at a time, so deselect others
195  {
196  var size = MultiSelectBox.mySelects_[name].length;
197  for (var opt=0; opt<size; opt++)
198  MultiSelectBox.mySelects_[name][opt] = 0;
199  }
200  MultiSelectBox.mySelects_[name][i] = selected?1:0;
201 } //end setSelectionElementByIndex()
202 
203 //for multiple selects to behave like checkboxes
204 MultiSelectBox.myOptionSelect = function(option, index, isSingleSelect, event)
205 {
206  var select = option.parentElement;
207  var id = select.getAttribute("id");
208  var selectList = MultiSelectBox.mySelects_[id];
209  var size = select.childNodes.length;
210 
211  if(event)
212  MultiSelectBox.dbg("Shift click = " + event.shiftKey);
213 
214  if(event)
215  MultiSelectBox.dbg("Control click = " + event.ctrlKey);
216 
217  //if shift.. then select or deselect
218  // (based on value at MultiSelectBox.lastOptSelect_[id]) from
219  // MultiSelectBox.lastOptSelect_[id]
220  // to this click
221 
222  //MultiSelectBox.dbg(selectList);
223  if (!selectList || selectList.length!=size)
224  { //first time, populate select list
225  MultiSelectBox.mySelects_[id] = [];
226  MultiSelectBox.lastOptSelect_[id] = -1;
227  selectList=MultiSelectBox.mySelects_[id];
228  for (var opt=0; opt<size; opt++)
229  selectList.push(0);
230  }
231 
232  //toggle highlighted style and global array
233  MultiSelectBox.toggleClass(option,"optionhighlighted");
234  selectList[index] ^= 1;
235 
236  if(isSingleSelect || //if true, only allow one select at a time, so deselect others
237  (MultiSelectBox.requireCtrlMultiClick_[id] && !event.ctrlKey && !event.shiftKey))
238  for (var opt=0; opt<size; opt++)
239  {
240  //fixed, now works for any order option IDs. Goes by index only.
241  var cindex = select.childNodes[opt].id.split("_");
242  cindex = cindex[cindex.length-1];
243 
244  if(cindex == index) continue;
245  else if(selectList[cindex] == 1)
246  {
247  MultiSelectBox.toggleClass(select.childNodes[opt],"optionhighlighted");
248  selectList[cindex] = 0;
249  }
250  }
251  else if(event.shiftKey &&
252  MultiSelectBox.lastOptSelect_[id] != -1)
253  {
254  //if shift.. then select or deselect
255  // (based on value at MultiSelectBox.lastOptSelect_[id]) from
256  // MultiSelectBox.lastOptSelect_[id]
257  // to this click
258 
259  var lo = MultiSelectBox.lastOptSelect_[id] < index?
260  MultiSelectBox.lastOptSelect_[id]:index;
261  var hi = MultiSelectBox.lastOptSelect_[id] < index?
262  index:MultiSelectBox.lastOptSelect_[id];
263 
264  //MultiSelectBox.dbg("lo ",lo," hi ",hi);
265  //handle multi shift click
266  for (var opt=lo; opt<=hi; opt++)
267  {
268  //MultiSelectBox.dbg(selectList[opt]," vs ",
269  // selectList[MultiSelectBox.lastOptSelect_[id]]);
270  if(selectList[opt] !=
271  selectList[MultiSelectBox.lastOptSelect_[id]]) //if not matching selected value
272  {
273  //MultiSelectBox.dbg("flip");
274  //toggle highlighted style and global array
275  MultiSelectBox.toggleClass(select.childNodes[opt],"optionhighlighted");
276  selectList[opt] ^= 1;
277  }
278  }
279  }
280 
281  MultiSelectBox.dbg(selectList);
282  selected = selectList;
283  MultiSelectBox.lastOptSelect_[id] = index; //save selection
284 } //end myOptionSelect()
285 
286 //This function is called by user to actually create the multi select box
287 // These parameters are optional and can be omitted or set to 0:
288 // keys, types, handler, noMultiSelect, mouseOverHandler,
289 // iconURLs, mouseDownHandler, mouseUpHandler,
290 // requireCtrlMultiClick
291 // Note: handler is the string name of the function
292 MultiSelectBox.createSelectBox = function(el,name,title,vals,keys,types,
293  handler,noMultiSelect,mouseOverHandler,iconURLs,mouseDownHandler,
294  mouseUpHandler,
295  requireCtrlMultiClick,titles)
296 {
297  if(!el)
298  { MultiSelectBox.dbg("Invalid Element given to MultiSelectBox: " + el);
299  throw new Error("Invalid Element given to MultiSelectBox: " + el); return; }
300 
301  el.innerHTML = ""; //delete current contents
302 
303  name = "selbox-" + name;
304  MultiSelectBox.addClass(el,"multiselectbox"); //add multiselectbox class to div
305 
306  MultiSelectBox.omnis_[name] = el;
307  MultiSelectBox.isSingleSelect_[name] = noMultiSelect;
308  MultiSelectBox.lastOptSelect_[name] = -1; //default to nothing selected
309  MultiSelectBox.selInitBoxHeight_[name] = 0; //init with first showing of search box in showSearch()
310  MultiSelectBox.requireCtrlMultiClick_[name] = requireCtrlMultiClick;
311 
312  //searchglass=28x28, margin=5, vscroll=16, border=1
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;
315 
316  el = document.createElement("div"); //create element within element
317  MultiSelectBox.omnis_[name].appendChild(el);
318 
319  var str = "";
320 
321  if(title)
322  {
323  str += "<div id='" + name + "header' " +
324  "style='margin-top:20px; width:100%; white-space:nowrap; height:21px'><b>"; //had to add height for new Chrome bug
325  str += title;
326  str += "</b></div>";
327  }
328 
329  if(!keys) keys = vals;
330  if(!types) types = vals;
331 
332  //make selbox
333  str += "<table cellpadding='0' cellspacing='0'>";
334  str += "<tr><td>";
335  str += "<div class='mySelect' unselectable='on' id='" +
336  name + "' style='float:left;" +
337  "width: " + (msW) + "px;" +
338  "height: " + (msH) + "px;" +
339  "' name='" + name + "' " +
340  ">";
341 
342  for (var i = 0; i < keys.length;++i)//cactus length
343  {
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") //if handler supplied as string
349  str += handler + "(this,event);"; //user selection handler
350  else if(handler) //assume it is a function
351  str += handler.name + "(this,event);"; //user selection handler
352  str += "' ";
353 
354  str += "onmouseover='";
355  if(mouseOverHandler && (typeof mouseOverHandler) == "string") //if mouseOverHandler supplied as string
356  str += mouseOverHandler + "(this,event);"; //user selection mouseOverHandler
357  else if(mouseOverHandler) //assume it is a function
358  str += mouseOverHandler.name + "(this,event);"; //user selection mouseOverHandler
359  str += "' ";
360 
361  str += "onmousedown='";
362  if(mouseDownHandler && (typeof mouseDownHandler) == "string") //if mouseDownHandler supplied as string
363  str += mouseDownHandler + "(this,event);"; //user selection mouseDownHandler
364  else if(mouseDownHandler) //assume it is a function
365  str += mouseDownHandler.name + "(this,event);"; //user selection mouseDownHandler
366  str += "' ";
367 
368  str += "onmouseup='";
369  if(mouseUpHandler && (typeof mouseUpHandler) == "string") //if mouseUpHandler supplied as string
370  str += mouseUpHandler + "(this,event);"; //user selection mouseUpHandler
371  else if(mouseUpHandler) //assume it is a function
372  str += mouseUpHandler.name + "(this,event);"; //user selection mouseUpHandler
373  str += "' ";
374 
375  if(titles)
376  str += "title='" + titles[i] + "' ";
377 
378  str += "key-value='" + keys[i] + "' type-value='" +
379  types[i] + "'>"; //index, key, ids available as attributes
380  if(iconURLs && iconURLs[i]) //add image if available
381  {
382  if(iconURLs[i][0] != '=')
383  str += "<img style='width:32px; height:32px; margin: 0px 5px -8px 0;' " +
384  "src='" +
385  iconURLs[i] + "' />";
386  else //alt text
387  str += iconURLs[i].substr(1) + " - ";
388  }
389 
390  str += vals[i];
391  str += "</div>";
392  }
393  str += "</div>";
394  //close selbox
395 
396  str += "</td><td valign='top'>";
397  //append search bar
398  str += MultiSelectBox.makeSearchBar(name);
399  str += "</td></table>";
400  el.innerHTML = str;
401 
402  if(msH > 200)
403  { //provide a minimum width for looks (to avoid long and skinny)
404  var el = document.getElementById(name);
405  if(msW < 200)
406  el.style.width = 200 + "px";
407  }
408 
409 } //end createSelectBox()
410 
411 //for initializing the highlights if selects are made "manually" (without clicking)
412 MultiSelectBox.initMySelectBoxes = function(clearPreviousSelections)
413 {
414  var divs=document.getElementsByClassName('mySelect');
415  for (var el=0; el<divs.length; el++)
416  {
417  var select = divs[el];
418 
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)
424  {//if first time drawing select box OR size was reduced
425  if(!MultiSelectBox.mySelects_[id] || clearPreviousSelections)
426  MultiSelectBox.mySelects_[id]=[];
427  for (var opt=0; opt<options.length; opt++)
428  {
429  if(clearPreviousSelections || opt >= MultiSelectBox.mySelects_.length)
430  MultiSelectBox.mySelects_[id].push(0);
431  options[opt].setAttribute("unselectable","on");//make not selectable for ie<10
432  }
433  //remove any extras
434  while(MultiSelectBox.mySelects_[id].length > options.length)
435  MultiSelectBox.mySelects_[id].splice(options.length,1);
436  }
437  else
438  { //if repaint: set highlighted options
439  MultiSelectBox.dbg("repaint");
440 
441  //if more elements were added, expand the selects array
442  for (var opt=MultiSelectBox.mySelects_[id].length; opt<options.length; opt++)
443  {
444  MultiSelectBox.mySelects_[id].push(0);
445  options[opt].setAttribute("unselectable","on");//make not selectable for ie<10
446  }
447 
448  //highlight properly according to mySelects_ array
449  for (var opt=0; opt < options.length; opt++)
450  {
451  if (clearPreviousSelections)
452  MultiSelectBox.mySelects_[id][opt] = 0; //clear
453 
454  if (MultiSelectBox.mySelects_[id][opt])
455  {
456  //MultiSelectBox.dbg(opt);
457  MultiSelectBox.addClass(options[opt],"optionhighlighted");
458  options[opt].scrollIntoView(); //so highlighted are visible to user
459  }
460  else
461  MultiSelectBox.removeClass(options[opt],"optionhighlighted");
462  }
463  }
464  }
465 } //end initMySelectBoxes()
466 
467 //for searching selectboxes (works for standard "selects" and "mySelects")
468 MultiSelectBox.showSearch = function(boxid)
469 {
470  var searchBox=$(boxid+"search");
471 
472  function localPlaceSearchBox()
473  {
474  //Goal: place searchBox search input correctly in table content
475  // irregardless of user div having style.position = normal/static, absolute, relative
476 
477  //finding the search input's offset parent is not so straight forward
478  // since it is initially hidden.
479  // Use the offset parent of the content table
480  // sibling[0] := div (of content)
481  // withing div, child[0] := header, child[1] := table (of content)
482 
483  var selRect = $(boxid).getBoundingClientRect();
484  var searchOffsetParent = searchBox.parentElement.children[0].children[1].offsetParent;
485  //check if there is no offset parent (the body is the offset parent)
486  // it seems to be the case that body returns a crazy bounding client rect (left = 8 and top = 13?) .. don't understand why
487  var searchOffsetParentIsBody = searchOffsetParent == document.body;
488 
489  var offsetRect =
490  {"left": searchOffsetParentIsBody?0:
491  searchOffsetParent.getBoundingClientRect().left, //offsetLeft is different
492  "top": searchOffsetParentIsBody?0:
493  searchOffsetParent.getBoundingClientRect().top
494  };
495  //previous attempts to place search input (all fail to solve all cases):
496  //MultiSelectBox.omnis_[id].getBoundingClientRect();
497  //select.offsetParent.getBoundingClientRect();
498 
499  var offsetx = selRect.left - offsetRect.left,
500  offsety = selRect.top - offsetRect.top;
501  var margin = 5;
502 
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";
507  //searchBox.style.display = "block"; //for debugging position
508  } //end localPlaceSearchBox()
509 
510  if(!MultiSelectBox.selInitBoxHeight_[boxid]) //init if not yet defined
511  {
512  MultiSelectBox.selInitBoxHeight_[boxid] = $(boxid).clientHeight; //as soon as hidden is toggled H changes
513 
514  localPlaceSearchBox();
515  }
516 
517 
518 
519  //RAR decided on 2/2/2017 to not show er
520  //MultiSelectBox.toggleClass($(boxid+"searchErr"),"hidden");
521  $(boxid+"searchErr").innerHTML = "";
522 
523  if (MultiSelectBox.toggleClass(searchBox,"hidden")){
524  $(boxid).style.height = (MultiSelectBox.selInitBoxHeight_[boxid]-47) + "px";
525  $(boxid).style.paddingTop = "42px";
526  //$(boxid).childNodes[0].style.marginTop="42px";
527  //searchBox.style.left = ($(boxid).offsetLeft-8) + "px"
528  searchBox.focus();
529  MultiSelectBox.searchSelect(boxid,searchBox);
530  }
531  else{
532  MultiSelectBox.searchSelect(boxid,null, '');
533  $(boxid).style.paddingTop = MultiSelectBox.SEL_INIT_PADDING + "px";
534  $(boxid).style.height = (MultiSelectBox.selInitBoxHeight_[boxid]-10) + "px";
535  //$(boxid).childNodes[0].style.marginTop="initial";
536  }
537 } //end showSearch()
538 
539 MultiSelectBox.searchTimeout_ = null;
540 
541 MultiSelectBox.searchSelect = function(id,el,altstr)
542 {
543  //wait 100ms so that it does not keep constantly searching as user types only when they are done typing
544  if (MultiSelectBox.searchTimeout_){
545  clearTimeout(MultiSelectBox.searchTimeout_);
546  }
547  MultiSelectBox.searchTimeout_ = setTimeout(function(){ MultiSelectBox.performSearchSelect(id,el,altstr); }, 100);
548 } //end searchSelect()
549 
550 MultiSelectBox.performSearchSelect = function(id,el,altstr)
551 {
552  var searchstr;
553  if (altstr !== undefined){
554  searchstr = altstr;
555  }
556  else{
557  searchstr = el.value;
558  }
559  MultiSelectBox.searchTimeout_ = null;
560  var select = $(id).childNodes;
561 
562  MultiSelectBox.dbg("END OF TIMEOUT FOR : "+searchstr);
563 
564  var re; //regular expression
565  $(id+"searchErr").innerHTML = "";
566  try {
567  re = new RegExp(searchstr,'i');
568  }
569  catch(err) { //invalid regular expression
570  $(id+"searchErr").innerHTML = err.message +
571  " <a href='https://regex101.com/' target='_blank'>(help)</a>";
572  re = "";
573  }
574 
575  for (var opt=0; opt < select.length; opt++)
576  {
577  var option = select[opt];
578 
579  //MultiSelectBox.dbg("opt: " + opt);
580 
581  if (option.tagName == 'INPUT') { continue; }
582  var html = option.innerHTML;
583 
584  //MultiSelectBox.dbg("tagName: " + option.tagName);
585 
586  //first set the hidden to unhidden and unbold the bolded
587  if (MultiSelectBox.hasClass(option,"hidden"))
588  MultiSelectBox.removeClass(option,"hidden");
589  else
590  option.innerHTML = html = html.replace("<b><u>","").replace("</u></b>","");
591 
592  if(searchstr == "") continue; //show all if no search str
593 
594  var text = option.textContent; //search only the text (assume that is val
595  var endOfImgIndex = html.indexOf(">");
596  var index = text.search(re);
597  var matchedText = (text.match(re) || [[]])[0]; //returns the matched string within an array or null (when null take [[]])
598  var len = matchedText.length; // so we want length of element 0
599  //MultiSelectBox.dbg(text+' '+index);
600  index = html.indexOf(matchedText,endOfImgIndex); //try to find in html text
601 
602  if(!len) //if searchstr not in option innerHTML
603  MultiSelectBox.addClass(option,"hidden");
604  else if(index != -1) //make searched string bold (if possible - must be contiguous)
605  option.innerHTML = html.slice(0,index) + "<b><u>" +
606  html.slice(index,index+len) +
607  "</u></b>" + html.slice(index+len);
608  }
609 } //end performSearchSelect()
610 
611 MultiSelectBox.makeSearchBar = function(id)
612 {
613  //remove old existing search bars
614 
615  var el;
616  while(el = document.getElementById(id + "search"))
617  el.parentNode.removeChild(el);
618 
619  var searchBox=document.createElement("input");
620  var onchange='MultiSelectBox.searchSelect("' + id + '",this)';
621 
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);
631 
632 
633  var searchErrBox=document.createElement("div");
634 
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";
640 
641  var interval;
642  function addSearchBox()
643  {
644  var select=$(id);
645  if (select)
646  {
647  if(!MultiSelectBox.mySelects_[id])
648  MultiSelectBox.mySelects_[id] = []; //initialize to empty the selected items
649 
650 
651 
652  //err box no longer displayed...
653  // searchErrBox.style.position="absolute"; //place above title
654  // searchErrBox.style.top=(offsety - 37)+"px";
655  // searchErrBox.style.left=(offsetx + 0)+"px";
656 
657  MultiSelectBox.omnis_[id].appendChild(searchBox);
658  MultiSelectBox.omnis_[id].appendChild(searchErrBox);
659 
660 
661  clearInterval(interval);
662  }
663  }
664 
665  interval = setInterval( addSearchBox, 50);
666 
667  imgstr = "<img src='/WebPath/images/windowContentImages/multiselectbox-magnifying-glass.jpg' " +
668  " style='float:left' height='28' width='28' alt='&#128269;' ";
669  imgstr += "onclick = 'MultiSelectBox.showSearch(\"" + id + "\");' title='Search' class='searchimg'>";
670  return imgstr;
671 } //end makeSearchBar()
672 
673 
674