PageSourceSearch

https://www.wiener.hr/assets/js/multiselect-dropdown.js

js wiener.hr collected 2026-10-06 21:34:13 UTC 5,041 bytes, 131 lines download raw bytes

1function MultiselectDropdown(options){
2  var config={
3    search:true,
4    height:'15rem',
5    placeholder:'select',
6    txtSelected:'selected',
7    txtAll:'All',
8    txtRemove: 'Remove',
9    txtSearch:'search',
10    ...options
11  };
12  function newEl(tag,attrs){
13    var e=document.createElement(tag);
14    if(attrs!==undefined) Object.keys(attrs).forEach(k=>{
15      if(k==='class') { Array.isArray(attrs[k]) ? attrs[k].forEach(o=>o!==''?e.classList.add(o):0) : (attrs[k]!==''?e.classList.add(attrs[k]):0)}
16      else if(k==='style'){  
17        Object.keys(attrs[k]).forEach(ks=>{
18          e.style[ks]=attrs[k][ks];
19        });
20       }
21      else if(k==='text'){attrs[k]===''?e.innerHTML=' ':e.innerText=attrs[k]}
22      else e[k]=attrs[k];
23    });
24    return e;
25  }
26
27  
28  document.querySelectorAll("select[multiple]").forEach((el,k)=>{
29    
30    var div=newEl('div',{class:'multiselect-dropdown',style:{width:config.style?.width??el.clientWidth+'px',padding:config.style?.padding??''}});
31    el.style.display='none';
32    el.parentNode.insertBefore(div,el.nextSibling);
33    var listWrap=newEl('div',{class:'multiselect-dropdown-list-wrapper'});
34    var list=newEl('div',{class:'multiselect-dropdown-list',style:{height:config.height}});
35    var search=newEl('input',{class:['multiselect-dropdown-search'].concat([config.searchInput?.class??'form-control']),style:{width:'100%',display:el.attributes['multiselect-search']?.value==='true'?'block':'none'},placeholder:config.txtSearch});
36    listWrap.appendChild(search);
37    div.appendChild(listWrap);
38    listWrap.appendChild(list);
39
40    el.loadOptions=()=>{
41      list.innerHTML='';
42      
43      if(el.attributes['multiselect-select-all']?.value=='true'){
44        var op=newEl('div',{class:'multiselect-dropdown-all-selector'})
45        var ic=newEl('input',{type:'checkbox'});
46        op.appendChild(ic);
47        op.appendChild(newEl('label',{text:config.txtAll}));
48  
49        op.addEventListener('click',()=>{
50          op.classList.toggle('checked');
51          op.querySelector("input").checked=!op.querySelector("input").checked;
52          
53          var ch=op.querySelector("input").checked;
54          list.querySelectorAll(":scope > div:not(.multiselect-dropdown-all-selector)")
55            .forEach(i=>{if(i.style.display!=='none'){i.querySelector("input").checked=ch; i.optEl.selected=ch}});
56  
57          el.dispatchEvent(new Event('change'));
58        });
59        ic.addEventListener('click',(ev)=>{
60          ic.checked=!ic.checked;
61        });
62  
63        list.appendChild(op);
64      }
65
66      Array.from(el.options).map(o=>{
67        var op=newEl('div',{class:o.selected?'checked':'',optEl:o})
68        var ic=newEl('input',{type:'checkbox',checked:o.selected});
69        op.appendChild(ic);
70        op.appendChild(newEl('label',{text:o.text}));
71
72        op.addEventListener('click',()=>{
73          op.classList.toggle('checked');
74          op.querySelector("input").checked=!op.querySelector("input").checked;
75          op.optEl.selected=!!!op.optEl.selected;
76          el.dispatchEvent(new Event('change'));
77        });
78        ic.addEventListener('click',(ev)=>{
79          ic.checked=!ic.checked;
80        });
81        o.listitemEl=op;
82        list.appendChild(op);
83      });
84      div.listEl=listWrap;
85
86      div.refresh=()=>{
87        div.querySelectorAll('span.optext, span.placeholder').forEach(t=>div.removeChild(t));
88        var sels=Array.from(el.selectedOptions);
89        if(sels.length>(el.attributes['multiselect-max-items']?.value??5)){
90          div.appendChild(newEl('span',{class:['optext','maxselected'],text:sels.length+' '+config.txtSelected}));          
91        }
92        else{
93          sels.map(x=>{
94            var c=newEl('span',{class:'optext',text:x.text, srcOption: x});
95            if((el.attributes['multiselect-hide-x']?.value !== 'true'))
96              c.appendChild(newEl('span',{class:'optdel',text:'🗙',title:config.txtRemove, onclick:(ev)=>{c.srcOption.listitemEl.dispatchEvent(new Event('click'));div.refresh();ev.stopPropagation();}}));
97
98            div.appendChild(c);
99          });
100        }
101        if(0==el.selectedOptions.length) div.appendChild(newEl('span',{class:'placeholder',text:el.attributes['placeholder']?.value??config.placeholder}));
102      };
103      div.refresh();
104    }
105    el.loadOptions();
106    
107    search.addEventListener('input',()=>{
108      list.querySelectorAll(":scope div:not(.multiselect-dropdown-all-selector)").forEach(d=>{
109        var txt=d.querySelector("label").innerText.toUpperCase();
110        d.style.display=txt.includes(search.value.toUpperCase())?'flex':'none';
111      });
112    });
113
114    div.addEventListener('click',()=>{
115      div.listEl.style.display='block';
116      search.focus();
117      search.select();
118    });
119    
120    document.addEventListener('click', function(event) {
121      if (!div.contains(event.target)) {
122        listWrap.style.display='none';
123        div.refresh();
124      }
125    });    
126  });
127}
128
129//window.addEventListener('load',()=>{
130//  MultiselectDropdown(window.MultiselectDropdownOptions);
131//});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.