From f3d8e503aad3ee500433b9fa9d85ea641be6d080 Mon Sep 17 00:00:00 2001 From: Thomas Date: Wed, 29 Dec 2021 13:29:50 +0100 Subject: [PATCH] build min file --- tags-standalone.min.js | 2 +- tags-standalone.min.js.map | 4 ++-- tags.min.js | 2 +- tags.min.js.map | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tags-standalone.min.js b/tags-standalone.min.js index b6c7d62..ec26693 100644 --- a/tags-standalone.min.js +++ b/tags-standalone.min.js @@ -1,2 +1,2 @@ -function q(n){return n instanceof Element}function W(n,e){let t=e&&q(e)?e:document;return q(n)?n:t.querySelector(n)}function y(n,e){return W(n,e)}var Le="addEventListener",j=Le;var xe="removeEventListener",T=xe;var Ae=(()=>{let n=!1;try{let e=Object.defineProperty({},"passive",{get(){return n=!0,n}});document[j]("DOMContentLoaded",function t(){document[T]("DOMContentLoaded",t,e)},e)}catch(e){throw Error("Passive events are not supported")}return n})(),de=Ae;var Ce=de?{passive:!0}:!1,_=Ce;function S(n,e){n.classList.add(e)}function L(n,e){return n.classList.contains(e)}function p(n,e){n.classList.remove(e)}var je="aria-expanded",U=je;var Te="show",m=Te;var Ne="data-bs-toggle",K=Ne;var De=["dropdown","dropup","dropstart","dropend"],g=De;var Ie="dropdown-menu",Y=Ie;function A(n,e){let t=new CustomEvent(n,{cancelable:!0});return e instanceof Object&&Object.keys(e).forEach(s=>{Object.defineProperty(t,s,{value:e[s]})}),t}function O(n){let e=n.closest("A");return n&&(n.hasAttribute("href")&&n.href.slice(-1)==="#"||e&&e.hasAttribute("href")&&e.href.slice(-1)==="#")}function N(n){n.focus()}function k(n){return n==="true"?!0:n==="false"?!1:Number.isNaN(+n)?n===""||n==="null"?null:n:+n}var qe=n=>Object.keys(n),H=qe;function J(n,e,t,s){let o={...n.dataset},i={},r={};return H(o).forEach(l=>{let c=s&&l.includes(s)?l.replace(s,"").replace(/[A-Z]/,h=>h.toLowerCase()):l;r[c]=k(o[l])}),H(t).forEach(l=>{t[l]=k(t[l])}),H(e).forEach(l=>{l in t?i[l]=t[l]:l in r?i[l]=r[l]:i[l]=e[l]}),i}var V=class{constructor(e,t,s,o){let i=this,r=y(t);r[e]&&r[e].dispose(),i.element=r,s&&Object.keys(s).length&&(i.options=J(r,s,o||{},"bs")),r[e]=i}dispose(e){let t=this;t.element[e]=null,Object.keys(t).forEach(s=>{t[s]=null})}};var[u]=g,v="Dropdown",Q=`[${K}="${u}"]`,D=g[1],M=g[2],P=g[3],x=`${Y}-end`,he=["d-block","invisible"],Oe=[u,D],ue=[M,P],ke={offset:5,display:"dynamic"},Z=A(`show.bs.${u}`),fe=A(`shown.bs.${u}`),G=A(`hide.bs.${u}`),pe=A(`hidden.bs.${u}`);function X(n,e){let{element:t,menu:s,originalClass:o,menuEnd:i,options:r}=n,{offset:l}=r,c=t.parentElement;if(["margin","top","bottom","left","right"].forEach(d=>{s.style[d]=""}),p(c,"position-static"),!e){let d=L(s,x);c.className=o.join(" "),d&&!i?p(s,x):!d&&i&&S(s,x);return}let a=g.find(d=>o.includes(d))||u,f={dropdown:[l,0,0],dropup:[0,0,l],dropstart:[-1,l,0],dropend:[-1,0,0,l]},I={dropdown:{top:"100%"},dropup:{top:"auto",bottom:"100%"},dropstart:{left:"auto",right:"100%"},dropend:{left:"100%",right:"auto"},menuEnd:{right:0,left:"auto"}};he.forEach(d=>S(s,d));let we=new RegExp(`\\b(${u}|${D}|${M}|${P})+`),R={w:t.offsetWidth,h:t.offsetHeight},E={w:s.offsetWidth,h:s.offsetHeight},se=document.documentElement,ie=document.body,ne=se.clientWidth||ie.clientWidth,oe=se.clientHeight||ie.clientHeight,w=t.getBoundingClientRect(),ye=w.left+R.w-E.w<0,re=w.left-E.w<0,Se=w.left+E.w>=ne,le=w.left+E.w+R.w>=ne,z=w.top+E.h>=oe,ae=w.top+E.h+R.h>=oe,ce=w.top-E.h<0;ue.includes(a)&&re&&le&&(a=u),ue.includes(a)&&z&&(a=D),a===M&&re&&!z&&(a=P),a===P&&le&&!z&&(a=M),a===D&&ce&&!ae&&(a=u),a===u&&ae&&!ce&&(a=D),f=f[a],s.style.margin=`${f.map(d=>d&&`${d}px`).join(" ")}`,Object.keys(I[a]).forEach(d=>{s.style[d]=I[a][d]}),L(c,a)||(c.className=c.className.replace(we,a)),Oe.includes(a)&&(!i&&Se?S(s,x):i&&ye&&p(s,x),L(s,x)&&Object.keys(I.menuEnd).forEach(d=>{s.style[d]=I.menuEnd[d]})),he.forEach(d=>p(s,d))}function me(n){let e=n.open?j:T;document[e]("click",ve),document[e]("focus",ve),document[e]("keydown",$e),document[e]("keyup",Ve),n.options.display==="dynamic"&&(window[e]("scroll",be,_),window[e]("resize",be,_))}function ge(n,e){let t=e?j:T;n.element[t]("click",He)}function ee(){let n=g.concat("btn-group").map(e=>document.getElementsByClassName(`${e} ${m}`)).find(e=>e.length);return n&&n.length?Array.from(n[0].children).find(e=>e.hasAttribute(K)):null}function ve(n){let{target:e,type:t}=n;if(!e.closest)return;let s=ee(),o=s&&s.parentNode,i=s&&s[v],r=i&&i.menu,l=e.closest(Q)!==null,c=o&&o.contains(e)&&(e.tagName==="form"||e.closest("form")!==null);t==="click"&&O(e)&&n.preventDefault(),!(t==="focus"&&(e===s||e===r||r.contains(e)))&&(c||l||i&&i.hide(s))}function He(n){let e=this;e[v].toggle(e),O(n.target)&&n.preventDefault()}function $e(n){(n.which===38||n.which===40)&&n.preventDefault()}function Ve({which:n}){let e=ee(),t=e[v],{menu:s,menuItems:o,open:i}=t,r=document.activeElement,l=r===e,c=s.contains(r),h=r.parentNode===s||r.parentNode.parentNode===s,a=o.indexOf(r);h&&(l?a=0:n===38?a=a>1?a-1:0:n===40&&(a=a{l.children.length&&l.children[0].tagName==="A"&&s.menuItems.push(l.children[0]),l.tagName==="A"&&s.menuItems.push(l)}),s.open=!1,ge(s,1)}toggle(e){let t=this,{open:s}=t;s?t.hide(e):t.show(e)}show(e){let t=this,s=y(g.concat("btn-group").map(h=>`.${h}.${m}`).join(",")),o=s&&y(Q,s);o&&o[v].hide();let{element:i,menu:r,open:l}=t,c=i.parentNode;Z.relatedTarget=e||null,c.dispatchEvent(Z),!Z.defaultPrevented&&(X(t,1),S(r,m),S(c,m),i.setAttribute(U,!0),t.open=!l,setTimeout(()=>{N(r.getElementsByTagName("INPUT")[0]||i),me(t),fe.relatedTarget=e||null,c.dispatchEvent(fe)},1))}hide(e){let t=this,{element:s,menu:o,open:i}=t,r=s.parentNode;G.relatedTarget=e||null,r.dispatchEvent(G),!G.defaultPrevented&&(p(o,m),p(r,m),X(t),s.setAttribute(U,!1),t.open=!i,N(s),setTimeout(()=>me(t),1),pe.relatedTarget=e||null,r.dispatchEvent(pe))}dispose(){let e=this,{element:t}=e;L(t.parentNode,m)&&e.open&&e.hide(),ge(e),super.dispose(v)}};B.init={component:v,selector:Q,constructor:B};var Me="is-active",b=["is-active","bg-primary","text-white"],C="data-value",te=new WeakMap,F=class{#l;#t;#i;#n;#s;#e;#r;#o;constructor(e,t={}){e.style.display="none",e.dataset.tags=!0,this.#t=e;let s=i=>["true","false","1","0",!0,!1].includes(i)&&!!JSON.parse(i),o={...t,...e.dataset};for(this.allowNew=o.allowNew?s(o.allowNew):!1,this.showAllSuggestions=o.showAllSuggestions?s(o.showAllSuggestions):!1,this.badgeStyle=o.badgeStyle||"primary",this.allowClear=o.allowClear?s(o.allowClear):!1,this.server=o.server||!1,this.liveServer=o.liveServer?s(o.liveServer):!1,this.suggestionsThreshold=o.suggestionsThreshold?parseInt(o.suggestionsThreshold):1,this.validationRegex=o.regex||"",this.separator=o.separator?o.separator.split("|"):[],this.max=o.max?parseInt(o.max):null,this.clearLabel=o.clearLabel||"Clear",this.searchLabel=o.searchLabel||"Type a value",e.hasAttribute("multiple")||(this.max=1),this.placeholder=this.#m(),this.#r=!1,this.#o=!0,this.parentForm=e.parentElement;this.parentForm&&(this.parentForm=this.parentForm.parentElement,this.parentForm.nodeName!="FORM"););if(this.parentForm.addEventListener("reset",i=>{this.reset()}),this.#i=document.createElement("div"),this.#n=document.createElement("div"),this.#s=document.createElement("ul"),this.#e=document.createElement("input"),this.#i.appendChild(this.#n),this.#n.appendChild(this.#e),this.#i.appendChild(this.#s),this.#t.parentNode.insertBefore(this.#i,this.#t.nextSibling),this.#E(),this.#v(),this.#g(),this.#b(),this.server&&!this.liveServer)this.#u();else{let i=Array.from(this.#t.querySelectorAll("option")).map(r=>({value:r.getAttribute("value"),label:r.innerText}));this.#f(i)}}static init(e="select[multiple]",t={}){let s=document.querySelectorAll(e),o;for(let i=0;i{this.#r=!1})}#v(){this.#i.classList.add("form-control","dropdown"),this.isDisabled()&&this.#i.setAttribute("readonly",""),this.#p()===4&&(this.#i.style.height="auto")}#b(){this.#n.addEventListener("click",t=>{this.isDisabled()||(this.#e.style.visibility!="hidden"?this.#e.focus():this.max===1&&this.#c())});let e=this.#t.querySelectorAll("option[selected]");for(let t=0;t{this.#a(),this.#e.value.length>=this.suggestionsThreshold?this.liveServer?this.#u(!0):this.#c():this.#d()}),this.#e.addEventListener("focus",e=>{this.#e.value.length>=this.suggestionsThreshold&&this.#c()}),this.#e.addEventListener("focusout",e=>{this.#d()}),this.#e.addEventListener("keydown",e=>{let t=e.keyCode||e.key;if(this.separator.length&&this.separator.includes(e.key)){e.preventDefault(),this.addItem(this.#e.value,null)&&this.#h();return}switch(t){case 13:case"Enter":e.preventDefault();let s=this.getActiveSelection();s?s.click():this.allowNew&&!this.#S(this.#e.value)&&this.#e.value&&this.addItem(this.#e.value,null)&&this.#h();break;case 38:case"ArrowUp":e.preventDefault(),this.#r=!0;let o=this.#w();this.#e.value.length==0&&this.#s.classList.contains("show")&&!o&&this.#d();break;case 40:case"ArrowDown":e.preventDefault(),this.#r=!0,this.#y(),this.#e.value.length==0&&!this.#s.classList.contains("show")&&this.#c();break;case 8:case"Backspace":this.#e.value.length==0&&(this.removeLastItem(),this.#a(),this.#d());break}})}#w(){let e=this.getActiveSelection();if(e){let t=e.parentNode;do t=t.previousSibling;while(t&&t.style.display=="none");return t?(e.classList.remove(...b),t.querySelector("a").classList.add(...b),t.parentNode.scrollTop=t.offsetTop-t.parentNode.offsetTop,t):null}return null}#y(){let e=this.getActiveSelection(),t=null;if(e){t=e.parentNode;do t=t.nextSibling;while(t&&t.style.display=="none");return t?(e.classList.remove(...b),t.querySelector("a").classList.add(...b),t.offsetTop>t.parentNode.offsetHeight-t.offsetHeight&&(t.parentNode.scrollTop+=t.offsetHeight),t):null}return t}#a(){this.#e.value?this.#e.size=this.#e.value.length+1:this.getSelectedValues().length?(this.#e.placeholder="",this.#e.size=1):(this.#e.size=this.placeholder.length,this.#e.placeholder=this.placeholder)}#f(e=null){for(;this.#s.lastChild;)this.#s.removeChild(this.#s.lastChild);for(let t=0;t{this.#r||(this.removeActiveSelection(),o.querySelector("a").classList.add(...b))}),i.addEventListener("mousemove",r=>{this.#r=!1}),i.addEventListener("mousedown",r=>{r.preventDefault()}),i.addEventListener("click",r=>{r.preventDefault(),this.addItem(i.innerText,i.getAttribute(C),i.dataset),this.#h()})}}reset(){this.removeAll(),this.#o=!1;let e=this.#t.querySelectorAll("option[data-init]");for(let t=0;tt.value)}getSelectedOptions(){return this.#t.querySelectorAll("option[selected]")}#c(){this.#s.classList.contains("show")||this.#s.classList.add("show"),this.#s.style.left=this.#e.offsetLeft+"px";let e=this.#e.value.toLocaleLowerCase(),t=this.getSelectedValues(),s=this.#s.querySelectorAll("li"),o=!1,i=null,r=!1;for(let l=0;ls.textContent==e);return!!(t&&t.getAttribute("selected"))}#L(e){return new RegExp(this.validationRegex.trim()).test(e)}getActiveSelection(){return this.#s.querySelector("a."+Me)}removeActiveSelection(){let e=this.getActiveSelection();e&&e.classList.remove(...b)}removeAll(){this.#n.querySelectorAll("span").forEach(t=>{this.removeLastItem(!0)})}removeLastItem(e){e&&(this.#o=!1);let t=this.#n.querySelectorAll("span");if(!t.length)return;let s=t[t.length-1];this.removeItem(s.getAttribute(C)),this.#o=!0}isDisabled(){return this.#t.hasAttribute("disabled")||this.#t.hasAttribute("readonly")}addItem(e,t=null,s={}){if(t||(t=e),this.max&&this.getSelectedValues().length>=this.max)if(this.max===1)this.removeLastItem(!0);else return!1;if(this.validationRegex&&!this.#L(e))return this.#i.classList.add("is-invalid"),!1;let o=this.#p(),i=this.#t.querySelector('option[value="'+t+'"]');i&&(s=i.dataset);let r=e,l=document.createElement("span"),c=["badge"],h=this.badgeStyle;if(s.badgeStyle&&(h=s.badgeStyle),s.badgeClass&&c.push(s.badgeClass),o===5?c=[...c,"me-2","bg-"+h]:c=[...c,"mr-2","badge-"+h],l.classList.add(...c),l.setAttribute(C,t),this.allowClear&&!this.isDisabled()&&(r=(o===5?'':'')+r),l.innerHTML=r,this.#n.insertBefore(l,this.#e),this.allowClear&&!this.isDisabled()&&l.querySelector("button").addEventListener("click",a=>{a.preventDefault(),a.stopPropagation(),this.removeItem(t),document.activeElement.blur()}),!i){i=document.createElement("option"),i.value=t,i.innerText=e;for(let[a,f]of Object.entries(s))i.dataset[a]=f;this.#t.appendChild(i)}return i.setAttribute("selected","selected"),i.selected=!0,this.#o&&this.#t.dispatchEvent(new Event("change"),{bubbles:!0}),!0}removeItem(e){let t=this.#n.querySelector("span["+C+'="'+e+'"]');if(!t)return;t.remove();let s=this.#t.querySelector('option[value="'+e+'"]');s&&(s.removeAttribute("selected"),s.selected=!1,this.#o&&this.#t.dispatchEvent(new Event("change"),{bubbles:!0})),this.#e.style.visibility=="hidden"&&this.max&&this.getSelectedValues().length{let n=!1;try{let e=Object.defineProperty({},"passive",{get(){return n=!0,n}});document[j]("DOMContentLoaded",function t(){document[T]("DOMContentLoaded",t,e)},e)}catch(e){throw Error("Passive events are not supported")}return n})(),de=Ce;var Ae=de?{passive:!0}:!1,_=Ae;function L(n,e){n.classList.add(e)}function x(n,e){return n.classList.contains(e)}function p(n,e){n.classList.remove(e)}var je="aria-expanded",U=je;var Te="show",m=Te;var Ne="data-bs-toggle",K=Ne;var De=["dropdown","dropup","dropstart","dropend"],g=De;var Ie="dropdown-menu",Y=Ie;function C(n,e){let t=new CustomEvent(n,{cancelable:!0});return e instanceof Object&&Object.keys(e).forEach(s=>{Object.defineProperty(t,s,{value:e[s]})}),t}function O(n){let e=n.closest("A");return n&&(n.hasAttribute("href")&&n.href.slice(-1)==="#"||e&&e.hasAttribute("href")&&e.href.slice(-1)==="#")}function N(n){n.focus()}function k(n){return n==="true"?!0:n==="false"?!1:Number.isNaN(+n)?n===""||n==="null"?null:n:+n}var qe=n=>Object.keys(n),H=qe;function J(n,e,t,s){let o={...n.dataset},i={},r={};return H(o).forEach(l=>{let c=s&&l.includes(s)?l.replace(s,"").replace(/[A-Z]/,h=>h.toLowerCase()):l;r[c]=k(o[l])}),H(t).forEach(l=>{t[l]=k(t[l])}),H(e).forEach(l=>{l in t?i[l]=t[l]:l in r?i[l]=r[l]:i[l]=e[l]}),i}var V=class{constructor(e,t,s,o){let i=this,r=y(t);r[e]&&r[e].dispose(),i.element=r,s&&Object.keys(s).length&&(i.options=J(r,s,o||{},"bs")),r[e]=i}dispose(e){let t=this;t.element[e]=null,Object.keys(t).forEach(s=>{t[s]=null})}};var[u]=g,v="Dropdown",Q=`[${K}="${u}"]`,D=g[1],M=g[2],P=g[3],S=`${Y}-end`,he=["d-block","invisible"],Oe=[u,D],ue=[M,P],ke={offset:5,display:"dynamic"},Z=C(`show.bs.${u}`),fe=C(`shown.bs.${u}`),G=C(`hide.bs.${u}`),pe=C(`hidden.bs.${u}`);function X(n,e){let{element:t,menu:s,originalClass:o,menuEnd:i,options:r}=n,{offset:l}=r,c=t.parentElement;if(["margin","top","bottom","left","right"].forEach(d=>{s.style[d]=""}),p(c,"position-static"),!e){let d=x(s,S);c.className=o.join(" "),d&&!i?p(s,S):!d&&i&&L(s,S);return}let a=g.find(d=>o.includes(d))||u,f={dropdown:[l,0,0],dropup:[0,0,l],dropstart:[-1,l,0],dropend:[-1,0,0,l]},I={dropdown:{top:"100%"},dropup:{top:"auto",bottom:"100%"},dropstart:{left:"auto",right:"100%"},dropend:{left:"100%",right:"auto"},menuEnd:{right:0,left:"auto"}};he.forEach(d=>L(s,d));let we=new RegExp(`\\b(${u}|${D}|${M}|${P})+`),R={w:t.offsetWidth,h:t.offsetHeight},E={w:s.offsetWidth,h:s.offsetHeight},se=document.documentElement,ie=document.body,ne=se.clientWidth||ie.clientWidth,oe=se.clientHeight||ie.clientHeight,w=t.getBoundingClientRect(),ye=w.left+R.w-E.w<0,re=w.left-E.w<0,Le=w.left+E.w>=ne,le=w.left+E.w+R.w>=ne,z=w.top+E.h>=oe,ae=w.top+E.h+R.h>=oe,ce=w.top-E.h<0;ue.includes(a)&&re&&le&&(a=u),ue.includes(a)&&z&&(a=D),a===M&&re&&!z&&(a=P),a===P&&le&&!z&&(a=M),a===D&&ce&&!ae&&(a=u),a===u&&ae&&!ce&&(a=D),f=f[a],s.style.margin=`${f.map(d=>d&&`${d}px`).join(" ")}`,Object.keys(I[a]).forEach(d=>{s.style[d]=I[a][d]}),x(c,a)||(c.className=c.className.replace(we,a)),Oe.includes(a)&&(!i&&Le?L(s,S):i&&ye&&p(s,S),x(s,S)&&Object.keys(I.menuEnd).forEach(d=>{s.style[d]=I.menuEnd[d]})),he.forEach(d=>p(s,d))}function me(n){let e=n.open?j:T;document[e]("click",ve),document[e]("focus",ve),document[e]("keydown",$e),document[e]("keyup",Ve),n.options.display==="dynamic"&&(window[e]("scroll",be,_),window[e]("resize",be,_))}function ge(n,e){let t=e?j:T;n.element[t]("click",He)}function ee(){let n=g.concat("btn-group").map(e=>document.getElementsByClassName(`${e} ${m}`)).find(e=>e.length);return n&&n.length?Array.from(n[0].children).find(e=>e.hasAttribute(K)):null}function ve(n){let{target:e,type:t}=n;if(!e.closest)return;let s=ee(),o=s&&s.parentNode,i=s&&s[v],r=i&&i.menu,l=e.closest(Q)!==null,c=o&&o.contains(e)&&(e.tagName==="form"||e.closest("form")!==null);t==="click"&&O(e)&&n.preventDefault(),!(t==="focus"&&(e===s||e===r||r.contains(e)))&&(c||l||i&&i.hide(s))}function He(n){let e=this;e[v].toggle(e),O(n.target)&&n.preventDefault()}function $e(n){(n.which===38||n.which===40)&&n.preventDefault()}function Ve({which:n}){let e=ee(),t=e[v],{menu:s,menuItems:o,open:i}=t,r=document.activeElement,l=r===e,c=s.contains(r),h=r.parentNode===s||r.parentNode.parentNode===s,a=o.indexOf(r);h&&(l?a=0:n===38?a=a>1?a-1:0:n===40&&(a=a{l.children.length&&l.children[0].tagName==="A"&&s.menuItems.push(l.children[0]),l.tagName==="A"&&s.menuItems.push(l)}),s.open=!1,ge(s,1)}toggle(e){let t=this,{open:s}=t;s?t.hide(e):t.show(e)}show(e){let t=this,s=y(g.concat("btn-group").map(h=>`.${h}.${m}`).join(",")),o=s&&y(Q,s);o&&o[v].hide();let{element:i,menu:r,open:l}=t,c=i.parentNode;Z.relatedTarget=e||null,c.dispatchEvent(Z),!Z.defaultPrevented&&(X(t,1),L(r,m),L(c,m),i.setAttribute(U,!0),t.open=!l,setTimeout(()=>{N(r.getElementsByTagName("INPUT")[0]||i),me(t),fe.relatedTarget=e||null,c.dispatchEvent(fe)},1))}hide(e){let t=this,{element:s,menu:o,open:i}=t,r=s.parentNode;G.relatedTarget=e||null,r.dispatchEvent(G),!G.defaultPrevented&&(p(o,m),p(r,m),X(t),s.setAttribute(U,!1),t.open=!i,N(s),setTimeout(()=>me(t),1),pe.relatedTarget=e||null,r.dispatchEvent(pe))}dispose(){let e=this,{element:t}=e;x(t.parentNode,m)&&e.open&&e.hide(),ge(e),super.dispose(v)}};B.init={component:v,selector:Q,constructor:B};var Me="is-active",b=["is-active","bg-primary","text-white"],A="data-value",te=new WeakMap,F=class{#l;#t;#i;#n;#s;#e;#r;#o;constructor(e,t={}){e.style.display="none",e.dataset.tags=!0,this.#t=e;let s=i=>["true","false","1","0",!0,!1].includes(i)&&!!JSON.parse(i),o={...t,...e.dataset};for(this.allowNew=o.allowNew?s(o.allowNew):!1,this.showAllSuggestions=o.showAllSuggestions?s(o.showAllSuggestions):!1,this.badgeStyle=o.badgeStyle||"primary",this.allowClear=o.allowClear?s(o.allowClear):!1,this.server=o.server||!1,this.liveServer=o.liveServer?s(o.liveServer):!1,this.suggestionsThreshold=o.suggestionsThreshold?parseInt(o.suggestionsThreshold):1,this.validationRegex=o.regex||"",this.separator=o.separator?o.separator.split("|"):[],this.max=o.max?parseInt(o.max):null,this.clearLabel=o.clearLabel||"Clear",this.searchLabel=o.searchLabel||"Type a value",e.hasAttribute("multiple")||(this.max=1),this.placeholder=this.#m(),this.#r=!1,this.#o=!0,this.parentForm=e.parentElement;this.parentForm&&(this.parentForm=this.parentForm.parentElement,this.parentForm.nodeName!="FORM"););if(this.parentForm.addEventListener("reset",i=>{this.reset()}),this.#i=document.createElement("div"),this.#n=document.createElement("div"),this.#s=document.createElement("ul"),this.#e=document.createElement("input"),this.#i.appendChild(this.#n),this.#n.appendChild(this.#e),this.#i.appendChild(this.#s),this.#t.parentNode.insertBefore(this.#i,this.#t.nextSibling),this.#E(),this.#v(),this.#g(),this.#b(),this.server&&!this.liveServer)this.#u();else{let i=Array.from(this.#t.querySelectorAll("option")).map(r=>({value:r.getAttribute("value"),label:r.innerText}));this.#f(i)}}static init(e="select[multiple]",t={}){let s=document.querySelectorAll(e),o;for(let i=0;i{this.#r=!1})}#v(){this.#i.classList.add("form-control","dropdown"),this.isDisabled()&&this.#i.setAttribute("readonly",""),this.#p()===4&&(this.#i.style.height="auto")}#b(){this.#n.addEventListener("click",t=>{this.isDisabled()||(this.#e.style.visibility!="hidden"?this.#e.focus():this.max===1&&this.#c())});let e=this.#t.selectedOptions;for(let t=0;t{this.#a(),this.#e.value.length>=this.suggestionsThreshold?this.liveServer?this.#u(!0):this.#c():this.#d()}),this.#e.addEventListener("focus",e=>{this.#e.value.length>=this.suggestionsThreshold&&this.#c()}),this.#e.addEventListener("focusout",e=>{this.#d()}),this.#e.addEventListener("keydown",e=>{let t=e.keyCode||e.key;if(this.separator.length&&this.separator.includes(e.key)){e.preventDefault(),this.addItem(this.#e.value,null)&&this.#h();return}switch(t){case 13:case"Enter":e.preventDefault();let s=this.getActiveSelection();s?s.click():this.allowNew&&!this.#L(this.#e.value)&&this.#e.value&&this.addItem(this.#e.value,null)&&this.#h();break;case 38:case"ArrowUp":e.preventDefault(),this.#r=!0;let o=this.#w();this.#e.value.length==0&&this.#s.classList.contains("show")&&!o&&this.#d();break;case 40:case"ArrowDown":e.preventDefault(),this.#r=!0,this.#y(),this.#e.value.length==0&&!this.#s.classList.contains("show")&&this.#c();break;case 8:case"Backspace":this.#e.value.length==0&&(this.removeLastItem(),this.#a(),this.#d());break}})}#w(){let e=this.getActiveSelection();if(e){let t=e.parentNode;do t=t.previousSibling;while(t&&t.style.display=="none");return t?(e.classList.remove(...b),t.querySelector("a").classList.add(...b),t.parentNode.scrollTop=t.offsetTop-t.parentNode.offsetTop,t):null}return null}#y(){let e=this.getActiveSelection(),t=null;if(e){t=e.parentNode;do t=t.nextSibling;while(t&&t.style.display=="none");return t?(e.classList.remove(...b),t.querySelector("a").classList.add(...b),t.offsetTop>t.parentNode.offsetHeight-t.offsetHeight&&(t.parentNode.scrollTop+=t.offsetHeight),t):null}return t}#a(){this.#e.value?this.#e.size=this.#e.value.length+1:this.getSelectedValues().length?(this.#e.placeholder="",this.#e.size=1):(this.#e.size=this.placeholder.length,this.#e.placeholder=this.placeholder)}#f(e=null){for(;this.#s.lastChild;)this.#s.removeChild(this.#s.lastChild);for(let t=0;t{this.#r||(this.removeActiveSelection(),o.querySelector("a").classList.add(...b))}),i.addEventListener("mousemove",r=>{this.#r=!1}),i.addEventListener("mousedown",r=>{r.preventDefault()}),i.addEventListener("click",r=>{r.preventDefault(),this.addItem(i.innerText,i.getAttribute(A),i.dataset),this.#h()})}}reset(){this.removeAll(),this.#o=!1;let e=this.#t.querySelectorAll("option[data-init]");for(let t=0;tt.value)}#c(){this.#s.classList.contains("show")||this.#s.classList.add("show"),this.#s.style.left=this.#e.offsetLeft+"px";let e=this.#e.value.toLocaleLowerCase(),t=this.getSelectedValues(),s=this.#s.querySelectorAll("li"),o=!1,i=null,r=!1;for(let l=0;ls.textContent==e);return!!(t&&t.getAttribute("selected"))}#x(e){return new RegExp(this.validationRegex.trim()).test(e)}getActiveSelection(){return this.#s.querySelector("a."+Me)}removeActiveSelection(){let e=this.getActiveSelection();e&&e.classList.remove(...b)}removeAll(){this.#n.querySelectorAll("span").forEach(t=>{this.removeLastItem(!0)})}removeLastItem(e){e&&(this.#o=!1);let t=this.#n.querySelectorAll("span");if(!t.length)return;let s=t[t.length-1];this.removeItem(s.getAttribute(A)),this.#o=!0}isDisabled(){return this.#t.hasAttribute("disabled")||this.#t.hasAttribute("readonly")}addItem(e,t=null,s={}){if(t||(t=e),this.max&&this.getSelectedValues().length>=this.max)if(this.max===1)this.removeLastItem(!0);else return!1;if(this.validationRegex&&!this.#x(e))return this.#i.classList.add("is-invalid"),!1;let o=this.#p(),i=this.#t.querySelector('option[value="'+t+'"]');i&&(s=i.dataset);let r=e,l=document.createElement("span"),c=["badge"],h=this.badgeStyle;if(s.badgeStyle&&(h=s.badgeStyle),s.badgeClass&&c.push(s.badgeClass),o===5?c=[...c,"me-2","bg-"+h]:c=[...c,"mr-2","badge-"+h],l.classList.add(...c),l.setAttribute(A,t),this.allowClear&&!this.isDisabled()&&(r=(o===5?'':'')+r),l.innerHTML=r,this.#n.insertBefore(l,this.#e),this.allowClear&&!this.isDisabled()&&l.querySelector("button").addEventListener("click",a=>{a.preventDefault(),a.stopPropagation(),this.removeItem(t),document.activeElement.blur()}),!i){i=document.createElement("option"),i.value=t,i.innerText=e;for(let[a,f]of Object.entries(s))i.dataset[a]=f;this.#t.appendChild(i)}return i.setAttribute("selected","selected"),i.selected=!0,this.#o&&this.#t.dispatchEvent(new Event("change"),{bubbles:!0}),!0}removeItem(e){let t=this.#n.querySelector("span["+A+'="'+e+'"]');if(!t)return;t.remove();let s=this.#t.querySelector('option[value="'+e+'"]');s&&(s.removeAttribute("selected"),s.selected=!1,this.#o&&this.#t.dispatchEvent(new Event("change"),{bubbles:!0})),this.#e.style.visibility=="hidden"&&this.max&&this.getSelectedValues().length {\n let result = false;\n try {\n const opts = Object.defineProperty({}, 'passive', {\n get() {\n result = true;\n return result;\n },\n });\n document[addEventListener]('DOMContentLoaded', function wrap() {\n document[removeEventListener]('DOMContentLoaded', wrap, opts);\n }, opts);\n } catch (e) {\n throw Error('Passive events are not supported');\n }\n\n return result;\n})();\n\nexport default supportPassive;\n", "// general event options\n// not suited for scroll prevention\n// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection\nimport supportPassive from '../boolean/supportPassive';\n\n/**\n * A global namespace for most scroll event listeners.\n */\nconst passiveHandler = supportPassive ? { passive: true } : false;\n\nexport default passiveHandler;\n", "/**\n * Add class to Element.classList\n *\n * @param {Element} element target\n * @param {string} classNAME to add\n */\nexport default function addClass(element, classNAME) {\n element.classList.add(classNAME);\n}\n", "/**\n * Check class in Element.classList\n *\n * @param {Element} element target\n * @param {string} classNAME to check\n * @return {boolean}\n */\nexport default function hasClass(element, classNAME) {\n return element.classList.contains(classNAME);\n}\n", "/**\n * Remove class from Element.classList\n *\n * @param {Element} element target\n * @param {string} classNAME to remove\n */\nexport default function removeClass(element, classNAME) {\n element.classList.remove(classNAME);\n}\n", "const ariaExpanded = 'aria-expanded';\nexport default ariaExpanded;\n", "const showClass = 'show';\nexport default showClass;\n", "const dataBsToggle = 'data-bs-toggle';\nexport default dataBsToggle;\n", "const dropdownMenuClasses = ['dropdown', 'dropup', 'dropstart', 'dropend'];\nexport default dropdownMenuClasses;\n", "const dropdownMenuClass = 'dropdown-menu';\nexport default dropdownMenuClass;\n", "export default function bootstrapCustomEvent(namespacedEventType, eventProperties) {\n const OriginalCustomEvent = new CustomEvent(namespacedEventType, { cancelable: true });\n\n if (eventProperties instanceof Object) {\n Object.keys(eventProperties).forEach((key) => {\n Object.defineProperty(OriginalCustomEvent, key, {\n value: eventProperties[key],\n });\n });\n }\n return OriginalCustomEvent;\n}\n", "export default function isEmptyAnchor(elem) {\n const parentAnchor = elem.closest('A');\n // anchor href starts with #\n return elem && ((elem.hasAttribute('href') && elem.href.slice(-1) === '#')\n // OR a child of an anchor with href starts with #\n || (parentAnchor && parentAnchor.hasAttribute('href') && parentAnchor.href.slice(-1) === '#'));\n}\n", "export default function setFocus(element) {\n element.focus();\n}\n", "/**\n * The raw value or a given component option.\n *\n * @typedef {string | Element | Function | number | boolean | null} niceValue\n */\n\n/**\n * Utility to normalize component options\n *\n * @param {any} value the input value\n * @return {niceValue} the normalized value\n */\nexport default function normalizeValue(value) {\n if (value === 'true') { // boolean\n return true;\n }\n\n if (value === 'false') { // boolean\n return false;\n }\n\n if (!Number.isNaN(+value)) { // number\n return +value;\n }\n\n if (value === '' || value === 'null') { // null\n return null;\n }\n\n // string / function / Element / object\n return value;\n}\n", "/**\n * Shortcut for `Object.keys()` static method.\n * @param {Record} obj a target object\n * @returns {string[]}\n */\nconst ObjectKeys = (obj) => Object.keys(obj);\nexport default ObjectKeys;\n", "import normalizeValue from './normalizeValue';\nimport ObjectKeys from './ObjectKeys';\n\n/**\n * Utility to normalize component options\n *\n * @param {Element} element target\n * @param {Record} defaultOps component default options\n * @param {Record} inputOps component instance options\n * @param {string=} ns component namespace\n * @return {Record} normalized component options object\n */\nexport default function normalizeOptions(element, defaultOps, inputOps, ns) {\n // @ts-ignore -- usually our `Element` is `HTMLElement` as well\n const data = { ...element.dataset };\n const normalOps = {};\n const dataOps = {};\n\n ObjectKeys(data).forEach((k) => {\n const key = ns && k.includes(ns)\n ? k.replace(ns, '').replace(/[A-Z]/, (match) => match.toLowerCase())\n : k;\n\n dataOps[key] = normalizeValue(data[k]);\n });\n\n ObjectKeys(inputOps).forEach((k) => {\n inputOps[k] = normalizeValue(inputOps[k]);\n });\n\n ObjectKeys(defaultOps).forEach((k) => {\n if (k in inputOps) {\n normalOps[k] = inputOps[k];\n } else if (k in dataOps) {\n normalOps[k] = dataOps[k];\n } else {\n normalOps[k] = defaultOps[k];\n }\n });\n\n return normalOps;\n}\n", "/* Native JavaScript for Bootstrap 5 | Base Component\n----------------------------------------------------- */\n\nimport queryElement from 'shorter-js/src/misc/queryElement.js';\nimport normalizeOptions from 'shorter-js/src/misc/normalizeOptions.js';\n\nexport default class BaseComponent {\n constructor(name, target, defaults, config) {\n const self = this;\n const element = queryElement(target);\n\n if (element[name]) element[name].dispose();\n self.element = element;\n\n if (defaults && Object.keys(defaults).length) {\n self.options = normalizeOptions(element, defaults, (config || {}), 'bs');\n }\n element[name] = self;\n }\n\n dispose(name) {\n const self = this;\n self.element[name] = null;\n Object.keys(self).forEach((prop) => { self[prop] = null; });\n }\n}\n", "/* Native JavaScript for Bootstrap 5 | Dropdown\n----------------------------------------------- */\nimport queryElement from 'shorter-js/src/misc/queryElement.js';\nimport passiveHandler from 'shorter-js/src/misc/passiveHandler.js';\nimport addClass from 'shorter-js/src/class/addClass.js';\nimport hasClass from 'shorter-js/src/class/hasClass.js';\nimport removeClass from 'shorter-js/src/class/removeClass.js';\nimport addEventListener from 'shorter-js/src/strings/addEventListener.js';\nimport removeEventListener from 'shorter-js/src/strings/removeEventListener.js';\n\nimport ariaExpanded from '../strings/ariaExpanded.js';\nimport showClass from '../strings/showClass.js';\nimport dataBsToggle from '../strings/dataBsToggle.js';\nimport dropdownClasses from '../strings/dropdownClasses.js';\nimport dropdownMenuClass from '../strings/dropdownMenuClass.js';\n\nimport bootstrapCustomEvent from '../util/bootstrapCustomEvent.js';\nimport isEmptyAnchor from '../util/isEmptyAnchor.js';\nimport setFocus from '../util/setFocus.js';\nimport BaseComponent from './base-component.js';\n\n// DROPDOWN PRIVATE GC\n// ===================\nconst [dropdownString] = dropdownClasses;\nconst dropdownComponent = 'Dropdown';\nconst dropdownSelector = `[${dataBsToggle}=\"${dropdownString}\"]`;\n\n// DROPDOWN PRIVATE GC\n// ===================\nconst dropupString = dropdownClasses[1];\nconst dropstartString = dropdownClasses[2];\nconst dropendString = dropdownClasses[3];\nconst dropdownMenuEndClass = `${dropdownMenuClass}-end`;\nconst hideMenuClass = ['d-block', 'invisible'];\nconst verticalClass = [dropdownString, dropupString];\nconst horizontalClass = [dropstartString, dropendString];\nconst defaultDropdownOptions = {\n offset: 5, // [number] 5(px)\n display: 'dynamic', // [dynamic|static]\n};\n\n// DROPDOWN CUSTOM EVENTS\n// ========================\nconst showDropdownEvent = bootstrapCustomEvent(`show.bs.${dropdownString}`);\nconst shownDropdownEvent = bootstrapCustomEvent(`shown.bs.${dropdownString}`);\nconst hideDropdownEvent = bootstrapCustomEvent(`hide.bs.${dropdownString}`);\nconst hiddenDropdownEvent = bootstrapCustomEvent(`hidden.bs.${dropdownString}`);\n\n// DROPDOWN PRIVATE METHODS\n// ========================\nfunction styleDropdown(self, show) {\n const {\n element, menu, originalClass, menuEnd, options,\n } = self;\n const { offset } = options;\n const parent = element.parentElement;\n\n // reset menu offset and position\n const resetProps = ['margin', 'top', 'bottom', 'left', 'right'];\n resetProps.forEach((p) => { menu.style[p] = ''; });\n removeClass(parent, 'position-static');\n\n if (!show) {\n const menuEndNow = hasClass(menu, dropdownMenuEndClass);\n parent.className = originalClass.join(' ');\n if (menuEndNow && !menuEnd) removeClass(menu, dropdownMenuEndClass);\n else if (!menuEndNow && menuEnd) addClass(menu, dropdownMenuEndClass);\n return;\n }\n\n // set initial position class\n // take into account .btn-group parent as .dropdown\n let positionClass = dropdownClasses.find((c) => originalClass.includes(c)) || dropdownString;\n\n let dropdownMargin = {\n dropdown: [offset, 0, 0],\n dropup: [0, 0, offset],\n dropstart: [-1, offset, 0],\n dropend: [-1, 0, 0, offset],\n };\n\n const dropdownPosition = {\n dropdown: { top: '100%' },\n dropup: { top: 'auto', bottom: '100%' },\n dropstart: { left: 'auto', right: '100%' },\n dropend: { left: '100%', right: 'auto' },\n menuEnd: { right: 0, left: 'auto' },\n };\n\n // force showing the menu to calculate its size\n hideMenuClass.forEach((c) => addClass(menu, c));\n\n const dropdownRegex = new RegExp(`\\\\b(${dropdownString}|${dropupString}|${dropstartString}|${dropendString})+`);\n const elementDimensions = { w: element.offsetWidth, h: element.offsetHeight };\n const menuDimensions = { w: menu.offsetWidth, h: menu.offsetHeight };\n const HTML = document.documentElement;\n const BD = document.body;\n const windowWidth = (HTML.clientWidth || BD.clientWidth);\n const windowHeight = (HTML.clientHeight || BD.clientHeight);\n const targetBCR = element.getBoundingClientRect();\n // dropdownMenuEnd && [ dropdown | dropup ]\n const leftExceed = targetBCR.left + elementDimensions.w - menuDimensions.w < 0;\n // dropstart\n const leftFullExceed = targetBCR.left - menuDimensions.w < 0;\n // !dropdownMenuEnd && [ dropdown | dropup ]\n const rightExceed = targetBCR.left + menuDimensions.w >= windowWidth;\n // dropend\n const rightFullExceed = targetBCR.left + menuDimensions.w + elementDimensions.w >= windowWidth;\n // dropstart | dropend\n const bottomExceed = targetBCR.top + menuDimensions.h >= windowHeight;\n // dropdown\n const bottomFullExceed = targetBCR.top + menuDimensions.h + elementDimensions.h >= windowHeight;\n // dropup\n const topExceed = targetBCR.top - menuDimensions.h < 0;\n\n // recompute position\n if (horizontalClass.includes(positionClass) && leftFullExceed && rightFullExceed) {\n positionClass = dropdownString;\n }\n if (horizontalClass.includes(positionClass) && bottomExceed) {\n positionClass = dropupString;\n }\n if (positionClass === dropstartString && leftFullExceed && !bottomExceed) {\n positionClass = dropendString;\n }\n if (positionClass === dropendString && rightFullExceed && !bottomExceed) {\n positionClass = dropstartString;\n }\n if (positionClass === dropupString && topExceed && !bottomFullExceed) {\n positionClass = dropdownString;\n }\n if (positionClass === dropdownString && bottomFullExceed && !topExceed) {\n positionClass = dropupString;\n }\n\n // set spacing\n dropdownMargin = dropdownMargin[positionClass];\n menu.style.margin = `${dropdownMargin.map((x) => (x ? `${x}px` : x)).join(' ')}`;\n Object.keys(dropdownPosition[positionClass]).forEach((position) => {\n menu.style[position] = dropdownPosition[positionClass][position];\n });\n\n // update dropdown position class\n if (!hasClass(parent, positionClass)) {\n parent.className = parent.className.replace(dropdownRegex, positionClass);\n }\n\n // update dropdown / dropup to handle parent btn-group element\n // as well as the dropdown-menu-end utility class\n if (verticalClass.includes(positionClass)) {\n if (!menuEnd && rightExceed) addClass(menu, dropdownMenuEndClass);\n else if (menuEnd && leftExceed) removeClass(menu, dropdownMenuEndClass);\n\n if (hasClass(menu, dropdownMenuEndClass)) {\n Object.keys(dropdownPosition.menuEnd).forEach((p) => {\n menu.style[p] = dropdownPosition.menuEnd[p];\n });\n }\n }\n\n // remove util classes from the menu, we have its size\n hideMenuClass.forEach((c) => removeClass(menu, c));\n}\n\nfunction toggleDropdownDismiss(self) {\n const action = self.open ? addEventListener : removeEventListener;\n\n document[action]('click', dropdownDismissHandler);\n document[action]('focus', dropdownDismissHandler);\n document[action]('keydown', dropdownPreventScroll);\n document[action]('keyup', dropdownKeyHandler);\n\n if (self.options.display === 'dynamic') {\n window[action]('scroll', dropdownLayoutHandler, passiveHandler);\n window[action]('resize', dropdownLayoutHandler, passiveHandler);\n }\n}\n\nfunction toggleDropdownHandler(self, add) {\n const action = add ? addEventListener : removeEventListener;\n self.element[action]('click', dropdownClickHandler);\n}\n\nfunction getCurrentOpenDropdown() {\n const currentParent = dropdownClasses.concat('btn-group')\n .map((c) => document.getElementsByClassName(`${c} ${showClass}`))\n .find((x) => x.length);\n\n if (currentParent && currentParent.length) {\n return Array.from(currentParent[0].children).find((x) => x.hasAttribute(dataBsToggle));\n }\n return null;\n}\n\n// DROPDOWN EVENT HANDLERS\n// =======================\nfunction dropdownDismissHandler(e) {\n const { target, type } = e;\n if (!target.closest) return; // some weird FF bug #409\n\n const element = getCurrentOpenDropdown();\n const parent = element && element.parentNode;\n const self = element && element[dropdownComponent];\n const menu = self && self.menu;\n\n const hasData = target.closest(dropdownSelector) !== null;\n const isForm = parent && parent.contains(target)\n && (target.tagName === 'form' || target.closest('form') !== null);\n\n if (type === 'click' && isEmptyAnchor(target)) {\n e.preventDefault();\n }\n if (type === 'focus'\n && (target === element || target === menu || menu.contains(target))) {\n return;\n }\n\n if (isForm || hasData) {\n // smile to ESLint\n } else if (self) {\n self.hide(element);\n }\n}\n\nfunction dropdownClickHandler(e) {\n const element = this;\n const self = element[dropdownComponent];\n self.toggle(element);\n\n if (isEmptyAnchor(e.target)) e.preventDefault();\n}\n\nfunction dropdownPreventScroll(e) {\n if (e.which === 38 || e.which === 40) e.preventDefault();\n}\n\nfunction dropdownKeyHandler({ which }) {\n const element = getCurrentOpenDropdown();\n const self = element[dropdownComponent];\n const { menu, menuItems, open } = self;\n const activeItem = document.activeElement;\n const isSameElement = activeItem === element;\n const isInsideMenu = menu.contains(activeItem);\n const isMenuItem = activeItem.parentNode === menu || activeItem.parentNode.parentNode === menu;\n\n let idx = menuItems.indexOf(activeItem);\n\n if (isMenuItem) { // navigate up | down\n if (isSameElement) {\n idx = 0;\n } else if (which === 38) {\n idx = idx > 1 ? idx - 1 : 0;\n } else if (which === 40) {\n idx = idx < menuItems.length - 1 ? idx + 1 : idx;\n }\n\n if (menuItems[idx]) setFocus(menuItems[idx]);\n }\n\n if (((menuItems.length && isMenuItem) // menu has items\n || (!menuItems.length && (isInsideMenu || isSameElement)) // menu might be a form\n || !isInsideMenu) // or the focused element is not in the menu at all\n && open && which === 27 // menu must be open\n ) {\n self.toggle();\n }\n}\n\nfunction dropdownLayoutHandler() {\n const element = getCurrentOpenDropdown();\n const self = element && element[dropdownComponent];\n\n if (self && self.open) styleDropdown(self, 1);\n}\n\n// DROPDOWN DEFINITION\n// ===================\nexport default class Dropdown extends BaseComponent {\n constructor(target, config) {\n super(dropdownComponent, target, defaultDropdownOptions, config);\n // bind\n const self = this;\n\n // initialization element\n const { element } = self;\n\n // set targets\n const parent = element.parentElement;\n self.menu = queryElement(`.${dropdownMenuClass}`, parent);\n const { menu } = self;\n\n self.originalClass = Array.from(parent.classList);\n\n // set original position\n self.menuEnd = hasClass(menu, dropdownMenuEndClass);\n\n self.menuItems = [];\n\n Array.from(menu.children).forEach((child) => {\n if (child.children.length && (child.children[0].tagName === 'A')) self.menuItems.push(child.children[0]);\n if (child.tagName === 'A') self.menuItems.push(child);\n });\n\n // set initial state to closed\n self.open = false;\n\n // add event listener\n toggleDropdownHandler(self, 1);\n }\n\n // DROPDOWN PUBLIC METHODS\n // =======================\n toggle(related) {\n const self = this;\n const { open } = self;\n\n if (open) self.hide(related);\n else self.show(related);\n }\n\n show(related) {\n const self = this;\n const currentParent = queryElement(dropdownClasses.concat('btn-group').map((c) => `.${c}.${showClass}`).join(','));\n const currentElement = currentParent && queryElement(dropdownSelector, currentParent);\n\n if (currentElement) currentElement[dropdownComponent].hide();\n\n const { element, menu, open } = self;\n const parent = element.parentNode;\n\n // update relatedTarget and dispatch\n showDropdownEvent.relatedTarget = related || null;\n parent.dispatchEvent(showDropdownEvent);\n if (showDropdownEvent.defaultPrevented) return;\n\n // change menu position\n styleDropdown(self, 1);\n\n addClass(menu, showClass);\n addClass(parent, showClass);\n\n element.setAttribute(ariaExpanded, true);\n self.open = !open;\n\n setTimeout(() => {\n setFocus(menu.getElementsByTagName('INPUT')[0] || element); // focus the first input item | element\n toggleDropdownDismiss(self);\n\n shownDropdownEvent.relatedTarget = related || null;\n parent.dispatchEvent(shownDropdownEvent);\n }, 1);\n }\n\n hide(related) {\n const self = this;\n const { element, menu, open } = self;\n const parent = element.parentNode;\n hideDropdownEvent.relatedTarget = related || null;\n parent.dispatchEvent(hideDropdownEvent);\n if (hideDropdownEvent.defaultPrevented) return;\n\n removeClass(menu, showClass);\n removeClass(parent, showClass);\n\n // revert to original position\n styleDropdown(self);\n\n element.setAttribute(ariaExpanded, false);\n self.open = !open;\n\n setFocus(element);\n\n // only re-attach handler if the instance is not disposed\n setTimeout(() => toggleDropdownDismiss(self), 1);\n\n // update relatedTarget and dispatch\n hiddenDropdownEvent.relatedTarget = related || null;\n parent.dispatchEvent(hiddenDropdownEvent);\n }\n\n dispose() {\n const self = this;\n const { element } = self;\n\n if (hasClass(element.parentNode, showClass) && self.open) self.hide();\n\n toggleDropdownHandler(self);\n\n super.dispose(dropdownComponent);\n }\n}\n\nDropdown.init = {\n component: dropdownComponent,\n selector: dropdownSelector,\n constructor: Dropdown,\n};\n", "/**\r\n * Bootstrap 5 (and 4!) tags\r\n *\r\n * Turns your select[multiple] into nice tags lists\r\n *\r\n * Required Bootstrap 5 styles:\r\n * - badge\r\n * - background-color utility\r\n * - margin-end utility\r\n * - forms\r\n * - dropdown\r\n */\r\n\r\nconst ACTIVE_CLASS = \"is-active\";\r\nconst ACTIVE_CLASSES = [\"is-active\", \"bg-primary\", \"text-white\"];\r\nconst VALUE_ATTRIBUTE = \"data-value\";\r\n\r\n// Static map will minify very badly as class prop, so we use an external constant\r\nconst INSTANCE_MAP = new WeakMap();\r\n\r\nclass Tags {\r\n #abortController;\r\n #selectElement;\r\n #holderElement;\r\n #containerElement;\r\n #dropElement;\r\n #searchInput;\r\n #keyboardNavigation;\r\n #fireEvents;\r\n\r\n /**\r\n * @param {HTMLSelectElement} el\r\n * @param {Object} globalOpts\r\n */\r\n constructor(el, globalOpts = {}) {\r\n // Hide the select element and register a tags attr\r\n el.style.display = \"none\";\r\n el.dataset.tags = true;\r\n this.#selectElement = el;\r\n\r\n // Allow 1/0, true/false as strings\r\n const parseBool = (value) => [\"true\", \"false\", \"1\", \"0\", true, false].includes(value) && !!JSON.parse(value);\r\n\r\n // Handle options, using global settings first and data attr override\r\n const opts = { ...globalOpts, ...el.dataset };\r\n this.allowNew = opts.allowNew ? parseBool(opts.allowNew) : false;\r\n this.showAllSuggestions = opts.showAllSuggestions ? parseBool(opts.showAllSuggestions) : false;\r\n this.badgeStyle = opts.badgeStyle || \"primary\";\r\n this.allowClear = opts.allowClear ? parseBool(opts.allowClear) : false;\r\n this.server = opts.server || false;\r\n this.liveServer = opts.liveServer ? parseBool(opts.liveServer) : false;\r\n this.suggestionsThreshold = opts.suggestionsThreshold ? parseInt(opts.suggestionsThreshold) : 1;\r\n this.validationRegex = opts.regex || \"\";\r\n this.separator = opts.separator ? opts.separator.split(\"|\") : [];\r\n this.max = opts.max ? parseInt(opts.max) : null;\r\n this.clearLabel = opts.clearLabel || \"Clear\";\r\n this.searchLabel = opts.searchLabel || \"Type a value\";\r\n if (!el.hasAttribute(\"multiple\")) {\r\n this.max = 1;\r\n }\r\n\r\n this.placeholder = this.#getPlaceholder();\r\n this.#keyboardNavigation = false;\r\n this.#fireEvents = true;\r\n\r\n this.parentForm = el.parentElement;\r\n while (this.parentForm) {\r\n this.parentForm = this.parentForm.parentElement;\r\n if (this.parentForm.nodeName == \"FORM\") {\r\n break;\r\n }\r\n }\r\n this.parentForm.addEventListener(\"reset\", (ev) => {\r\n this.reset();\r\n });\r\n\r\n // Create elements\r\n this.#holderElement = document.createElement(\"div\"); // this is the one holding the fake input and the dropmenu\r\n this.#containerElement = document.createElement(\"div\"); // this is the one for the fake input (labels + input)\r\n this.#dropElement = document.createElement(\"ul\");\r\n this.#searchInput = document.createElement(\"input\");\r\n\r\n this.#holderElement.appendChild(this.#containerElement);\r\n this.#containerElement.appendChild(this.#searchInput);\r\n this.#holderElement.appendChild(this.#dropElement);\r\n // insert after\r\n this.#selectElement.parentNode.insertBefore(this.#holderElement, this.#selectElement.nextSibling);\r\n\r\n // Configure them\r\n this.#configureSearchInput();\r\n this.#configureHolderElement();\r\n this.#configureDropElement();\r\n this.#configureContainerElement();\r\n\r\n if (this.server && !this.liveServer) {\r\n this.#loadFromServer();\r\n } else {\r\n let suggestions = Array.from(this.#selectElement.querySelectorAll(\"option\")).map((option) => {\r\n return {\r\n value: option.getAttribute(\"value\"),\r\n label: option.innerText,\r\n };\r\n });\r\n this.#buildSuggestions(suggestions);\r\n }\r\n }\r\n\r\n /**\r\n * Attach to all elements matched by the selector\r\n * @param {string} selector\r\n * @param {Object} opts\r\n */\r\n static init(selector = \"select[multiple]\", opts = {}) {\r\n let list = document.querySelectorAll(selector);\r\n let el;\r\n for (let i = 0; i < list.length; i++) {\r\n if (!list[i].dataset.tags) {\r\n el = new Tags(list[i], opts);\r\n INSTANCE_MAP.set(list[i], el);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @param {HTMLSelectElement} el\r\n */\r\n static getInstance(el) {\r\n if (INSTANCE_MAP.has(el)) {\r\n return INSTANCE_MAP.get(el);\r\n }\r\n }\r\n\r\n dispose() {\r\n Data.remove(this._element, this.constructor.DATA_KEY);\r\n EventHandler.off(this._element, this.constructor.EVENT_KEY);\r\n }\r\n\r\n /**\r\n * @param {boolean} show\r\n */\r\n #loadFromServer(show = false) {\r\n if (this.#abortController) {\r\n this.#abortController.abort();\r\n }\r\n this.#abortController = new AbortController();\r\n fetch(this.server + \"?query=\" + encodeURIComponent(this.#searchInput.value), { signal: this.#abortController.signal })\r\n .then((r) => r.json())\r\n .then((suggestions) => {\r\n let data = suggestions.data || suggestions;\r\n this.#buildSuggestions(data);\r\n this.#abortController = null;\r\n if (show) {\r\n this.#showSuggestions();\r\n }\r\n })\r\n .catch((e) => {\r\n if (e.name === \"AbortError\") {\r\n return;\r\n }\r\n console.error(e);\r\n });\r\n }\r\n\r\n /**\r\n * @returns {string}\r\n */\r\n #getPlaceholder() {\r\n let firstOption = this.#selectElement.querySelector(\"option\");\r\n if (!firstOption) {\r\n return;\r\n }\r\n if (!firstOption.value) {\r\n let placeholder = firstOption.innerText;\r\n firstOption.remove();\r\n return placeholder;\r\n }\r\n if (this.#selectElement.getAttribute(\"placeholder\")) {\r\n return this.#selectElement.getAttribute(\"placeholder\");\r\n }\r\n if (this.#selectElement.getAttribute(\"data-placeholder\")) {\r\n return this.#selectElement.getAttribute(\"data-placeholder\");\r\n }\r\n return \"\";\r\n }\r\n\r\n #configureDropElement() {\r\n this.#dropElement.classList.add(...[\"dropdown-menu\", \"p-0\"]);\r\n this.#dropElement.style.maxHeight = \"280px\";\r\n this.#dropElement.style.overflowY = \"auto\";\r\n\r\n // If the mouse was outside, entering remove keyboard nav mode\r\n this.#dropElement.addEventListener(\"mouseenter\", (event) => {\r\n this.#keyboardNavigation = false;\r\n });\r\n }\r\n\r\n #configureHolderElement() {\r\n this.#holderElement.classList.add(...[\"form-control\", \"dropdown\"]);\r\n if (this.isDisabled()) {\r\n this.#holderElement.setAttribute(\"readonly\", \"\");\r\n }\r\n if (this.#getBootstrapVersion() === 4) {\r\n // Prevent fixed height due to form-control\r\n this.#holderElement.style.height = \"auto\";\r\n }\r\n }\r\n\r\n #configureContainerElement() {\r\n this.#containerElement.addEventListener(\"click\", (event) => {\r\n if (this.isDisabled()) {\r\n return;\r\n }\r\n if (this.#searchInput.style.visibility != \"hidden\") {\r\n this.#searchInput.focus();\r\n } else if (this.max === 1) {\r\n // Improve single select usage\r\n this.#showSuggestions();\r\n }\r\n });\r\n\r\n // add initial values\r\n let initialValues = this.#selectElement.querySelectorAll(\"option[selected]\");\r\n for (let j = 0; j < initialValues.length; j++) {\r\n let initialValue = initialValues[j];\r\n if (!initialValue.value) {\r\n continue;\r\n }\r\n // track initial values for reset\r\n initialValue.dataset.init = 1;\r\n this.addItem(initialValue.innerText, initialValue.value);\r\n }\r\n }\r\n\r\n #configureSearchInput() {\r\n this.#searchInput.type = \"text\";\r\n this.#searchInput.autocomplete = \"off\";\r\n this.#searchInput.style.backgroundColor = \"transparent\";\r\n this.#searchInput.style.border = 0;\r\n this.#searchInput.style.outline = 0;\r\n this.#searchInput.style.maxWidth = \"100%\";\r\n this.#searchInput.ariaLabel = this.searchLabel;\r\n if (this.isDisabled()) {\r\n this.#searchInput.setAttribute(\"disabled\", \"\");\r\n }\r\n this.#adjustWidth();\r\n\r\n this.#searchInput.addEventListener(\"input\", (event) => {\r\n this.#adjustWidth();\r\n if (this.#searchInput.value.length >= this.suggestionsThreshold) {\r\n if (this.liveServer) {\r\n this.#loadFromServer(true);\r\n } else {\r\n this.#showSuggestions();\r\n }\r\n } else {\r\n this.#hideSuggestions();\r\n }\r\n });\r\n this.#searchInput.addEventListener(\"focus\", (event) => {\r\n if (this.#searchInput.value.length >= this.suggestionsThreshold) {\r\n this.#showSuggestions();\r\n }\r\n });\r\n this.#searchInput.addEventListener(\"focusout\", (event) => {\r\n this.#hideSuggestions();\r\n });\r\n // keypress doesn't send arrow keys\r\n this.#searchInput.addEventListener(\"keydown\", (event) => {\r\n // Keycode reference : https://css-tricks.com/snippets/javascript/javascript-keycodes/\r\n let key = event.keyCode || event.key;\r\n if (this.separator.length && this.separator.includes(event.key)) {\r\n event.preventDefault();\r\n let res = this.addItem(this.#searchInput.value, null);\r\n if (res) {\r\n this.#resetSearchInput();\r\n }\r\n return;\r\n }\r\n switch (key) {\r\n case 13:\r\n case \"Enter\":\r\n event.preventDefault();\r\n let selection = this.getActiveSelection();\r\n if (selection) {\r\n selection.click();\r\n } else {\r\n // We use what is typed if not selected and not empty\r\n if (this.allowNew && !this.#isSelected(this.#searchInput.value) && this.#searchInput.value) {\r\n let res = this.addItem(this.#searchInput.value, null);\r\n if (res) {\r\n this.#resetSearchInput();\r\n }\r\n }\r\n }\r\n break;\r\n case 38:\r\n case \"ArrowUp\":\r\n event.preventDefault();\r\n this.#keyboardNavigation = true;\r\n let newSelection = this.#moveSelectionUp();\r\n // If we use arrow up without input and there is no new selection, hide suggestions\r\n if (this.#searchInput.value.length == 0 && this.#dropElement.classList.contains(\"show\") && !newSelection) {\r\n this.#hideSuggestions();\r\n }\r\n break;\r\n case 40:\r\n case \"ArrowDown\":\r\n event.preventDefault();\r\n this.#keyboardNavigation = true;\r\n this.#moveSelectionDown();\r\n // If we use arrow down without input, show suggestions\r\n if (this.#searchInput.value.length == 0 && !this.#dropElement.classList.contains(\"show\")) {\r\n this.#showSuggestions();\r\n }\r\n break;\r\n case 8:\r\n case \"Backspace\":\r\n if (this.#searchInput.value.length == 0) {\r\n this.removeLastItem();\r\n this.#adjustWidth();\r\n this.#hideSuggestions();\r\n }\r\n break;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n #moveSelectionUp() {\r\n let active = this.getActiveSelection();\r\n if (active) {\r\n let prev = active.parentNode;\r\n do {\r\n prev = prev.previousSibling;\r\n } while (prev && prev.style.display == \"none\");\r\n if (!prev) {\r\n return null;\r\n }\r\n active.classList.remove(...ACTIVE_CLASSES);\r\n prev.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n // Don't use scrollIntoView as it scrolls the whole window\r\n prev.parentNode.scrollTop = prev.offsetTop - prev.parentNode.offsetTop;\r\n return prev;\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n #moveSelectionDown() {\r\n let active = this.getActiveSelection();\r\n let next = null;\r\n if (active) {\r\n next = active.parentNode;\r\n do {\r\n next = next.nextSibling;\r\n } while (next && next.style.display == \"none\");\r\n if (!next) {\r\n return null;\r\n }\r\n active.classList.remove(...ACTIVE_CLASSES);\r\n next.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n // This is the equivalent of scrollIntoView(false) but only for parent node\r\n if (next.offsetTop > next.parentNode.offsetHeight - next.offsetHeight) {\r\n next.parentNode.scrollTop += next.offsetHeight;\r\n }\r\n return next;\r\n }\r\n return next;\r\n }\r\n\r\n /**\r\n * Adjust the field to fit its content\r\n */\r\n #adjustWidth() {\r\n if (this.#searchInput.value) {\r\n this.#searchInput.size = this.#searchInput.value.length + 1;\r\n } else {\r\n // Show the placeholder only if empty\r\n if (this.getSelectedValues().length) {\r\n this.#searchInput.placeholder = \"\";\r\n this.#searchInput.size = 1;\r\n } else {\r\n this.#searchInput.size = this.placeholder.length;\r\n this.#searchInput.placeholder = this.placeholder;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Add suggestions to the drop element\r\n * @param {array}\r\n */\r\n #buildSuggestions(suggestions = null) {\r\n while (this.#dropElement.lastChild) {\r\n this.#dropElement.removeChild(this.#dropElement.lastChild);\r\n }\r\n for (let i = 0; i < suggestions.length; i++) {\r\n let suggestion = suggestions[i];\r\n if (!suggestion.value) {\r\n continue;\r\n }\r\n let newChild = document.createElement(\"li\");\r\n let newChildLink = document.createElement(\"a\");\r\n newChild.append(newChildLink);\r\n newChildLink.classList.add(\"dropdown-item\");\r\n newChildLink.setAttribute(VALUE_ATTRIBUTE, suggestion.value);\r\n newChildLink.setAttribute(\"href\", \"#\");\r\n newChildLink.innerText = suggestion.label;\r\n if (suggestion.data) {\r\n for (const [key, value] of Object.entries(suggestion.data)) {\r\n newChildLink.dataset[key] = value;\r\n }\r\n }\r\n this.#dropElement.appendChild(newChild);\r\n\r\n // Hover sets active item\r\n newChildLink.addEventListener(\"mouseenter\", (event) => {\r\n // Don't trigger enter if using arrows\r\n if (this.#keyboardNavigation) {\r\n return;\r\n }\r\n this.removeActiveSelection();\r\n newChild.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n });\r\n // Moving the mouse means no longer using keyboard\r\n newChildLink.addEventListener(\"mousemove\", (event) => {\r\n this.#keyboardNavigation = false;\r\n });\r\n\r\n newChildLink.addEventListener(\"mousedown\", (event) => {\r\n // Otherwise searchInput would lose focus and close the menu\r\n event.preventDefault();\r\n });\r\n newChildLink.addEventListener(\"click\", (event) => {\r\n event.preventDefault();\r\n this.addItem(newChildLink.innerText, newChildLink.getAttribute(VALUE_ATTRIBUTE), newChildLink.dataset);\r\n this.#resetSearchInput();\r\n });\r\n }\r\n }\r\n\r\n reset() {\r\n this.removeAll();\r\n\r\n // Reset doesn't fire change event\r\n this.#fireEvents = false;\r\n let initialValues = this.#selectElement.querySelectorAll(\"option[data-init]\");\r\n for (let j = 0; j < initialValues.length; j++) {\r\n let initialValue = initialValues[j];\r\n this.addItem(initialValue.innerText, initialValue.value);\r\n }\r\n this.#adjustWidth();\r\n this.#fireEvents = true;\r\n }\r\n\r\n #resetSearchInput() {\r\n this.#searchInput.value = \"\";\r\n this.#adjustWidth();\r\n this.#hideSuggestions();\r\n\r\n // We use visibility instead of display to keep layout intact\r\n if (this.max && this.getSelectedValues().length === this.max) {\r\n this.#searchInput.style.visibility = \"hidden\";\r\n } else if (this.#searchInput.style.visibility == \"hidden\") {\r\n this.#searchInput.style.visibility = \"visible\";\r\n }\r\n }\r\n\r\n /**\r\n * @returns {array}\r\n */\r\n getSelectedValues() {\r\n let selected = this.getSelectedOptions();\r\n return Array.from(selected).map((el) => el.value);\r\n }\r\n\r\n /**\r\n * @returns {NodeList}\r\n */\r\n getSelectedOptions() {\r\n // :checked can return false positives\r\n return this.#selectElement.querySelectorAll(\"option[selected]\");\r\n }\r\n\r\n /**\r\n * The element create with buildSuggestions\r\n */\r\n #showSuggestions() {\r\n if (!this.#dropElement.classList.contains(\"show\")) {\r\n this.#dropElement.classList.add(\"show\");\r\n }\r\n\r\n // Position next to search input\r\n this.#dropElement.style.left = this.#searchInput.offsetLeft + \"px\";\r\n\r\n // Get search value\r\n let search = this.#searchInput.value.toLocaleLowerCase();\r\n\r\n // Get current values\r\n let values = this.getSelectedValues();\r\n\r\n // Filter the list according to search string\r\n let list = this.#dropElement.querySelectorAll(\"li\");\r\n let found = false;\r\n let firstItem = null;\r\n let hasPossibleValues = false;\r\n for (let i = 0; i < list.length; i++) {\r\n let item = list[i];\r\n let text = item.innerText.toLocaleLowerCase();\r\n let link = item.querySelector(\"a\");\r\n\r\n // Remove previous selection\r\n link.classList.remove(...ACTIVE_CLASSES);\r\n\r\n // Hide selected values\r\n if (values.indexOf(link.getAttribute(VALUE_ATTRIBUTE)) != -1) {\r\n item.style.display = \"none\";\r\n continue;\r\n }\r\n\r\n hasPossibleValues = true;\r\n\r\n // Check search length since we can trigger dropdown with arrow\r\n let isMatched = search.length === 0 || text.indexOf(search) !== -1;\r\n if (this.showAllSuggestions || this.suggestionsThreshold === 0 || isMatched) {\r\n item.style.display = \"list-item\";\r\n found = true;\r\n if (!firstItem && isMatched) {\r\n firstItem = item;\r\n }\r\n } else {\r\n item.style.display = \"none\";\r\n }\r\n }\r\n\r\n // Special case if nothing matches\r\n if (!found) {\r\n this.#dropElement.classList.remove(\"show\");\r\n }\r\n\r\n // Always select first item\r\n if (firstItem) {\r\n if (this.#holderElement.classList.contains(\"is-invalid\")) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n }\r\n firstItem.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n firstItem.parentNode.scrollTop = firstItem.offsetTop - firstItem.parentNode.offsetTop;\r\n } else {\r\n // No item and we don't allow new items => error\r\n if (!this.allowNew && !(search.length === 0 && !hasPossibleValues)) {\r\n this.#holderElement.classList.add(\"is-invalid\");\r\n } else if (this.validationRegex && this.#holderElement.classList.contains(\"is-invalid\")) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * The element create with buildSuggestions\r\n */\r\n #hideSuggestions() {\r\n if (this.#dropElement.classList.contains(\"show\")) {\r\n this.#dropElement.classList.remove(\"show\");\r\n }\r\n if (this.#holderElement.classList.contains(\"is-invalid\")) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n }\r\n this.removeActiveSelection();\r\n }\r\n\r\n /**\r\n * @returns {Number}\r\n */\r\n #getBootstrapVersion() {\r\n let ver = 5;\r\n // If we have jQuery and the tooltip plugin for BS4\r\n if (window.jQuery && $.fn.tooltip != undefined && $.fn.tooltip.Constructor != undefined) {\r\n ver = parseInt($.fn.tooltip.Constructor.VERSION.charAt(0));\r\n }\r\n return ver;\r\n }\r\n\r\n /**\r\n * Find if label is already selected (based on attribute)\r\n * @param {string} text\r\n * @returns {boolean}\r\n */\r\n #isSelected(text) {\r\n const opt = Array.from(this.#selectElement.querySelectorAll(\"option\")).find((el) => el.textContent == text);\r\n if (opt && opt.getAttribute(\"selected\")) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Checks if value matches a configured regex\r\n * @param {string} value\r\n * @returns {boolean}\r\n */\r\n #validateRegex(value) {\r\n const regex = new RegExp(this.validationRegex.trim());\r\n return regex.test(value);\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n getActiveSelection() {\r\n return this.#dropElement.querySelector(\"a.\" + ACTIVE_CLASS);\r\n }\r\n\r\n removeActiveSelection() {\r\n let selection = this.getActiveSelection();\r\n if (selection) {\r\n selection.classList.remove(...ACTIVE_CLASSES);\r\n }\r\n }\r\n\r\n removeAll() {\r\n let items = this.#containerElement.querySelectorAll(\"span\");\r\n items.forEach((item) => {\r\n this.removeLastItem(true);\r\n });\r\n }\r\n\r\n /**\r\n * @param {boolean} noEvents \r\n */\r\n removeLastItem(noEvents) {\r\n if (noEvents) {\r\n this.#fireEvents = false;\r\n }\r\n let items = this.#containerElement.querySelectorAll(\"span\");\r\n if (!items.length) {\r\n return;\r\n }\r\n let lastItem = items[items.length - 1];\r\n this.removeItem(lastItem.getAttribute(VALUE_ATTRIBUTE));\r\n this.#fireEvents = true;\r\n }\r\n\r\n isDisabled() {\r\n return this.#selectElement.hasAttribute(\"disabled\") || this.#selectElement.hasAttribute(\"readonly\");\r\n }\r\n\r\n /**\r\n * @param {string} text\r\n * @param {string} value\r\n * @param {object} data\r\n * @return {boolean}\r\n */\r\n addItem(text, value = null, data = {}) {\r\n if (!value) {\r\n value = text;\r\n }\r\n\r\n if (this.max && this.getSelectedValues().length >= this.max) {\r\n // Replace value for single select\r\n if (this.max === 1) {\r\n this.removeLastItem(true);\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n if (this.validationRegex && !this.#validateRegex(text)) {\r\n this.#holderElement.classList.add(\"is-invalid\");\r\n return false;\r\n }\r\n\r\n const bver = this.#getBootstrapVersion();\r\n let opt = this.#selectElement.querySelector('option[value=\"' + value + '\"]');\r\n if (opt) {\r\n data = opt.dataset;\r\n }\r\n\r\n // create span\r\n let html = text;\r\n let span = document.createElement(\"span\");\r\n let classes = [\"badge\"];\r\n let badgeStyle = this.badgeStyle;\r\n if (data.badgeStyle) {\r\n badgeStyle = data.badgeStyle;\r\n }\r\n if (data.badgeClass) {\r\n classes.push(data.badgeClass);\r\n }\r\n if (bver === 5) {\r\n //https://getbootstrap.com/docs/5.1/components/badge/\r\n classes = [...classes, ...[\"me-2\", \"bg-\" + badgeStyle]];\r\n } else {\r\n // https://getbootstrap.com/docs/4.6/components/badge/\r\n classes = [...classes, ...[\"mr-2\", \"badge-\" + badgeStyle]];\r\n }\r\n span.classList.add(...classes);\r\n span.setAttribute(VALUE_ATTRIBUTE, value);\r\n\r\n if (this.allowClear && !this.isDisabled()) {\r\n const btn =\r\n bver === 5\r\n ? ''\r\n : '';\r\n html = btn + html;\r\n }\r\n\r\n span.innerHTML = html;\r\n this.#containerElement.insertBefore(span, this.#searchInput);\r\n\r\n if (this.allowClear && !this.isDisabled()) {\r\n span.querySelector(\"button\").addEventListener(\"click\", (event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.removeItem(value);\r\n document.activeElement.blur();\r\n });\r\n }\r\n\r\n // we need to create a new option\r\n if (!opt) {\r\n opt = document.createElement(\"option\");\r\n opt.value = value;\r\n opt.innerText = text;\r\n // Pass along data provided\r\n for (const [key, value] of Object.entries(data)) {\r\n opt.dataset[key] = value;\r\n }\r\n this.#selectElement.appendChild(opt);\r\n }\r\n\r\n // update select, we need to set attribute for isSelected\r\n opt.setAttribute(\"selected\", \"selected\");\r\n opt.selected = true;\r\n\r\n // Fire change event\r\n if (this.#fireEvents) {\r\n this.#selectElement.dispatchEvent(new Event(\"change\"), { bubbles: true });\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * @param {string} value\r\n */\r\n removeItem(value) {\r\n let item = this.#containerElement.querySelector(\"span[\" + VALUE_ATTRIBUTE + '=\"' + value + '\"]');\r\n if (!item) {\r\n return;\r\n }\r\n item.remove();\r\n\r\n // update select\r\n let opt = this.#selectElement.querySelector('option[value=\"' + value + '\"]');\r\n if (opt) {\r\n opt.removeAttribute(\"selected\");\r\n opt.selected = false;\r\n\r\n // Fire change event\r\n if (this.#fireEvents) {\r\n this.#selectElement.dispatchEvent(new Event(\"change\"), { bubbles: true });\r\n }\r\n }\r\n\r\n // Make input visible\r\n if (this.#searchInput.style.visibility == \"hidden\" && this.max && this.getSelectedValues().length < this.max) {\r\n this.#searchInput.style.visibility = \"visible\";\r\n }\r\n }\r\n}\r\n\r\nexport default Tags;\r\n", "import { Dropdown } from \"./node_modules/bootstrap.native/src/components/dropdown-native.js\";\r\nimport Tags from \"./tags.js\";\r\n\r\nexport default Tags;"], - "mappings": "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", + "sourcesContent": ["/**\n * Checks if an object is an `Element`.\n *\n * @param {any} element the target object\n * @returns {boolean} the query result\n */\nexport default function isElement(element) {\n return element instanceof Element;\n}\n", "import isElement from './isElement';\n\n/**\n * Utility to check if target is typeof `Element`\n * or find one that matches a selector.\n *\n * @param {Element | string} selector the input selector or target element\n * @param {Element=} parent optional Element to look into\n * @return {Element?} the Element or `querySelector` result\n */\nexport default function querySelector(selector, parent) {\n const lookUp = parent && isElement(parent) ? parent : document;\n // @ts-ignore -- `isElement` is just as good\n return isElement(selector) ? selector : lookUp.querySelector(selector);\n}\n", "import querySelector from './querySelector';\n\n/**\n * Utility to check if target is typeof `Element`\n * or find one that matches a selector.\n *\n * @deprecated\n *\n * @param {Element | string} selector the input selector or target element\n * @param {Element=} parent optional Element to look into\n * @return {Element?} the Element or `querySelector` result\n */\nexport default function queryElement(selector, parent) {\n return querySelector(selector, parent);\n}\n", "/**\n * A global namespace for 'addEventListener' string.\n * @type {string}\n */\nconst addEventListener = 'addEventListener';\nexport default addEventListener;\n", "/**\n * A global namespace for 'removeEventListener' string.\n * @type {string}\n */\nconst removeEventListener = 'removeEventListener';\nexport default removeEventListener;\n", "import addEventListener from '../strings/addEventListener.js';\nimport removeEventListener from '../strings/removeEventListener.js';\n\n/**\n * A global namespace for passive events support.\n * @type {boolean}\n */\nconst supportPassive = (() => {\n let result = false;\n try {\n const opts = Object.defineProperty({}, 'passive', {\n get() {\n result = true;\n return result;\n },\n });\n document[addEventListener]('DOMContentLoaded', function wrap() {\n document[removeEventListener]('DOMContentLoaded', wrap, opts);\n }, opts);\n } catch (e) {\n throw Error('Passive events are not supported');\n }\n\n return result;\n})();\n\nexport default supportPassive;\n", "// general event options\n// not suited for scroll prevention\n// https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection\nimport supportPassive from '../boolean/supportPassive';\n\n/**\n * A global namespace for most scroll event listeners.\n */\nconst passiveHandler = supportPassive ? { passive: true } : false;\n\nexport default passiveHandler;\n", "/**\n * Add class to Element.classList\n *\n * @param {Element} element target\n * @param {string} classNAME to add\n */\nexport default function addClass(element, classNAME) {\n element.classList.add(classNAME);\n}\n", "/**\n * Check class in Element.classList\n *\n * @param {Element} element target\n * @param {string} classNAME to check\n * @return {boolean}\n */\nexport default function hasClass(element, classNAME) {\n return element.classList.contains(classNAME);\n}\n", "/**\n * Remove class from Element.classList\n *\n * @param {Element} element target\n * @param {string} classNAME to remove\n */\nexport default function removeClass(element, classNAME) {\n element.classList.remove(classNAME);\n}\n", "const ariaExpanded = 'aria-expanded';\nexport default ariaExpanded;\n", "const showClass = 'show';\nexport default showClass;\n", "const dataBsToggle = 'data-bs-toggle';\nexport default dataBsToggle;\n", "const dropdownMenuClasses = ['dropdown', 'dropup', 'dropstart', 'dropend'];\nexport default dropdownMenuClasses;\n", "const dropdownMenuClass = 'dropdown-menu';\nexport default dropdownMenuClass;\n", "export default function bootstrapCustomEvent(namespacedEventType, eventProperties) {\n const OriginalCustomEvent = new CustomEvent(namespacedEventType, { cancelable: true });\n\n if (eventProperties instanceof Object) {\n Object.keys(eventProperties).forEach((key) => {\n Object.defineProperty(OriginalCustomEvent, key, {\n value: eventProperties[key],\n });\n });\n }\n return OriginalCustomEvent;\n}\n", "export default function isEmptyAnchor(elem) {\n const parentAnchor = elem.closest('A');\n // anchor href starts with #\n return elem && ((elem.hasAttribute('href') && elem.href.slice(-1) === '#')\n // OR a child of an anchor with href starts with #\n || (parentAnchor && parentAnchor.hasAttribute('href') && parentAnchor.href.slice(-1) === '#'));\n}\n", "export default function setFocus(element) {\n element.focus();\n}\n", "/**\n * The raw value or a given component option.\n *\n * @typedef {string | Element | Function | number | boolean | null} niceValue\n */\n\n/**\n * Utility to normalize component options\n *\n * @param {any} value the input value\n * @return {niceValue} the normalized value\n */\nexport default function normalizeValue(value) {\n if (value === 'true') { // boolean\n return true;\n }\n\n if (value === 'false') { // boolean\n return false;\n }\n\n if (!Number.isNaN(+value)) { // number\n return +value;\n }\n\n if (value === '' || value === 'null') { // null\n return null;\n }\n\n // string / function / Element / object\n return value;\n}\n", "/**\n * Shortcut for `Object.keys()` static method.\n * @param {Record} obj a target object\n * @returns {string[]}\n */\nconst ObjectKeys = (obj) => Object.keys(obj);\nexport default ObjectKeys;\n", "import normalizeValue from './normalizeValue';\nimport ObjectKeys from './ObjectKeys';\n\n/**\n * Utility to normalize component options\n *\n * @param {Element} element target\n * @param {Record} defaultOps component default options\n * @param {Record} inputOps component instance options\n * @param {string=} ns component namespace\n * @return {Record} normalized component options object\n */\nexport default function normalizeOptions(element, defaultOps, inputOps, ns) {\n // @ts-ignore -- usually our `Element` is `HTMLElement` as well\n const data = { ...element.dataset };\n const normalOps = {};\n const dataOps = {};\n\n ObjectKeys(data).forEach((k) => {\n const key = ns && k.includes(ns)\n ? k.replace(ns, '').replace(/[A-Z]/, (match) => match.toLowerCase())\n : k;\n\n dataOps[key] = normalizeValue(data[k]);\n });\n\n ObjectKeys(inputOps).forEach((k) => {\n inputOps[k] = normalizeValue(inputOps[k]);\n });\n\n ObjectKeys(defaultOps).forEach((k) => {\n if (k in inputOps) {\n normalOps[k] = inputOps[k];\n } else if (k in dataOps) {\n normalOps[k] = dataOps[k];\n } else {\n normalOps[k] = defaultOps[k];\n }\n });\n\n return normalOps;\n}\n", "/* Native JavaScript for Bootstrap 5 | Base Component\n----------------------------------------------------- */\n\nimport queryElement from 'shorter-js/src/misc/queryElement.js';\nimport normalizeOptions from 'shorter-js/src/misc/normalizeOptions.js';\n\nexport default class BaseComponent {\n constructor(name, target, defaults, config) {\n const self = this;\n const element = queryElement(target);\n\n if (element[name]) element[name].dispose();\n self.element = element;\n\n if (defaults && Object.keys(defaults).length) {\n self.options = normalizeOptions(element, defaults, (config || {}), 'bs');\n }\n element[name] = self;\n }\n\n dispose(name) {\n const self = this;\n self.element[name] = null;\n Object.keys(self).forEach((prop) => { self[prop] = null; });\n }\n}\n", "/* Native JavaScript for Bootstrap 5 | Dropdown\n----------------------------------------------- */\nimport queryElement from 'shorter-js/src/misc/queryElement.js';\nimport passiveHandler from 'shorter-js/src/misc/passiveHandler.js';\nimport addClass from 'shorter-js/src/class/addClass.js';\nimport hasClass from 'shorter-js/src/class/hasClass.js';\nimport removeClass from 'shorter-js/src/class/removeClass.js';\nimport addEventListener from 'shorter-js/src/strings/addEventListener.js';\nimport removeEventListener from 'shorter-js/src/strings/removeEventListener.js';\n\nimport ariaExpanded from '../strings/ariaExpanded.js';\nimport showClass from '../strings/showClass.js';\nimport dataBsToggle from '../strings/dataBsToggle.js';\nimport dropdownClasses from '../strings/dropdownClasses.js';\nimport dropdownMenuClass from '../strings/dropdownMenuClass.js';\n\nimport bootstrapCustomEvent from '../util/bootstrapCustomEvent.js';\nimport isEmptyAnchor from '../util/isEmptyAnchor.js';\nimport setFocus from '../util/setFocus.js';\nimport BaseComponent from './base-component.js';\n\n// DROPDOWN PRIVATE GC\n// ===================\nconst [dropdownString] = dropdownClasses;\nconst dropdownComponent = 'Dropdown';\nconst dropdownSelector = `[${dataBsToggle}=\"${dropdownString}\"]`;\n\n// DROPDOWN PRIVATE GC\n// ===================\nconst dropupString = dropdownClasses[1];\nconst dropstartString = dropdownClasses[2];\nconst dropendString = dropdownClasses[3];\nconst dropdownMenuEndClass = `${dropdownMenuClass}-end`;\nconst hideMenuClass = ['d-block', 'invisible'];\nconst verticalClass = [dropdownString, dropupString];\nconst horizontalClass = [dropstartString, dropendString];\nconst defaultDropdownOptions = {\n offset: 5, // [number] 5(px)\n display: 'dynamic', // [dynamic|static]\n};\n\n// DROPDOWN CUSTOM EVENTS\n// ========================\nconst showDropdownEvent = bootstrapCustomEvent(`show.bs.${dropdownString}`);\nconst shownDropdownEvent = bootstrapCustomEvent(`shown.bs.${dropdownString}`);\nconst hideDropdownEvent = bootstrapCustomEvent(`hide.bs.${dropdownString}`);\nconst hiddenDropdownEvent = bootstrapCustomEvent(`hidden.bs.${dropdownString}`);\n\n// DROPDOWN PRIVATE METHODS\n// ========================\nfunction styleDropdown(self, show) {\n const {\n element, menu, originalClass, menuEnd, options,\n } = self;\n const { offset } = options;\n const parent = element.parentElement;\n\n // reset menu offset and position\n const resetProps = ['margin', 'top', 'bottom', 'left', 'right'];\n resetProps.forEach((p) => { menu.style[p] = ''; });\n removeClass(parent, 'position-static');\n\n if (!show) {\n const menuEndNow = hasClass(menu, dropdownMenuEndClass);\n parent.className = originalClass.join(' ');\n if (menuEndNow && !menuEnd) removeClass(menu, dropdownMenuEndClass);\n else if (!menuEndNow && menuEnd) addClass(menu, dropdownMenuEndClass);\n return;\n }\n\n // set initial position class\n // take into account .btn-group parent as .dropdown\n let positionClass = dropdownClasses.find((c) => originalClass.includes(c)) || dropdownString;\n\n let dropdownMargin = {\n dropdown: [offset, 0, 0],\n dropup: [0, 0, offset],\n dropstart: [-1, offset, 0],\n dropend: [-1, 0, 0, offset],\n };\n\n const dropdownPosition = {\n dropdown: { top: '100%' },\n dropup: { top: 'auto', bottom: '100%' },\n dropstart: { left: 'auto', right: '100%' },\n dropend: { left: '100%', right: 'auto' },\n menuEnd: { right: 0, left: 'auto' },\n };\n\n // force showing the menu to calculate its size\n hideMenuClass.forEach((c) => addClass(menu, c));\n\n const dropdownRegex = new RegExp(`\\\\b(${dropdownString}|${dropupString}|${dropstartString}|${dropendString})+`);\n const elementDimensions = { w: element.offsetWidth, h: element.offsetHeight };\n const menuDimensions = { w: menu.offsetWidth, h: menu.offsetHeight };\n const HTML = document.documentElement;\n const BD = document.body;\n const windowWidth = (HTML.clientWidth || BD.clientWidth);\n const windowHeight = (HTML.clientHeight || BD.clientHeight);\n const targetBCR = element.getBoundingClientRect();\n // dropdownMenuEnd && [ dropdown | dropup ]\n const leftExceed = targetBCR.left + elementDimensions.w - menuDimensions.w < 0;\n // dropstart\n const leftFullExceed = targetBCR.left - menuDimensions.w < 0;\n // !dropdownMenuEnd && [ dropdown | dropup ]\n const rightExceed = targetBCR.left + menuDimensions.w >= windowWidth;\n // dropend\n const rightFullExceed = targetBCR.left + menuDimensions.w + elementDimensions.w >= windowWidth;\n // dropstart | dropend\n const bottomExceed = targetBCR.top + menuDimensions.h >= windowHeight;\n // dropdown\n const bottomFullExceed = targetBCR.top + menuDimensions.h + elementDimensions.h >= windowHeight;\n // dropup\n const topExceed = targetBCR.top - menuDimensions.h < 0;\n\n // recompute position\n if (horizontalClass.includes(positionClass) && leftFullExceed && rightFullExceed) {\n positionClass = dropdownString;\n }\n if (horizontalClass.includes(positionClass) && bottomExceed) {\n positionClass = dropupString;\n }\n if (positionClass === dropstartString && leftFullExceed && !bottomExceed) {\n positionClass = dropendString;\n }\n if (positionClass === dropendString && rightFullExceed && !bottomExceed) {\n positionClass = dropstartString;\n }\n if (positionClass === dropupString && topExceed && !bottomFullExceed) {\n positionClass = dropdownString;\n }\n if (positionClass === dropdownString && bottomFullExceed && !topExceed) {\n positionClass = dropupString;\n }\n\n // set spacing\n dropdownMargin = dropdownMargin[positionClass];\n menu.style.margin = `${dropdownMargin.map((x) => (x ? `${x}px` : x)).join(' ')}`;\n Object.keys(dropdownPosition[positionClass]).forEach((position) => {\n menu.style[position] = dropdownPosition[positionClass][position];\n });\n\n // update dropdown position class\n if (!hasClass(parent, positionClass)) {\n parent.className = parent.className.replace(dropdownRegex, positionClass);\n }\n\n // update dropdown / dropup to handle parent btn-group element\n // as well as the dropdown-menu-end utility class\n if (verticalClass.includes(positionClass)) {\n if (!menuEnd && rightExceed) addClass(menu, dropdownMenuEndClass);\n else if (menuEnd && leftExceed) removeClass(menu, dropdownMenuEndClass);\n\n if (hasClass(menu, dropdownMenuEndClass)) {\n Object.keys(dropdownPosition.menuEnd).forEach((p) => {\n menu.style[p] = dropdownPosition.menuEnd[p];\n });\n }\n }\n\n // remove util classes from the menu, we have its size\n hideMenuClass.forEach((c) => removeClass(menu, c));\n}\n\nfunction toggleDropdownDismiss(self) {\n const action = self.open ? addEventListener : removeEventListener;\n\n document[action]('click', dropdownDismissHandler);\n document[action]('focus', dropdownDismissHandler);\n document[action]('keydown', dropdownPreventScroll);\n document[action]('keyup', dropdownKeyHandler);\n\n if (self.options.display === 'dynamic') {\n window[action]('scroll', dropdownLayoutHandler, passiveHandler);\n window[action]('resize', dropdownLayoutHandler, passiveHandler);\n }\n}\n\nfunction toggleDropdownHandler(self, add) {\n const action = add ? addEventListener : removeEventListener;\n self.element[action]('click', dropdownClickHandler);\n}\n\nfunction getCurrentOpenDropdown() {\n const currentParent = dropdownClasses.concat('btn-group')\n .map((c) => document.getElementsByClassName(`${c} ${showClass}`))\n .find((x) => x.length);\n\n if (currentParent && currentParent.length) {\n return Array.from(currentParent[0].children).find((x) => x.hasAttribute(dataBsToggle));\n }\n return null;\n}\n\n// DROPDOWN EVENT HANDLERS\n// =======================\nfunction dropdownDismissHandler(e) {\n const { target, type } = e;\n if (!target.closest) return; // some weird FF bug #409\n\n const element = getCurrentOpenDropdown();\n const parent = element && element.parentNode;\n const self = element && element[dropdownComponent];\n const menu = self && self.menu;\n\n const hasData = target.closest(dropdownSelector) !== null;\n const isForm = parent && parent.contains(target)\n && (target.tagName === 'form' || target.closest('form') !== null);\n\n if (type === 'click' && isEmptyAnchor(target)) {\n e.preventDefault();\n }\n if (type === 'focus'\n && (target === element || target === menu || menu.contains(target))) {\n return;\n }\n\n if (isForm || hasData) {\n // smile to ESLint\n } else if (self) {\n self.hide(element);\n }\n}\n\nfunction dropdownClickHandler(e) {\n const element = this;\n const self = element[dropdownComponent];\n self.toggle(element);\n\n if (isEmptyAnchor(e.target)) e.preventDefault();\n}\n\nfunction dropdownPreventScroll(e) {\n if (e.which === 38 || e.which === 40) e.preventDefault();\n}\n\nfunction dropdownKeyHandler({ which }) {\n const element = getCurrentOpenDropdown();\n const self = element[dropdownComponent];\n const { menu, menuItems, open } = self;\n const activeItem = document.activeElement;\n const isSameElement = activeItem === element;\n const isInsideMenu = menu.contains(activeItem);\n const isMenuItem = activeItem.parentNode === menu || activeItem.parentNode.parentNode === menu;\n\n let idx = menuItems.indexOf(activeItem);\n\n if (isMenuItem) { // navigate up | down\n if (isSameElement) {\n idx = 0;\n } else if (which === 38) {\n idx = idx > 1 ? idx - 1 : 0;\n } else if (which === 40) {\n idx = idx < menuItems.length - 1 ? idx + 1 : idx;\n }\n\n if (menuItems[idx]) setFocus(menuItems[idx]);\n }\n\n if (((menuItems.length && isMenuItem) // menu has items\n || (!menuItems.length && (isInsideMenu || isSameElement)) // menu might be a form\n || !isInsideMenu) // or the focused element is not in the menu at all\n && open && which === 27 // menu must be open\n ) {\n self.toggle();\n }\n}\n\nfunction dropdownLayoutHandler() {\n const element = getCurrentOpenDropdown();\n const self = element && element[dropdownComponent];\n\n if (self && self.open) styleDropdown(self, 1);\n}\n\n// DROPDOWN DEFINITION\n// ===================\nexport default class Dropdown extends BaseComponent {\n constructor(target, config) {\n super(dropdownComponent, target, defaultDropdownOptions, config);\n // bind\n const self = this;\n\n // initialization element\n const { element } = self;\n\n // set targets\n const parent = element.parentElement;\n self.menu = queryElement(`.${dropdownMenuClass}`, parent);\n const { menu } = self;\n\n self.originalClass = Array.from(parent.classList);\n\n // set original position\n self.menuEnd = hasClass(menu, dropdownMenuEndClass);\n\n self.menuItems = [];\n\n Array.from(menu.children).forEach((child) => {\n if (child.children.length && (child.children[0].tagName === 'A')) self.menuItems.push(child.children[0]);\n if (child.tagName === 'A') self.menuItems.push(child);\n });\n\n // set initial state to closed\n self.open = false;\n\n // add event listener\n toggleDropdownHandler(self, 1);\n }\n\n // DROPDOWN PUBLIC METHODS\n // =======================\n toggle(related) {\n const self = this;\n const { open } = self;\n\n if (open) self.hide(related);\n else self.show(related);\n }\n\n show(related) {\n const self = this;\n const currentParent = queryElement(dropdownClasses.concat('btn-group').map((c) => `.${c}.${showClass}`).join(','));\n const currentElement = currentParent && queryElement(dropdownSelector, currentParent);\n\n if (currentElement) currentElement[dropdownComponent].hide();\n\n const { element, menu, open } = self;\n const parent = element.parentNode;\n\n // update relatedTarget and dispatch\n showDropdownEvent.relatedTarget = related || null;\n parent.dispatchEvent(showDropdownEvent);\n if (showDropdownEvent.defaultPrevented) return;\n\n // change menu position\n styleDropdown(self, 1);\n\n addClass(menu, showClass);\n addClass(parent, showClass);\n\n element.setAttribute(ariaExpanded, true);\n self.open = !open;\n\n setTimeout(() => {\n setFocus(menu.getElementsByTagName('INPUT')[0] || element); // focus the first input item | element\n toggleDropdownDismiss(self);\n\n shownDropdownEvent.relatedTarget = related || null;\n parent.dispatchEvent(shownDropdownEvent);\n }, 1);\n }\n\n hide(related) {\n const self = this;\n const { element, menu, open } = self;\n const parent = element.parentNode;\n hideDropdownEvent.relatedTarget = related || null;\n parent.dispatchEvent(hideDropdownEvent);\n if (hideDropdownEvent.defaultPrevented) return;\n\n removeClass(menu, showClass);\n removeClass(parent, showClass);\n\n // revert to original position\n styleDropdown(self);\n\n element.setAttribute(ariaExpanded, false);\n self.open = !open;\n\n setFocus(element);\n\n // only re-attach handler if the instance is not disposed\n setTimeout(() => toggleDropdownDismiss(self), 1);\n\n // update relatedTarget and dispatch\n hiddenDropdownEvent.relatedTarget = related || null;\n parent.dispatchEvent(hiddenDropdownEvent);\n }\n\n dispose() {\n const self = this;\n const { element } = self;\n\n if (hasClass(element.parentNode, showClass) && self.open) self.hide();\n\n toggleDropdownHandler(self);\n\n super.dispose(dropdownComponent);\n }\n}\n\nDropdown.init = {\n component: dropdownComponent,\n selector: dropdownSelector,\n constructor: Dropdown,\n};\n", "/**\r\n * Bootstrap 5 (and 4!) tags\r\n *\r\n * Turns your select[multiple] into nice tags lists\r\n *\r\n * Required Bootstrap 5 styles:\r\n * - badge\r\n * - background-color utility\r\n * - margin-end utility\r\n * - forms\r\n * - dropdown\r\n */\r\n\r\nconst ACTIVE_CLASS = \"is-active\";\r\nconst ACTIVE_CLASSES = [\"is-active\", \"bg-primary\", \"text-white\"];\r\nconst VALUE_ATTRIBUTE = \"data-value\";\r\n\r\n// Static map will minify very badly as class prop, so we use an external constant\r\nconst INSTANCE_MAP = new WeakMap();\r\n\r\nclass Tags {\r\n #abortController;\r\n #selectElement;\r\n #holderElement;\r\n #containerElement;\r\n #dropElement;\r\n #searchInput;\r\n #keyboardNavigation;\r\n #fireEvents;\r\n\r\n /**\r\n * @param {HTMLSelectElement} el\r\n * @param {Object} globalOpts\r\n */\r\n constructor(el, globalOpts = {}) {\r\n // Hide the select element and register a tags attr\r\n el.style.display = \"none\";\r\n el.dataset.tags = true;\r\n this.#selectElement = el;\r\n\r\n // Allow 1/0, true/false as strings\r\n const parseBool = (value) => [\"true\", \"false\", \"1\", \"0\", true, false].includes(value) && !!JSON.parse(value);\r\n\r\n // Handle options, using global settings first and data attr override\r\n const opts = { ...globalOpts, ...el.dataset };\r\n this.allowNew = opts.allowNew ? parseBool(opts.allowNew) : false;\r\n this.showAllSuggestions = opts.showAllSuggestions ? parseBool(opts.showAllSuggestions) : false;\r\n this.badgeStyle = opts.badgeStyle || \"primary\";\r\n this.allowClear = opts.allowClear ? parseBool(opts.allowClear) : false;\r\n this.server = opts.server || false;\r\n this.liveServer = opts.liveServer ? parseBool(opts.liveServer) : false;\r\n this.suggestionsThreshold = opts.suggestionsThreshold ? parseInt(opts.suggestionsThreshold) : 1;\r\n this.validationRegex = opts.regex || \"\";\r\n this.separator = opts.separator ? opts.separator.split(\"|\") : [];\r\n this.max = opts.max ? parseInt(opts.max) : null;\r\n this.clearLabel = opts.clearLabel || \"Clear\";\r\n this.searchLabel = opts.searchLabel || \"Type a value\";\r\n if (!el.hasAttribute(\"multiple\")) {\r\n this.max = 1;\r\n }\r\n\r\n this.placeholder = this.#getPlaceholder();\r\n this.#keyboardNavigation = false;\r\n this.#fireEvents = true;\r\n\r\n this.parentForm = el.parentElement;\r\n while (this.parentForm) {\r\n this.parentForm = this.parentForm.parentElement;\r\n if (this.parentForm.nodeName == \"FORM\") {\r\n break;\r\n }\r\n }\r\n this.parentForm.addEventListener(\"reset\", (ev) => {\r\n this.reset();\r\n });\r\n\r\n // Create elements\r\n this.#holderElement = document.createElement(\"div\"); // this is the one holding the fake input and the dropmenu\r\n this.#containerElement = document.createElement(\"div\"); // this is the one for the fake input (labels + input)\r\n this.#dropElement = document.createElement(\"ul\");\r\n this.#searchInput = document.createElement(\"input\");\r\n\r\n this.#holderElement.appendChild(this.#containerElement);\r\n this.#containerElement.appendChild(this.#searchInput);\r\n this.#holderElement.appendChild(this.#dropElement);\r\n // insert after\r\n this.#selectElement.parentNode.insertBefore(this.#holderElement, this.#selectElement.nextSibling);\r\n\r\n // Configure them\r\n this.#configureSearchInput();\r\n this.#configureHolderElement();\r\n this.#configureDropElement();\r\n this.#configureContainerElement();\r\n\r\n if (this.server && !this.liveServer) {\r\n this.#loadFromServer();\r\n } else {\r\n let suggestions = Array.from(this.#selectElement.querySelectorAll(\"option\")).map((option) => {\r\n return {\r\n value: option.getAttribute(\"value\"),\r\n label: option.innerText,\r\n };\r\n });\r\n this.#buildSuggestions(suggestions);\r\n }\r\n }\r\n\r\n /**\r\n * Attach to all elements matched by the selector\r\n * @param {string} selector\r\n * @param {Object} opts\r\n */\r\n static init(selector = \"select[multiple]\", opts = {}) {\r\n let list = document.querySelectorAll(selector);\r\n let el;\r\n for (let i = 0; i < list.length; i++) {\r\n if (!list[i].dataset.tags) {\r\n el = new Tags(list[i], opts);\r\n INSTANCE_MAP.set(list[i], el);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @param {HTMLSelectElement} el\r\n */\r\n static getInstance(el) {\r\n if (INSTANCE_MAP.has(el)) {\r\n return INSTANCE_MAP.get(el);\r\n }\r\n }\r\n\r\n dispose() {\r\n Data.remove(this._element, this.constructor.DATA_KEY);\r\n EventHandler.off(this._element, this.constructor.EVENT_KEY);\r\n }\r\n\r\n /**\r\n * @param {boolean} show\r\n */\r\n #loadFromServer(show = false) {\r\n if (this.#abortController) {\r\n this.#abortController.abort();\r\n }\r\n this.#abortController = new AbortController();\r\n fetch(this.server + \"?query=\" + encodeURIComponent(this.#searchInput.value), { signal: this.#abortController.signal })\r\n .then((r) => r.json())\r\n .then((suggestions) => {\r\n let data = suggestions.data || suggestions;\r\n this.#buildSuggestions(data);\r\n this.#abortController = null;\r\n if (show) {\r\n this.#showSuggestions();\r\n }\r\n })\r\n .catch((e) => {\r\n if (e.name === \"AbortError\") {\r\n return;\r\n }\r\n console.error(e);\r\n });\r\n }\r\n\r\n /**\r\n * @returns {string}\r\n */\r\n #getPlaceholder() {\r\n let firstOption = this.#selectElement.querySelector(\"option\");\r\n if (!firstOption) {\r\n return;\r\n }\r\n if (!firstOption.value) {\r\n let placeholder = firstOption.innerText;\r\n firstOption.remove();\r\n return placeholder;\r\n }\r\n if (this.#selectElement.getAttribute(\"placeholder\")) {\r\n return this.#selectElement.getAttribute(\"placeholder\");\r\n }\r\n if (this.#selectElement.getAttribute(\"data-placeholder\")) {\r\n return this.#selectElement.getAttribute(\"data-placeholder\");\r\n }\r\n return \"\";\r\n }\r\n\r\n #configureDropElement() {\r\n this.#dropElement.classList.add(...[\"dropdown-menu\", \"p-0\"]);\r\n this.#dropElement.style.maxHeight = \"280px\";\r\n this.#dropElement.style.overflowY = \"auto\";\r\n\r\n // If the mouse was outside, entering remove keyboard nav mode\r\n this.#dropElement.addEventListener(\"mouseenter\", (event) => {\r\n this.#keyboardNavigation = false;\r\n });\r\n }\r\n\r\n #configureHolderElement() {\r\n this.#holderElement.classList.add(...[\"form-control\", \"dropdown\"]);\r\n if (this.isDisabled()) {\r\n this.#holderElement.setAttribute(\"readonly\", \"\");\r\n }\r\n if (this.#getBootstrapVersion() === 4) {\r\n // Prevent fixed height due to form-control\r\n this.#holderElement.style.height = \"auto\";\r\n }\r\n }\r\n\r\n #configureContainerElement() {\r\n this.#containerElement.addEventListener(\"click\", (event) => {\r\n if (this.isDisabled()) {\r\n return;\r\n }\r\n if (this.#searchInput.style.visibility != \"hidden\") {\r\n this.#searchInput.focus();\r\n } else if (this.max === 1) {\r\n // Improve single select usage\r\n this.#showSuggestions();\r\n }\r\n });\r\n\r\n // add initial values\r\n let initialValues = this.#selectElement.selectedOptions;\r\n for (let j = 0; j < initialValues.length; j++) {\r\n let initialValue = initialValues[j];\r\n if (!initialValue.value) {\r\n continue;\r\n }\r\n // track initial values for reset\r\n initialValue.dataset.init = 1;\r\n this.addItem(initialValue.innerText, initialValue.value);\r\n }\r\n }\r\n\r\n #configureSearchInput() {\r\n this.#searchInput.type = \"text\";\r\n this.#searchInput.autocomplete = \"off\";\r\n this.#searchInput.style.backgroundColor = \"transparent\";\r\n this.#searchInput.style.border = 0;\r\n this.#searchInput.style.outline = 0;\r\n this.#searchInput.style.maxWidth = \"100%\";\r\n this.#searchInput.ariaLabel = this.searchLabel;\r\n if (this.isDisabled()) {\r\n this.#searchInput.setAttribute(\"disabled\", \"\");\r\n }\r\n this.#adjustWidth();\r\n\r\n this.#searchInput.addEventListener(\"input\", (event) => {\r\n this.#adjustWidth();\r\n if (this.#searchInput.value.length >= this.suggestionsThreshold) {\r\n if (this.liveServer) {\r\n this.#loadFromServer(true);\r\n } else {\r\n this.#showSuggestions();\r\n }\r\n } else {\r\n this.#hideSuggestions();\r\n }\r\n });\r\n this.#searchInput.addEventListener(\"focus\", (event) => {\r\n if (this.#searchInput.value.length >= this.suggestionsThreshold) {\r\n this.#showSuggestions();\r\n }\r\n });\r\n this.#searchInput.addEventListener(\"focusout\", (event) => {\r\n this.#hideSuggestions();\r\n });\r\n // keypress doesn't send arrow keys\r\n this.#searchInput.addEventListener(\"keydown\", (event) => {\r\n // Keycode reference : https://css-tricks.com/snippets/javascript/javascript-keycodes/\r\n let key = event.keyCode || event.key;\r\n if (this.separator.length && this.separator.includes(event.key)) {\r\n event.preventDefault();\r\n let res = this.addItem(this.#searchInput.value, null);\r\n if (res) {\r\n this.#resetSearchInput();\r\n }\r\n return;\r\n }\r\n switch (key) {\r\n case 13:\r\n case \"Enter\":\r\n event.preventDefault();\r\n let selection = this.getActiveSelection();\r\n if (selection) {\r\n selection.click();\r\n } else {\r\n // We use what is typed if not selected and not empty\r\n if (this.allowNew && !this.#isSelected(this.#searchInput.value) && this.#searchInput.value) {\r\n let res = this.addItem(this.#searchInput.value, null);\r\n if (res) {\r\n this.#resetSearchInput();\r\n }\r\n }\r\n }\r\n break;\r\n case 38:\r\n case \"ArrowUp\":\r\n event.preventDefault();\r\n this.#keyboardNavigation = true;\r\n let newSelection = this.#moveSelectionUp();\r\n // If we use arrow up without input and there is no new selection, hide suggestions\r\n if (this.#searchInput.value.length == 0 && this.#dropElement.classList.contains(\"show\") && !newSelection) {\r\n this.#hideSuggestions();\r\n }\r\n break;\r\n case 40:\r\n case \"ArrowDown\":\r\n event.preventDefault();\r\n this.#keyboardNavigation = true;\r\n this.#moveSelectionDown();\r\n // If we use arrow down without input, show suggestions\r\n if (this.#searchInput.value.length == 0 && !this.#dropElement.classList.contains(\"show\")) {\r\n this.#showSuggestions();\r\n }\r\n break;\r\n case 8:\r\n case \"Backspace\":\r\n if (this.#searchInput.value.length == 0) {\r\n this.removeLastItem();\r\n this.#adjustWidth();\r\n this.#hideSuggestions();\r\n }\r\n break;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n #moveSelectionUp() {\r\n let active = this.getActiveSelection();\r\n if (active) {\r\n let prev = active.parentNode;\r\n do {\r\n prev = prev.previousSibling;\r\n } while (prev && prev.style.display == \"none\");\r\n if (!prev) {\r\n return null;\r\n }\r\n active.classList.remove(...ACTIVE_CLASSES);\r\n prev.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n // Don't use scrollIntoView as it scrolls the whole window\r\n prev.parentNode.scrollTop = prev.offsetTop - prev.parentNode.offsetTop;\r\n return prev;\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n #moveSelectionDown() {\r\n let active = this.getActiveSelection();\r\n let next = null;\r\n if (active) {\r\n next = active.parentNode;\r\n do {\r\n next = next.nextSibling;\r\n } while (next && next.style.display == \"none\");\r\n if (!next) {\r\n return null;\r\n }\r\n active.classList.remove(...ACTIVE_CLASSES);\r\n next.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n // This is the equivalent of scrollIntoView(false) but only for parent node\r\n if (next.offsetTop > next.parentNode.offsetHeight - next.offsetHeight) {\r\n next.parentNode.scrollTop += next.offsetHeight;\r\n }\r\n return next;\r\n }\r\n return next;\r\n }\r\n\r\n /**\r\n * Adjust the field to fit its content\r\n */\r\n #adjustWidth() {\r\n if (this.#searchInput.value) {\r\n this.#searchInput.size = this.#searchInput.value.length + 1;\r\n } else {\r\n // Show the placeholder only if empty\r\n if (this.getSelectedValues().length) {\r\n this.#searchInput.placeholder = \"\";\r\n this.#searchInput.size = 1;\r\n } else {\r\n this.#searchInput.size = this.placeholder.length;\r\n this.#searchInput.placeholder = this.placeholder;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Add suggestions to the drop element\r\n * @param {array}\r\n */\r\n #buildSuggestions(suggestions = null) {\r\n while (this.#dropElement.lastChild) {\r\n this.#dropElement.removeChild(this.#dropElement.lastChild);\r\n }\r\n for (let i = 0; i < suggestions.length; i++) {\r\n let suggestion = suggestions[i];\r\n if (!suggestion.value) {\r\n continue;\r\n }\r\n let newChild = document.createElement(\"li\");\r\n let newChildLink = document.createElement(\"a\");\r\n newChild.append(newChildLink);\r\n newChildLink.classList.add(\"dropdown-item\");\r\n newChildLink.setAttribute(VALUE_ATTRIBUTE, suggestion.value);\r\n newChildLink.setAttribute(\"href\", \"#\");\r\n newChildLink.innerText = suggestion.label;\r\n if (suggestion.data) {\r\n for (const [key, value] of Object.entries(suggestion.data)) {\r\n newChildLink.dataset[key] = value;\r\n }\r\n }\r\n this.#dropElement.appendChild(newChild);\r\n\r\n // Hover sets active item\r\n newChildLink.addEventListener(\"mouseenter\", (event) => {\r\n // Don't trigger enter if using arrows\r\n if (this.#keyboardNavigation) {\r\n return;\r\n }\r\n this.removeActiveSelection();\r\n newChild.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n });\r\n // Moving the mouse means no longer using keyboard\r\n newChildLink.addEventListener(\"mousemove\", (event) => {\r\n this.#keyboardNavigation = false;\r\n });\r\n\r\n newChildLink.addEventListener(\"mousedown\", (event) => {\r\n // Otherwise searchInput would lose focus and close the menu\r\n event.preventDefault();\r\n });\r\n newChildLink.addEventListener(\"click\", (event) => {\r\n event.preventDefault();\r\n this.addItem(newChildLink.innerText, newChildLink.getAttribute(VALUE_ATTRIBUTE), newChildLink.dataset);\r\n this.#resetSearchInput();\r\n });\r\n }\r\n }\r\n\r\n reset() {\r\n this.removeAll();\r\n\r\n // Reset doesn't fire change event\r\n this.#fireEvents = false;\r\n let initialValues = this.#selectElement.querySelectorAll(\"option[data-init]\");\r\n for (let j = 0; j < initialValues.length; j++) {\r\n let initialValue = initialValues[j];\r\n this.addItem(initialValue.innerText, initialValue.value);\r\n }\r\n this.#adjustWidth();\r\n this.#fireEvents = true;\r\n }\r\n\r\n #resetSearchInput() {\r\n this.#searchInput.value = \"\";\r\n this.#adjustWidth();\r\n this.#hideSuggestions();\r\n\r\n // We use visibility instead of display to keep layout intact\r\n if (this.max && this.getSelectedValues().length === this.max) {\r\n this.#searchInput.style.visibility = \"hidden\";\r\n } else if (this.#searchInput.style.visibility == \"hidden\") {\r\n this.#searchInput.style.visibility = \"visible\";\r\n }\r\n }\r\n\r\n /**\r\n * @returns {array}\r\n */\r\n getSelectedValues() {\r\n let selected = this.#selectElement.selectedOptions;\r\n return Array.from(selected).map((el) => el.value);\r\n }\r\n\r\n /**\r\n * The element create with buildSuggestions\r\n */\r\n #showSuggestions() {\r\n if (!this.#dropElement.classList.contains(\"show\")) {\r\n this.#dropElement.classList.add(\"show\");\r\n }\r\n\r\n // Position next to search input\r\n this.#dropElement.style.left = this.#searchInput.offsetLeft + \"px\";\r\n\r\n // Get search value\r\n let search = this.#searchInput.value.toLocaleLowerCase();\r\n\r\n // Get current values\r\n let values = this.getSelectedValues();\r\n\r\n // Filter the list according to search string\r\n let list = this.#dropElement.querySelectorAll(\"li\");\r\n let found = false;\r\n let firstItem = null;\r\n let hasPossibleValues = false;\r\n for (let i = 0; i < list.length; i++) {\r\n let item = list[i];\r\n let text = item.innerText.toLocaleLowerCase();\r\n let link = item.querySelector(\"a\");\r\n\r\n // Remove previous selection\r\n link.classList.remove(...ACTIVE_CLASSES);\r\n\r\n // Hide selected values\r\n if (values.indexOf(link.getAttribute(VALUE_ATTRIBUTE)) != -1) {\r\n item.style.display = \"none\";\r\n continue;\r\n }\r\n\r\n hasPossibleValues = true;\r\n\r\n // Check search length since we can trigger dropdown with arrow\r\n let isMatched = search.length === 0 || text.indexOf(search) !== -1;\r\n if (this.showAllSuggestions || this.suggestionsThreshold === 0 || isMatched) {\r\n item.style.display = \"list-item\";\r\n found = true;\r\n if (!firstItem && isMatched) {\r\n firstItem = item;\r\n }\r\n } else {\r\n item.style.display = \"none\";\r\n }\r\n }\r\n\r\n // Special case if nothing matches\r\n if (!found) {\r\n this.#dropElement.classList.remove(\"show\");\r\n }\r\n\r\n // Always select first item\r\n if (firstItem) {\r\n if (this.#holderElement.classList.contains(\"is-invalid\")) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n }\r\n firstItem.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n firstItem.parentNode.scrollTop = firstItem.offsetTop - firstItem.parentNode.offsetTop;\r\n } else {\r\n // No item and we don't allow new items => error\r\n if (!this.allowNew && !(search.length === 0 && !hasPossibleValues)) {\r\n this.#holderElement.classList.add(\"is-invalid\");\r\n } else if (this.validationRegex && this.#holderElement.classList.contains(\"is-invalid\")) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * The element create with buildSuggestions\r\n */\r\n #hideSuggestions() {\r\n if (this.#dropElement.classList.contains(\"show\")) {\r\n this.#dropElement.classList.remove(\"show\");\r\n }\r\n if (this.#holderElement.classList.contains(\"is-invalid\")) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n }\r\n this.removeActiveSelection();\r\n }\r\n\r\n /**\r\n * @returns {Number}\r\n */\r\n #getBootstrapVersion() {\r\n let ver = 5;\r\n // If we have jQuery and the tooltip plugin for BS4\r\n if (window.jQuery && $.fn.tooltip != undefined && $.fn.tooltip.Constructor != undefined) {\r\n ver = parseInt($.fn.tooltip.Constructor.VERSION.charAt(0));\r\n }\r\n return ver;\r\n }\r\n\r\n /**\r\n * Find if label is already selected (based on attribute)\r\n * @param {string} text\r\n * @returns {boolean}\r\n */\r\n #isSelected(text) {\r\n const opt = Array.from(this.#selectElement.querySelectorAll(\"option\")).find((el) => el.textContent == text);\r\n if (opt && opt.getAttribute(\"selected\")) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Checks if value matches a configured regex\r\n * @param {string} value\r\n * @returns {boolean}\r\n */\r\n #validateRegex(value) {\r\n const regex = new RegExp(this.validationRegex.trim());\r\n return regex.test(value);\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n getActiveSelection() {\r\n return this.#dropElement.querySelector(\"a.\" + ACTIVE_CLASS);\r\n }\r\n\r\n removeActiveSelection() {\r\n let selection = this.getActiveSelection();\r\n if (selection) {\r\n selection.classList.remove(...ACTIVE_CLASSES);\r\n }\r\n }\r\n\r\n removeAll() {\r\n let items = this.#containerElement.querySelectorAll(\"span\");\r\n items.forEach((item) => {\r\n this.removeLastItem(true);\r\n });\r\n }\r\n\r\n /**\r\n * @param {boolean} noEvents\r\n */\r\n removeLastItem(noEvents) {\r\n if (noEvents) {\r\n this.#fireEvents = false;\r\n }\r\n let items = this.#containerElement.querySelectorAll(\"span\");\r\n if (!items.length) {\r\n return;\r\n }\r\n let lastItem = items[items.length - 1];\r\n this.removeItem(lastItem.getAttribute(VALUE_ATTRIBUTE));\r\n this.#fireEvents = true;\r\n }\r\n\r\n isDisabled() {\r\n return this.#selectElement.hasAttribute(\"disabled\") || this.#selectElement.hasAttribute(\"readonly\");\r\n }\r\n\r\n /**\r\n * @param {string} text\r\n * @param {string} value\r\n * @param {object} data\r\n * @return {boolean}\r\n */\r\n addItem(text, value = null, data = {}) {\r\n if (!value) {\r\n value = text;\r\n }\r\n\r\n if (this.max && this.getSelectedValues().length >= this.max) {\r\n // Replace value for single select\r\n if (this.max === 1) {\r\n this.removeLastItem(true);\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n if (this.validationRegex && !this.#validateRegex(text)) {\r\n this.#holderElement.classList.add(\"is-invalid\");\r\n return false;\r\n }\r\n\r\n const bver = this.#getBootstrapVersion();\r\n let opt = this.#selectElement.querySelector('option[value=\"' + value + '\"]');\r\n if (opt) {\r\n data = opt.dataset;\r\n }\r\n\r\n // create span\r\n let html = text;\r\n let span = document.createElement(\"span\");\r\n let classes = [\"badge\"];\r\n let badgeStyle = this.badgeStyle;\r\n if (data.badgeStyle) {\r\n badgeStyle = data.badgeStyle;\r\n }\r\n if (data.badgeClass) {\r\n classes.push(data.badgeClass);\r\n }\r\n if (bver === 5) {\r\n //https://getbootstrap.com/docs/5.1/components/badge/\r\n classes = [...classes, ...[\"me-2\", \"bg-\" + badgeStyle]];\r\n } else {\r\n // https://getbootstrap.com/docs/4.6/components/badge/\r\n classes = [...classes, ...[\"mr-2\", \"badge-\" + badgeStyle]];\r\n }\r\n span.classList.add(...classes);\r\n span.setAttribute(VALUE_ATTRIBUTE, value);\r\n\r\n if (this.allowClear && !this.isDisabled()) {\r\n const btn =\r\n bver === 5\r\n ? ''\r\n : '';\r\n html = btn + html;\r\n }\r\n\r\n span.innerHTML = html;\r\n this.#containerElement.insertBefore(span, this.#searchInput);\r\n\r\n if (this.allowClear && !this.isDisabled()) {\r\n span.querySelector(\"button\").addEventListener(\"click\", (event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.removeItem(value);\r\n document.activeElement.blur();\r\n });\r\n }\r\n\r\n // we need to create a new option\r\n if (!opt) {\r\n opt = document.createElement(\"option\");\r\n opt.value = value;\r\n opt.innerText = text;\r\n // Pass along data provided\r\n for (const [key, value] of Object.entries(data)) {\r\n opt.dataset[key] = value;\r\n }\r\n this.#selectElement.appendChild(opt);\r\n }\r\n\r\n // update select, we need to set attribute for isSelected\r\n opt.setAttribute(\"selected\", \"selected\");\r\n opt.selected = true;\r\n\r\n // Fire change event\r\n if (this.#fireEvents) {\r\n this.#selectElement.dispatchEvent(new Event(\"change\"), { bubbles: true });\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * @param {string} value\r\n */\r\n removeItem(value) {\r\n let item = this.#containerElement.querySelector(\"span[\" + VALUE_ATTRIBUTE + '=\"' + value + '\"]');\r\n if (!item) {\r\n return;\r\n }\r\n item.remove();\r\n\r\n // update select\r\n let opt = this.#selectElement.querySelector('option[value=\"' + value + '\"]');\r\n if (opt) {\r\n opt.removeAttribute(\"selected\");\r\n opt.selected = false;\r\n\r\n // Fire change event\r\n if (this.#fireEvents) {\r\n this.#selectElement.dispatchEvent(new Event(\"change\"), { bubbles: true });\r\n }\r\n }\r\n\r\n // Make input visible\r\n if (this.#searchInput.style.visibility == \"hidden\" && this.max && this.getSelectedValues().length < this.max) {\r\n this.#searchInput.style.visibility = \"visible\";\r\n }\r\n }\r\n}\r\n\r\nexport default Tags;\r\n", "import { Dropdown } from \"./node_modules/bootstrap.native/src/components/dropdown-native.js\";\r\nimport Tags from \"./tags.js\";\r\n\r\nexport default Tags;"], + "mappings": "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", "names": [] } diff --git a/tags.min.js b/tags.min.js index 3640355..7aafc50 100644 --- a/tags.min.js +++ b/tags.min.js @@ -1,2 +1,2 @@ -var v="is-active",h=["is-active","bg-primary","text-white"],d="data-value",p=new WeakMap,f=class{#n;#t;#i;#l;#s;#e;#a;#r;constructor(t,e={}){t.style.display="none",t.dataset.tags=!0,this.#t=t;let s=i=>["true","false","1","0",!0,!1].includes(i)&&!!JSON.parse(i),l={...e,...t.dataset};for(this.allowNew=l.allowNew?s(l.allowNew):!1,this.showAllSuggestions=l.showAllSuggestions?s(l.showAllSuggestions):!1,this.badgeStyle=l.badgeStyle||"primary",this.allowClear=l.allowClear?s(l.allowClear):!1,this.server=l.server||!1,this.liveServer=l.liveServer?s(l.liveServer):!1,this.suggestionsThreshold=l.suggestionsThreshold?parseInt(l.suggestionsThreshold):1,this.validationRegex=l.regex||"",this.separator=l.separator?l.separator.split("|"):[],this.max=l.max?parseInt(l.max):null,this.clearLabel=l.clearLabel||"Clear",this.searchLabel=l.searchLabel||"Type a value",t.hasAttribute("multiple")||(this.max=1),this.placeholder=this.#v(),this.#a=!1,this.#r=!0,this.parentForm=t.parentElement;this.parentForm&&(this.parentForm=this.parentForm.parentElement,this.parentForm.nodeName!="FORM"););if(this.parentForm.addEventListener("reset",i=>{this.reset()}),this.#i=document.createElement("div"),this.#l=document.createElement("div"),this.#s=document.createElement("ul"),this.#e=document.createElement("input"),this.#i.appendChild(this.#l),this.#l.appendChild(this.#e),this.#i.appendChild(this.#s),this.#t.parentNode.insertBefore(this.#i,this.#t.nextSibling),this.#y(),this.#g(),this.#m(),this.#b(),this.server&&!this.liveServer)this.#u();else{let i=Array.from(this.#t.querySelectorAll("option")).map(r=>({value:r.getAttribute("value"),label:r.innerText}));this.#f(i)}}static init(t="select[multiple]",e={}){let s=document.querySelectorAll(t),l;for(let i=0;i{this.#a=!1})}#g(){this.#i.classList.add("form-control","dropdown"),this.isDisabled()&&this.#i.setAttribute("readonly",""),this.#p()===4&&(this.#i.style.height="auto")}#b(){this.#l.addEventListener("click",e=>{this.isDisabled()||(this.#e.style.visibility!="hidden"?this.#e.focus():this.max===1&&this.#h())});let t=this.#t.querySelectorAll("option[selected]");for(let e=0;e{this.#o(),this.#e.value.length>=this.suggestionsThreshold?this.liveServer?this.#u(!0):this.#h():this.#d()}),this.#e.addEventListener("focus",t=>{this.#e.value.length>=this.suggestionsThreshold&&this.#h()}),this.#e.addEventListener("focusout",t=>{this.#d()}),this.#e.addEventListener("keydown",t=>{let e=t.keyCode||t.key;if(this.separator.length&&this.separator.includes(t.key)){t.preventDefault(),this.addItem(this.#e.value,null)&&this.#c();return}switch(e){case 13:case"Enter":t.preventDefault();let s=this.getActiveSelection();s?s.click():this.allowNew&&!this.#A(this.#e.value)&&this.#e.value&&this.addItem(this.#e.value,null)&&this.#c();break;case 38:case"ArrowUp":t.preventDefault(),this.#a=!0;let l=this.#S();this.#e.value.length==0&&this.#s.classList.contains("show")&&!l&&this.#d();break;case 40:case"ArrowDown":t.preventDefault(),this.#a=!0,this.#L(),this.#e.value.length==0&&!this.#s.classList.contains("show")&&this.#h();break;case 8:case"Backspace":this.#e.value.length==0&&(this.removeLastItem(),this.#o(),this.#d());break}})}#S(){let t=this.getActiveSelection();if(t){let e=t.parentNode;do e=e.previousSibling;while(e&&e.style.display=="none");return e?(t.classList.remove(...h),e.querySelector("a").classList.add(...h),e.parentNode.scrollTop=e.offsetTop-e.parentNode.offsetTop,e):null}return null}#L(){let t=this.getActiveSelection(),e=null;if(t){e=t.parentNode;do e=e.nextSibling;while(e&&e.style.display=="none");return e?(t.classList.remove(...h),e.querySelector("a").classList.add(...h),e.offsetTop>e.parentNode.offsetHeight-e.offsetHeight&&(e.parentNode.scrollTop+=e.offsetHeight),e):null}return e}#o(){this.#e.value?this.#e.size=this.#e.value.length+1:this.getSelectedValues().length?(this.#e.placeholder="",this.#e.size=1):(this.#e.size=this.placeholder.length,this.#e.placeholder=this.placeholder)}#f(t=null){for(;this.#s.lastChild;)this.#s.removeChild(this.#s.lastChild);for(let e=0;e{this.#a||(this.removeActiveSelection(),l.querySelector("a").classList.add(...h))}),i.addEventListener("mousemove",r=>{this.#a=!1}),i.addEventListener("mousedown",r=>{r.preventDefault()}),i.addEventListener("click",r=>{r.preventDefault(),this.addItem(i.innerText,i.getAttribute(d),i.dataset),this.#c()})}}reset(){this.removeAll(),this.#r=!1;let t=this.#t.querySelectorAll("option[data-init]");for(let e=0;ee.value)}getSelectedOptions(){return this.#t.querySelectorAll("option[selected]")}#h(){this.#s.classList.contains("show")||this.#s.classList.add("show"),this.#s.style.left=this.#e.offsetLeft+"px";let t=this.#e.value.toLocaleLowerCase(),e=this.getSelectedValues(),s=this.#s.querySelectorAll("li"),l=!1,i=null,r=!1;for(let n=0;ns.textContent==t);return!!(e&&e.getAttribute("selected"))}#w(t){return new RegExp(this.validationRegex.trim()).test(t)}getActiveSelection(){return this.#s.querySelector("a."+v)}removeActiveSelection(){let t=this.getActiveSelection();t&&t.classList.remove(...h)}removeAll(){this.#l.querySelectorAll("span").forEach(e=>{this.removeLastItem(!0)})}removeLastItem(t){t&&(this.#r=!1);let e=this.#l.querySelectorAll("span");if(!e.length)return;let s=e[e.length-1];this.removeItem(s.getAttribute(d)),this.#r=!0}isDisabled(){return this.#t.hasAttribute("disabled")||this.#t.hasAttribute("readonly")}addItem(t,e=null,s={}){if(e||(e=t),this.max&&this.getSelectedValues().length>=this.max)if(this.max===1)this.removeLastItem(!0);else return!1;if(this.validationRegex&&!this.#w(t))return this.#i.classList.add("is-invalid"),!1;let l=this.#p(),i=this.#t.querySelector('option[value="'+e+'"]');i&&(s=i.dataset);let r=t,n=document.createElement("span"),a=["badge"],c=this.badgeStyle;if(s.badgeStyle&&(c=s.badgeStyle),s.badgeClass&&a.push(s.badgeClass),l===5?a=[...a,"me-2","bg-"+c]:a=[...a,"mr-2","badge-"+c],n.classList.add(...a),n.setAttribute(d,e),this.allowClear&&!this.isDisabled()&&(r=(l===5?'':'')+r),n.innerHTML=r,this.#l.insertBefore(n,this.#e),this.allowClear&&!this.isDisabled()&&n.querySelector("button").addEventListener("click",o=>{o.preventDefault(),o.stopPropagation(),this.removeItem(e),document.activeElement.blur()}),!i){i=document.createElement("option"),i.value=e,i.innerText=t;for(let[o,u]of Object.entries(s))i.dataset[o]=u;this.#t.appendChild(i)}return i.setAttribute("selected","selected"),i.selected=!0,this.#r&&this.#t.dispatchEvent(new Event("change"),{bubbles:!0}),!0}removeItem(t){let e=this.#l.querySelector("span["+d+'="'+t+'"]');if(!e)return;e.remove();let s=this.#t.querySelector('option[value="'+t+'"]');s&&(s.removeAttribute("selected"),s.selected=!1,this.#r&&this.#t.dispatchEvent(new Event("change"),{bubbles:!0})),this.#e.style.visibility=="hidden"&&this.max&&this.getSelectedValues().length["true","false","1","0",!0,!1].includes(i)&&!!JSON.parse(i),l={...e,...t.dataset};for(this.allowNew=l.allowNew?s(l.allowNew):!1,this.showAllSuggestions=l.showAllSuggestions?s(l.showAllSuggestions):!1,this.badgeStyle=l.badgeStyle||"primary",this.allowClear=l.allowClear?s(l.allowClear):!1,this.server=l.server||!1,this.liveServer=l.liveServer?s(l.liveServer):!1,this.suggestionsThreshold=l.suggestionsThreshold?parseInt(l.suggestionsThreshold):1,this.validationRegex=l.regex||"",this.separator=l.separator?l.separator.split("|"):[],this.max=l.max?parseInt(l.max):null,this.clearLabel=l.clearLabel||"Clear",this.searchLabel=l.searchLabel||"Type a value",t.hasAttribute("multiple")||(this.max=1),this.placeholder=this.#p(),this.#a=!1,this.#r=!0,this.parentForm=t.parentElement;this.parentForm&&(this.parentForm=this.parentForm.parentElement,this.parentForm.nodeName!="FORM"););if(this.parentForm.addEventListener("reset",i=>{this.reset()}),this.#i=document.createElement("div"),this.#l=document.createElement("div"),this.#s=document.createElement("ul"),this.#e=document.createElement("input"),this.#i.appendChild(this.#l),this.#l.appendChild(this.#e),this.#i.appendChild(this.#s),this.#t.parentNode.insertBefore(this.#i,this.#t.nextSibling),this.#y(),this.#g(),this.#m(),this.#b(),this.server&&!this.liveServer)this.#u();else{let i=Array.from(this.#t.querySelectorAll("option")).map(r=>({value:r.getAttribute("value"),label:r.innerText}));this.#f(i)}}static init(t="select[multiple]",e={}){let s=document.querySelectorAll(t),l;for(let i=0;i{this.#a=!1})}#g(){this.#i.classList.add("form-control","dropdown"),this.isDisabled()&&this.#i.setAttribute("readonly",""),this.#v()===4&&(this.#i.style.height="auto")}#b(){this.#l.addEventListener("click",e=>{this.isDisabled()||(this.#e.style.visibility!="hidden"?this.#e.focus():this.max===1&&this.#h())});let t=this.#t.selectedOptions;for(let e=0;e{this.#o(),this.#e.value.length>=this.suggestionsThreshold?this.liveServer?this.#u(!0):this.#h():this.#d()}),this.#e.addEventListener("focus",t=>{this.#e.value.length>=this.suggestionsThreshold&&this.#h()}),this.#e.addEventListener("focusout",t=>{this.#d()}),this.#e.addEventListener("keydown",t=>{let e=t.keyCode||t.key;if(this.separator.length&&this.separator.includes(t.key)){t.preventDefault(),this.addItem(this.#e.value,null)&&this.#c();return}switch(e){case 13:case"Enter":t.preventDefault();let s=this.getActiveSelection();s?s.click():this.allowNew&&!this.#w(this.#e.value)&&this.#e.value&&this.addItem(this.#e.value,null)&&this.#c();break;case 38:case"ArrowUp":t.preventDefault(),this.#a=!0;let l=this.#S();this.#e.value.length==0&&this.#s.classList.contains("show")&&!l&&this.#d();break;case 40:case"ArrowDown":t.preventDefault(),this.#a=!0,this.#L(),this.#e.value.length==0&&!this.#s.classList.contains("show")&&this.#h();break;case 8:case"Backspace":this.#e.value.length==0&&(this.removeLastItem(),this.#o(),this.#d());break}})}#S(){let t=this.getActiveSelection();if(t){let e=t.parentNode;do e=e.previousSibling;while(e&&e.style.display=="none");return e?(t.classList.remove(...h),e.querySelector("a").classList.add(...h),e.parentNode.scrollTop=e.offsetTop-e.parentNode.offsetTop,e):null}return null}#L(){let t=this.getActiveSelection(),e=null;if(t){e=t.parentNode;do e=e.nextSibling;while(e&&e.style.display=="none");return e?(t.classList.remove(...h),e.querySelector("a").classList.add(...h),e.offsetTop>e.parentNode.offsetHeight-e.offsetHeight&&(e.parentNode.scrollTop+=e.offsetHeight),e):null}return e}#o(){this.#e.value?this.#e.size=this.#e.value.length+1:this.getSelectedValues().length?(this.#e.placeholder="",this.#e.size=1):(this.#e.size=this.placeholder.length,this.#e.placeholder=this.placeholder)}#f(t=null){for(;this.#s.lastChild;)this.#s.removeChild(this.#s.lastChild);for(let e=0;e{this.#a||(this.removeActiveSelection(),l.querySelector("a").classList.add(...h))}),i.addEventListener("mousemove",r=>{this.#a=!1}),i.addEventListener("mousedown",r=>{r.preventDefault()}),i.addEventListener("click",r=>{r.preventDefault(),this.addItem(i.innerText,i.getAttribute(d),i.dataset),this.#c()})}}reset(){this.removeAll(),this.#r=!1;let t=this.#t.querySelectorAll("option[data-init]");for(let e=0;ee.value)}#h(){this.#s.classList.contains("show")||this.#s.classList.add("show"),this.#s.style.left=this.#e.offsetLeft+"px";let t=this.#e.value.toLocaleLowerCase(),e=this.getSelectedValues(),s=this.#s.querySelectorAll("li"),l=!1,i=null,r=!1;for(let n=0;ns.textContent==t);return!!(e&&e.getAttribute("selected"))}#A(t){return new RegExp(this.validationRegex.trim()).test(t)}getActiveSelection(){return this.#s.querySelector("a."+p)}removeActiveSelection(){let t=this.getActiveSelection();t&&t.classList.remove(...h)}removeAll(){this.#l.querySelectorAll("span").forEach(e=>{this.removeLastItem(!0)})}removeLastItem(t){t&&(this.#r=!1);let e=this.#l.querySelectorAll("span");if(!e.length)return;let s=e[e.length-1];this.removeItem(s.getAttribute(d)),this.#r=!0}isDisabled(){return this.#t.hasAttribute("disabled")||this.#t.hasAttribute("readonly")}addItem(t,e=null,s={}){if(e||(e=t),this.max&&this.getSelectedValues().length>=this.max)if(this.max===1)this.removeLastItem(!0);else return!1;if(this.validationRegex&&!this.#A(t))return this.#i.classList.add("is-invalid"),!1;let l=this.#v(),i=this.#t.querySelector('option[value="'+e+'"]');i&&(s=i.dataset);let r=t,n=document.createElement("span"),a=["badge"],c=this.badgeStyle;if(s.badgeStyle&&(c=s.badgeStyle),s.badgeClass&&a.push(s.badgeClass),l===5?a=[...a,"me-2","bg-"+c]:a=[...a,"mr-2","badge-"+c],n.classList.add(...a),n.setAttribute(d,e),this.allowClear&&!this.isDisabled()&&(r=(l===5?'':'')+r),n.innerHTML=r,this.#l.insertBefore(n,this.#e),this.allowClear&&!this.isDisabled()&&n.querySelector("button").addEventListener("click",o=>{o.preventDefault(),o.stopPropagation(),this.removeItem(e),document.activeElement.blur()}),!i){i=document.createElement("option"),i.value=e,i.innerText=t;for(let[o,u]of Object.entries(s))i.dataset[o]=u;this.#t.appendChild(i)}return i.setAttribute("selected","selected"),i.selected=!0,this.#r&&this.#t.dispatchEvent(new Event("change"),{bubbles:!0}),!0}removeItem(t){let e=this.#l.querySelector("span["+d+'="'+t+'"]');if(!e)return;e.remove();let s=this.#t.querySelector('option[value="'+t+'"]');s&&(s.removeAttribute("selected"),s.selected=!1,this.#r&&this.#t.dispatchEvent(new Event("change"),{bubbles:!0})),this.#e.style.visibility=="hidden"&&this.max&&this.getSelectedValues().length [\"true\", \"false\", \"1\", \"0\", true, false].includes(value) && !!JSON.parse(value);\r\n\r\n // Handle options, using global settings first and data attr override\r\n const opts = { ...globalOpts, ...el.dataset };\r\n this.allowNew = opts.allowNew ? parseBool(opts.allowNew) : false;\r\n this.showAllSuggestions = opts.showAllSuggestions ? parseBool(opts.showAllSuggestions) : false;\r\n this.badgeStyle = opts.badgeStyle || \"primary\";\r\n this.allowClear = opts.allowClear ? parseBool(opts.allowClear) : false;\r\n this.server = opts.server || false;\r\n this.liveServer = opts.liveServer ? parseBool(opts.liveServer) : false;\r\n this.suggestionsThreshold = opts.suggestionsThreshold ? parseInt(opts.suggestionsThreshold) : 1;\r\n this.validationRegex = opts.regex || \"\";\r\n this.separator = opts.separator ? opts.separator.split(\"|\") : [];\r\n this.max = opts.max ? parseInt(opts.max) : null;\r\n this.clearLabel = opts.clearLabel || \"Clear\";\r\n this.searchLabel = opts.searchLabel || \"Type a value\";\r\n if (!el.hasAttribute(\"multiple\")) {\r\n this.max = 1;\r\n }\r\n\r\n this.placeholder = this.#getPlaceholder();\r\n this.#keyboardNavigation = false;\r\n this.#fireEvents = true;\r\n\r\n this.parentForm = el.parentElement;\r\n while (this.parentForm) {\r\n this.parentForm = this.parentForm.parentElement;\r\n if (this.parentForm.nodeName == \"FORM\") {\r\n break;\r\n }\r\n }\r\n this.parentForm.addEventListener(\"reset\", (ev) => {\r\n this.reset();\r\n });\r\n\r\n // Create elements\r\n this.#holderElement = document.createElement(\"div\"); // this is the one holding the fake input and the dropmenu\r\n this.#containerElement = document.createElement(\"div\"); // this is the one for the fake input (labels + input)\r\n this.#dropElement = document.createElement(\"ul\");\r\n this.#searchInput = document.createElement(\"input\");\r\n\r\n this.#holderElement.appendChild(this.#containerElement);\r\n this.#containerElement.appendChild(this.#searchInput);\r\n this.#holderElement.appendChild(this.#dropElement);\r\n // insert after\r\n this.#selectElement.parentNode.insertBefore(this.#holderElement, this.#selectElement.nextSibling);\r\n\r\n // Configure them\r\n this.#configureSearchInput();\r\n this.#configureHolderElement();\r\n this.#configureDropElement();\r\n this.#configureContainerElement();\r\n\r\n if (this.server && !this.liveServer) {\r\n this.#loadFromServer();\r\n } else {\r\n let suggestions = Array.from(this.#selectElement.querySelectorAll(\"option\")).map((option) => {\r\n return {\r\n value: option.getAttribute(\"value\"),\r\n label: option.innerText,\r\n };\r\n });\r\n this.#buildSuggestions(suggestions);\r\n }\r\n }\r\n\r\n /**\r\n * Attach to all elements matched by the selector\r\n * @param {string} selector\r\n * @param {Object} opts\r\n */\r\n static init(selector = \"select[multiple]\", opts = {}) {\r\n let list = document.querySelectorAll(selector);\r\n let el;\r\n for (let i = 0; i < list.length; i++) {\r\n if (!list[i].dataset.tags) {\r\n el = new Tags(list[i], opts);\r\n INSTANCE_MAP.set(list[i], el);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @param {HTMLSelectElement} el\r\n */\r\n static getInstance(el) {\r\n if (INSTANCE_MAP.has(el)) {\r\n return INSTANCE_MAP.get(el);\r\n }\r\n }\r\n\r\n dispose() {\r\n Data.remove(this._element, this.constructor.DATA_KEY);\r\n EventHandler.off(this._element, this.constructor.EVENT_KEY);\r\n }\r\n\r\n /**\r\n * @param {boolean} show\r\n */\r\n #loadFromServer(show = false) {\r\n if (this.#abortController) {\r\n this.#abortController.abort();\r\n }\r\n this.#abortController = new AbortController();\r\n fetch(this.server + \"?query=\" + encodeURIComponent(this.#searchInput.value), { signal: this.#abortController.signal })\r\n .then((r) => r.json())\r\n .then((suggestions) => {\r\n let data = suggestions.data || suggestions;\r\n this.#buildSuggestions(data);\r\n this.#abortController = null;\r\n if (show) {\r\n this.#showSuggestions();\r\n }\r\n })\r\n .catch((e) => {\r\n if (e.name === \"AbortError\") {\r\n return;\r\n }\r\n console.error(e);\r\n });\r\n }\r\n\r\n /**\r\n * @returns {string}\r\n */\r\n #getPlaceholder() {\r\n let firstOption = this.#selectElement.querySelector(\"option\");\r\n if (!firstOption) {\r\n return;\r\n }\r\n if (!firstOption.value) {\r\n let placeholder = firstOption.innerText;\r\n firstOption.remove();\r\n return placeholder;\r\n }\r\n if (this.#selectElement.getAttribute(\"placeholder\")) {\r\n return this.#selectElement.getAttribute(\"placeholder\");\r\n }\r\n if (this.#selectElement.getAttribute(\"data-placeholder\")) {\r\n return this.#selectElement.getAttribute(\"data-placeholder\");\r\n }\r\n return \"\";\r\n }\r\n\r\n #configureDropElement() {\r\n this.#dropElement.classList.add(...[\"dropdown-menu\", \"p-0\"]);\r\n this.#dropElement.style.maxHeight = \"280px\";\r\n this.#dropElement.style.overflowY = \"auto\";\r\n\r\n // If the mouse was outside, entering remove keyboard nav mode\r\n this.#dropElement.addEventListener(\"mouseenter\", (event) => {\r\n this.#keyboardNavigation = false;\r\n });\r\n }\r\n\r\n #configureHolderElement() {\r\n this.#holderElement.classList.add(...[\"form-control\", \"dropdown\"]);\r\n if (this.isDisabled()) {\r\n this.#holderElement.setAttribute(\"readonly\", \"\");\r\n }\r\n if (this.#getBootstrapVersion() === 4) {\r\n // Prevent fixed height due to form-control\r\n this.#holderElement.style.height = \"auto\";\r\n }\r\n }\r\n\r\n #configureContainerElement() {\r\n this.#containerElement.addEventListener(\"click\", (event) => {\r\n if (this.isDisabled()) {\r\n return;\r\n }\r\n if (this.#searchInput.style.visibility != \"hidden\") {\r\n this.#searchInput.focus();\r\n } else if (this.max === 1) {\r\n // Improve single select usage\r\n this.#showSuggestions();\r\n }\r\n });\r\n\r\n // add initial values\r\n let initialValues = this.#selectElement.querySelectorAll(\"option[selected]\");\r\n for (let j = 0; j < initialValues.length; j++) {\r\n let initialValue = initialValues[j];\r\n if (!initialValue.value) {\r\n continue;\r\n }\r\n // track initial values for reset\r\n initialValue.dataset.init = 1;\r\n this.addItem(initialValue.innerText, initialValue.value);\r\n }\r\n }\r\n\r\n #configureSearchInput() {\r\n this.#searchInput.type = \"text\";\r\n this.#searchInput.autocomplete = \"off\";\r\n this.#searchInput.style.backgroundColor = \"transparent\";\r\n this.#searchInput.style.border = 0;\r\n this.#searchInput.style.outline = 0;\r\n this.#searchInput.style.maxWidth = \"100%\";\r\n this.#searchInput.ariaLabel = this.searchLabel;\r\n if (this.isDisabled()) {\r\n this.#searchInput.setAttribute(\"disabled\", \"\");\r\n }\r\n this.#adjustWidth();\r\n\r\n this.#searchInput.addEventListener(\"input\", (event) => {\r\n this.#adjustWidth();\r\n if (this.#searchInput.value.length >= this.suggestionsThreshold) {\r\n if (this.liveServer) {\r\n this.#loadFromServer(true);\r\n } else {\r\n this.#showSuggestions();\r\n }\r\n } else {\r\n this.#hideSuggestions();\r\n }\r\n });\r\n this.#searchInput.addEventListener(\"focus\", (event) => {\r\n if (this.#searchInput.value.length >= this.suggestionsThreshold) {\r\n this.#showSuggestions();\r\n }\r\n });\r\n this.#searchInput.addEventListener(\"focusout\", (event) => {\r\n this.#hideSuggestions();\r\n });\r\n // keypress doesn't send arrow keys\r\n this.#searchInput.addEventListener(\"keydown\", (event) => {\r\n // Keycode reference : https://css-tricks.com/snippets/javascript/javascript-keycodes/\r\n let key = event.keyCode || event.key;\r\n if (this.separator.length && this.separator.includes(event.key)) {\r\n event.preventDefault();\r\n let res = this.addItem(this.#searchInput.value, null);\r\n if (res) {\r\n this.#resetSearchInput();\r\n }\r\n return;\r\n }\r\n switch (key) {\r\n case 13:\r\n case \"Enter\":\r\n event.preventDefault();\r\n let selection = this.getActiveSelection();\r\n if (selection) {\r\n selection.click();\r\n } else {\r\n // We use what is typed if not selected and not empty\r\n if (this.allowNew && !this.#isSelected(this.#searchInput.value) && this.#searchInput.value) {\r\n let res = this.addItem(this.#searchInput.value, null);\r\n if (res) {\r\n this.#resetSearchInput();\r\n }\r\n }\r\n }\r\n break;\r\n case 38:\r\n case \"ArrowUp\":\r\n event.preventDefault();\r\n this.#keyboardNavigation = true;\r\n let newSelection = this.#moveSelectionUp();\r\n // If we use arrow up without input and there is no new selection, hide suggestions\r\n if (this.#searchInput.value.length == 0 && this.#dropElement.classList.contains(\"show\") && !newSelection) {\r\n this.#hideSuggestions();\r\n }\r\n break;\r\n case 40:\r\n case \"ArrowDown\":\r\n event.preventDefault();\r\n this.#keyboardNavigation = true;\r\n this.#moveSelectionDown();\r\n // If we use arrow down without input, show suggestions\r\n if (this.#searchInput.value.length == 0 && !this.#dropElement.classList.contains(\"show\")) {\r\n this.#showSuggestions();\r\n }\r\n break;\r\n case 8:\r\n case \"Backspace\":\r\n if (this.#searchInput.value.length == 0) {\r\n this.removeLastItem();\r\n this.#adjustWidth();\r\n this.#hideSuggestions();\r\n }\r\n break;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n #moveSelectionUp() {\r\n let active = this.getActiveSelection();\r\n if (active) {\r\n let prev = active.parentNode;\r\n do {\r\n prev = prev.previousSibling;\r\n } while (prev && prev.style.display == \"none\");\r\n if (!prev) {\r\n return null;\r\n }\r\n active.classList.remove(...ACTIVE_CLASSES);\r\n prev.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n // Don't use scrollIntoView as it scrolls the whole window\r\n prev.parentNode.scrollTop = prev.offsetTop - prev.parentNode.offsetTop;\r\n return prev;\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n #moveSelectionDown() {\r\n let active = this.getActiveSelection();\r\n let next = null;\r\n if (active) {\r\n next = active.parentNode;\r\n do {\r\n next = next.nextSibling;\r\n } while (next && next.style.display == \"none\");\r\n if (!next) {\r\n return null;\r\n }\r\n active.classList.remove(...ACTIVE_CLASSES);\r\n next.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n // This is the equivalent of scrollIntoView(false) but only for parent node\r\n if (next.offsetTop > next.parentNode.offsetHeight - next.offsetHeight) {\r\n next.parentNode.scrollTop += next.offsetHeight;\r\n }\r\n return next;\r\n }\r\n return next;\r\n }\r\n\r\n /**\r\n * Adjust the field to fit its content\r\n */\r\n #adjustWidth() {\r\n if (this.#searchInput.value) {\r\n this.#searchInput.size = this.#searchInput.value.length + 1;\r\n } else {\r\n // Show the placeholder only if empty\r\n if (this.getSelectedValues().length) {\r\n this.#searchInput.placeholder = \"\";\r\n this.#searchInput.size = 1;\r\n } else {\r\n this.#searchInput.size = this.placeholder.length;\r\n this.#searchInput.placeholder = this.placeholder;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Add suggestions to the drop element\r\n * @param {array}\r\n */\r\n #buildSuggestions(suggestions = null) {\r\n while (this.#dropElement.lastChild) {\r\n this.#dropElement.removeChild(this.#dropElement.lastChild);\r\n }\r\n for (let i = 0; i < suggestions.length; i++) {\r\n let suggestion = suggestions[i];\r\n if (!suggestion.value) {\r\n continue;\r\n }\r\n let newChild = document.createElement(\"li\");\r\n let newChildLink = document.createElement(\"a\");\r\n newChild.append(newChildLink);\r\n newChildLink.classList.add(\"dropdown-item\");\r\n newChildLink.setAttribute(VALUE_ATTRIBUTE, suggestion.value);\r\n newChildLink.setAttribute(\"href\", \"#\");\r\n newChildLink.innerText = suggestion.label;\r\n if (suggestion.data) {\r\n for (const [key, value] of Object.entries(suggestion.data)) {\r\n newChildLink.dataset[key] = value;\r\n }\r\n }\r\n this.#dropElement.appendChild(newChild);\r\n\r\n // Hover sets active item\r\n newChildLink.addEventListener(\"mouseenter\", (event) => {\r\n // Don't trigger enter if using arrows\r\n if (this.#keyboardNavigation) {\r\n return;\r\n }\r\n this.removeActiveSelection();\r\n newChild.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n });\r\n // Moving the mouse means no longer using keyboard\r\n newChildLink.addEventListener(\"mousemove\", (event) => {\r\n this.#keyboardNavigation = false;\r\n });\r\n\r\n newChildLink.addEventListener(\"mousedown\", (event) => {\r\n // Otherwise searchInput would lose focus and close the menu\r\n event.preventDefault();\r\n });\r\n newChildLink.addEventListener(\"click\", (event) => {\r\n event.preventDefault();\r\n this.addItem(newChildLink.innerText, newChildLink.getAttribute(VALUE_ATTRIBUTE), newChildLink.dataset);\r\n this.#resetSearchInput();\r\n });\r\n }\r\n }\r\n\r\n reset() {\r\n this.removeAll();\r\n\r\n // Reset doesn't fire change event\r\n this.#fireEvents = false;\r\n let initialValues = this.#selectElement.querySelectorAll(\"option[data-init]\");\r\n for (let j = 0; j < initialValues.length; j++) {\r\n let initialValue = initialValues[j];\r\n this.addItem(initialValue.innerText, initialValue.value);\r\n }\r\n this.#adjustWidth();\r\n this.#fireEvents = true;\r\n }\r\n\r\n #resetSearchInput() {\r\n this.#searchInput.value = \"\";\r\n this.#adjustWidth();\r\n this.#hideSuggestions();\r\n\r\n // We use visibility instead of display to keep layout intact\r\n if (this.max && this.getSelectedValues().length === this.max) {\r\n this.#searchInput.style.visibility = \"hidden\";\r\n } else if (this.#searchInput.style.visibility == \"hidden\") {\r\n this.#searchInput.style.visibility = \"visible\";\r\n }\r\n }\r\n\r\n /**\r\n * @returns {array}\r\n */\r\n getSelectedValues() {\r\n let selected = this.getSelectedOptions();\r\n return Array.from(selected).map((el) => el.value);\r\n }\r\n\r\n /**\r\n * @returns {NodeList}\r\n */\r\n getSelectedOptions() {\r\n // :checked can return false positives\r\n return this.#selectElement.querySelectorAll(\"option[selected]\");\r\n }\r\n\r\n /**\r\n * The element create with buildSuggestions\r\n */\r\n #showSuggestions() {\r\n if (!this.#dropElement.classList.contains(\"show\")) {\r\n this.#dropElement.classList.add(\"show\");\r\n }\r\n\r\n // Position next to search input\r\n this.#dropElement.style.left = this.#searchInput.offsetLeft + \"px\";\r\n\r\n // Get search value\r\n let search = this.#searchInput.value.toLocaleLowerCase();\r\n\r\n // Get current values\r\n let values = this.getSelectedValues();\r\n\r\n // Filter the list according to search string\r\n let list = this.#dropElement.querySelectorAll(\"li\");\r\n let found = false;\r\n let firstItem = null;\r\n let hasPossibleValues = false;\r\n for (let i = 0; i < list.length; i++) {\r\n let item = list[i];\r\n let text = item.innerText.toLocaleLowerCase();\r\n let link = item.querySelector(\"a\");\r\n\r\n // Remove previous selection\r\n link.classList.remove(...ACTIVE_CLASSES);\r\n\r\n // Hide selected values\r\n if (values.indexOf(link.getAttribute(VALUE_ATTRIBUTE)) != -1) {\r\n item.style.display = \"none\";\r\n continue;\r\n }\r\n\r\n hasPossibleValues = true;\r\n\r\n // Check search length since we can trigger dropdown with arrow\r\n let isMatched = search.length === 0 || text.indexOf(search) !== -1;\r\n if (this.showAllSuggestions || this.suggestionsThreshold === 0 || isMatched) {\r\n item.style.display = \"list-item\";\r\n found = true;\r\n if (!firstItem && isMatched) {\r\n firstItem = item;\r\n }\r\n } else {\r\n item.style.display = \"none\";\r\n }\r\n }\r\n\r\n // Special case if nothing matches\r\n if (!found) {\r\n this.#dropElement.classList.remove(\"show\");\r\n }\r\n\r\n // Always select first item\r\n if (firstItem) {\r\n if (this.#holderElement.classList.contains(\"is-invalid\")) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n }\r\n firstItem.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n firstItem.parentNode.scrollTop = firstItem.offsetTop - firstItem.parentNode.offsetTop;\r\n } else {\r\n // No item and we don't allow new items => error\r\n if (!this.allowNew && !(search.length === 0 && !hasPossibleValues)) {\r\n this.#holderElement.classList.add(\"is-invalid\");\r\n } else if (this.validationRegex && this.#holderElement.classList.contains(\"is-invalid\")) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * The element create with buildSuggestions\r\n */\r\n #hideSuggestions() {\r\n if (this.#dropElement.classList.contains(\"show\")) {\r\n this.#dropElement.classList.remove(\"show\");\r\n }\r\n if (this.#holderElement.classList.contains(\"is-invalid\")) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n }\r\n this.removeActiveSelection();\r\n }\r\n\r\n /**\r\n * @returns {Number}\r\n */\r\n #getBootstrapVersion() {\r\n let ver = 5;\r\n // If we have jQuery and the tooltip plugin for BS4\r\n if (window.jQuery && $.fn.tooltip != undefined && $.fn.tooltip.Constructor != undefined) {\r\n ver = parseInt($.fn.tooltip.Constructor.VERSION.charAt(0));\r\n }\r\n return ver;\r\n }\r\n\r\n /**\r\n * Find if label is already selected (based on attribute)\r\n * @param {string} text\r\n * @returns {boolean}\r\n */\r\n #isSelected(text) {\r\n const opt = Array.from(this.#selectElement.querySelectorAll(\"option\")).find((el) => el.textContent == text);\r\n if (opt && opt.getAttribute(\"selected\")) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Checks if value matches a configured regex\r\n * @param {string} value\r\n * @returns {boolean}\r\n */\r\n #validateRegex(value) {\r\n const regex = new RegExp(this.validationRegex.trim());\r\n return regex.test(value);\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n getActiveSelection() {\r\n return this.#dropElement.querySelector(\"a.\" + ACTIVE_CLASS);\r\n }\r\n\r\n removeActiveSelection() {\r\n let selection = this.getActiveSelection();\r\n if (selection) {\r\n selection.classList.remove(...ACTIVE_CLASSES);\r\n }\r\n }\r\n\r\n removeAll() {\r\n let items = this.#containerElement.querySelectorAll(\"span\");\r\n items.forEach((item) => {\r\n this.removeLastItem(true);\r\n });\r\n }\r\n\r\n /**\r\n * @param {boolean} noEvents \r\n */\r\n removeLastItem(noEvents) {\r\n if (noEvents) {\r\n this.#fireEvents = false;\r\n }\r\n let items = this.#containerElement.querySelectorAll(\"span\");\r\n if (!items.length) {\r\n return;\r\n }\r\n let lastItem = items[items.length - 1];\r\n this.removeItem(lastItem.getAttribute(VALUE_ATTRIBUTE));\r\n this.#fireEvents = true;\r\n }\r\n\r\n isDisabled() {\r\n return this.#selectElement.hasAttribute(\"disabled\") || this.#selectElement.hasAttribute(\"readonly\");\r\n }\r\n\r\n /**\r\n * @param {string} text\r\n * @param {string} value\r\n * @param {object} data\r\n * @return {boolean}\r\n */\r\n addItem(text, value = null, data = {}) {\r\n if (!value) {\r\n value = text;\r\n }\r\n\r\n if (this.max && this.getSelectedValues().length >= this.max) {\r\n // Replace value for single select\r\n if (this.max === 1) {\r\n this.removeLastItem(true);\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n if (this.validationRegex && !this.#validateRegex(text)) {\r\n this.#holderElement.classList.add(\"is-invalid\");\r\n return false;\r\n }\r\n\r\n const bver = this.#getBootstrapVersion();\r\n let opt = this.#selectElement.querySelector('option[value=\"' + value + '\"]');\r\n if (opt) {\r\n data = opt.dataset;\r\n }\r\n\r\n // create span\r\n let html = text;\r\n let span = document.createElement(\"span\");\r\n let classes = [\"badge\"];\r\n let badgeStyle = this.badgeStyle;\r\n if (data.badgeStyle) {\r\n badgeStyle = data.badgeStyle;\r\n }\r\n if (data.badgeClass) {\r\n classes.push(data.badgeClass);\r\n }\r\n if (bver === 5) {\r\n //https://getbootstrap.com/docs/5.1/components/badge/\r\n classes = [...classes, ...[\"me-2\", \"bg-\" + badgeStyle]];\r\n } else {\r\n // https://getbootstrap.com/docs/4.6/components/badge/\r\n classes = [...classes, ...[\"mr-2\", \"badge-\" + badgeStyle]];\r\n }\r\n span.classList.add(...classes);\r\n span.setAttribute(VALUE_ATTRIBUTE, value);\r\n\r\n if (this.allowClear && !this.isDisabled()) {\r\n const btn =\r\n bver === 5\r\n ? ''\r\n : '';\r\n html = btn + html;\r\n }\r\n\r\n span.innerHTML = html;\r\n this.#containerElement.insertBefore(span, this.#searchInput);\r\n\r\n if (this.allowClear && !this.isDisabled()) {\r\n span.querySelector(\"button\").addEventListener(\"click\", (event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.removeItem(value);\r\n document.activeElement.blur();\r\n });\r\n }\r\n\r\n // we need to create a new option\r\n if (!opt) {\r\n opt = document.createElement(\"option\");\r\n opt.value = value;\r\n opt.innerText = text;\r\n // Pass along data provided\r\n for (const [key, value] of Object.entries(data)) {\r\n opt.dataset[key] = value;\r\n }\r\n this.#selectElement.appendChild(opt);\r\n }\r\n\r\n // update select, we need to set attribute for isSelected\r\n opt.setAttribute(\"selected\", \"selected\");\r\n opt.selected = true;\r\n\r\n // Fire change event\r\n if (this.#fireEvents) {\r\n this.#selectElement.dispatchEvent(new Event(\"change\"), { bubbles: true });\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * @param {string} value\r\n */\r\n removeItem(value) {\r\n let item = this.#containerElement.querySelector(\"span[\" + VALUE_ATTRIBUTE + '=\"' + value + '\"]');\r\n if (!item) {\r\n return;\r\n }\r\n item.remove();\r\n\r\n // update select\r\n let opt = this.#selectElement.querySelector('option[value=\"' + value + '\"]');\r\n if (opt) {\r\n opt.removeAttribute(\"selected\");\r\n opt.selected = false;\r\n\r\n // Fire change event\r\n if (this.#fireEvents) {\r\n this.#selectElement.dispatchEvent(new Event(\"change\"), { bubbles: true });\r\n }\r\n }\r\n\r\n // Make input visible\r\n if (this.#searchInput.style.visibility == \"hidden\" && this.max && this.getSelectedValues().length < this.max) {\r\n this.#searchInput.style.visibility = \"visible\";\r\n }\r\n }\r\n}\r\n\r\nexport default Tags;\r\n"], - "mappings": "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", + "sourcesContent": ["/**\r\n * Bootstrap 5 (and 4!) tags\r\n *\r\n * Turns your select[multiple] into nice tags lists\r\n *\r\n * Required Bootstrap 5 styles:\r\n * - badge\r\n * - background-color utility\r\n * - margin-end utility\r\n * - forms\r\n * - dropdown\r\n */\r\n\r\nconst ACTIVE_CLASS = \"is-active\";\r\nconst ACTIVE_CLASSES = [\"is-active\", \"bg-primary\", \"text-white\"];\r\nconst VALUE_ATTRIBUTE = \"data-value\";\r\n\r\n// Static map will minify very badly as class prop, so we use an external constant\r\nconst INSTANCE_MAP = new WeakMap();\r\n\r\nclass Tags {\r\n #abortController;\r\n #selectElement;\r\n #holderElement;\r\n #containerElement;\r\n #dropElement;\r\n #searchInput;\r\n #keyboardNavigation;\r\n #fireEvents;\r\n\r\n /**\r\n * @param {HTMLSelectElement} el\r\n * @param {Object} globalOpts\r\n */\r\n constructor(el, globalOpts = {}) {\r\n // Hide the select element and register a tags attr\r\n el.style.display = \"none\";\r\n el.dataset.tags = true;\r\n this.#selectElement = el;\r\n\r\n // Allow 1/0, true/false as strings\r\n const parseBool = (value) => [\"true\", \"false\", \"1\", \"0\", true, false].includes(value) && !!JSON.parse(value);\r\n\r\n // Handle options, using global settings first and data attr override\r\n const opts = { ...globalOpts, ...el.dataset };\r\n this.allowNew = opts.allowNew ? parseBool(opts.allowNew) : false;\r\n this.showAllSuggestions = opts.showAllSuggestions ? parseBool(opts.showAllSuggestions) : false;\r\n this.badgeStyle = opts.badgeStyle || \"primary\";\r\n this.allowClear = opts.allowClear ? parseBool(opts.allowClear) : false;\r\n this.server = opts.server || false;\r\n this.liveServer = opts.liveServer ? parseBool(opts.liveServer) : false;\r\n this.suggestionsThreshold = opts.suggestionsThreshold ? parseInt(opts.suggestionsThreshold) : 1;\r\n this.validationRegex = opts.regex || \"\";\r\n this.separator = opts.separator ? opts.separator.split(\"|\") : [];\r\n this.max = opts.max ? parseInt(opts.max) : null;\r\n this.clearLabel = opts.clearLabel || \"Clear\";\r\n this.searchLabel = opts.searchLabel || \"Type a value\";\r\n if (!el.hasAttribute(\"multiple\")) {\r\n this.max = 1;\r\n }\r\n\r\n this.placeholder = this.#getPlaceholder();\r\n this.#keyboardNavigation = false;\r\n this.#fireEvents = true;\r\n\r\n this.parentForm = el.parentElement;\r\n while (this.parentForm) {\r\n this.parentForm = this.parentForm.parentElement;\r\n if (this.parentForm.nodeName == \"FORM\") {\r\n break;\r\n }\r\n }\r\n this.parentForm.addEventListener(\"reset\", (ev) => {\r\n this.reset();\r\n });\r\n\r\n // Create elements\r\n this.#holderElement = document.createElement(\"div\"); // this is the one holding the fake input and the dropmenu\r\n this.#containerElement = document.createElement(\"div\"); // this is the one for the fake input (labels + input)\r\n this.#dropElement = document.createElement(\"ul\");\r\n this.#searchInput = document.createElement(\"input\");\r\n\r\n this.#holderElement.appendChild(this.#containerElement);\r\n this.#containerElement.appendChild(this.#searchInput);\r\n this.#holderElement.appendChild(this.#dropElement);\r\n // insert after\r\n this.#selectElement.parentNode.insertBefore(this.#holderElement, this.#selectElement.nextSibling);\r\n\r\n // Configure them\r\n this.#configureSearchInput();\r\n this.#configureHolderElement();\r\n this.#configureDropElement();\r\n this.#configureContainerElement();\r\n\r\n if (this.server && !this.liveServer) {\r\n this.#loadFromServer();\r\n } else {\r\n let suggestions = Array.from(this.#selectElement.querySelectorAll(\"option\")).map((option) => {\r\n return {\r\n value: option.getAttribute(\"value\"),\r\n label: option.innerText,\r\n };\r\n });\r\n this.#buildSuggestions(suggestions);\r\n }\r\n }\r\n\r\n /**\r\n * Attach to all elements matched by the selector\r\n * @param {string} selector\r\n * @param {Object} opts\r\n */\r\n static init(selector = \"select[multiple]\", opts = {}) {\r\n let list = document.querySelectorAll(selector);\r\n let el;\r\n for (let i = 0; i < list.length; i++) {\r\n if (!list[i].dataset.tags) {\r\n el = new Tags(list[i], opts);\r\n INSTANCE_MAP.set(list[i], el);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @param {HTMLSelectElement} el\r\n */\r\n static getInstance(el) {\r\n if (INSTANCE_MAP.has(el)) {\r\n return INSTANCE_MAP.get(el);\r\n }\r\n }\r\n\r\n dispose() {\r\n Data.remove(this._element, this.constructor.DATA_KEY);\r\n EventHandler.off(this._element, this.constructor.EVENT_KEY);\r\n }\r\n\r\n /**\r\n * @param {boolean} show\r\n */\r\n #loadFromServer(show = false) {\r\n if (this.#abortController) {\r\n this.#abortController.abort();\r\n }\r\n this.#abortController = new AbortController();\r\n fetch(this.server + \"?query=\" + encodeURIComponent(this.#searchInput.value), { signal: this.#abortController.signal })\r\n .then((r) => r.json())\r\n .then((suggestions) => {\r\n let data = suggestions.data || suggestions;\r\n this.#buildSuggestions(data);\r\n this.#abortController = null;\r\n if (show) {\r\n this.#showSuggestions();\r\n }\r\n })\r\n .catch((e) => {\r\n if (e.name === \"AbortError\") {\r\n return;\r\n }\r\n console.error(e);\r\n });\r\n }\r\n\r\n /**\r\n * @returns {string}\r\n */\r\n #getPlaceholder() {\r\n let firstOption = this.#selectElement.querySelector(\"option\");\r\n if (!firstOption) {\r\n return;\r\n }\r\n if (!firstOption.value) {\r\n let placeholder = firstOption.innerText;\r\n firstOption.remove();\r\n return placeholder;\r\n }\r\n if (this.#selectElement.getAttribute(\"placeholder\")) {\r\n return this.#selectElement.getAttribute(\"placeholder\");\r\n }\r\n if (this.#selectElement.getAttribute(\"data-placeholder\")) {\r\n return this.#selectElement.getAttribute(\"data-placeholder\");\r\n }\r\n return \"\";\r\n }\r\n\r\n #configureDropElement() {\r\n this.#dropElement.classList.add(...[\"dropdown-menu\", \"p-0\"]);\r\n this.#dropElement.style.maxHeight = \"280px\";\r\n this.#dropElement.style.overflowY = \"auto\";\r\n\r\n // If the mouse was outside, entering remove keyboard nav mode\r\n this.#dropElement.addEventListener(\"mouseenter\", (event) => {\r\n this.#keyboardNavigation = false;\r\n });\r\n }\r\n\r\n #configureHolderElement() {\r\n this.#holderElement.classList.add(...[\"form-control\", \"dropdown\"]);\r\n if (this.isDisabled()) {\r\n this.#holderElement.setAttribute(\"readonly\", \"\");\r\n }\r\n if (this.#getBootstrapVersion() === 4) {\r\n // Prevent fixed height due to form-control\r\n this.#holderElement.style.height = \"auto\";\r\n }\r\n }\r\n\r\n #configureContainerElement() {\r\n this.#containerElement.addEventListener(\"click\", (event) => {\r\n if (this.isDisabled()) {\r\n return;\r\n }\r\n if (this.#searchInput.style.visibility != \"hidden\") {\r\n this.#searchInput.focus();\r\n } else if (this.max === 1) {\r\n // Improve single select usage\r\n this.#showSuggestions();\r\n }\r\n });\r\n\r\n // add initial values\r\n let initialValues = this.#selectElement.selectedOptions;\r\n for (let j = 0; j < initialValues.length; j++) {\r\n let initialValue = initialValues[j];\r\n if (!initialValue.value) {\r\n continue;\r\n }\r\n // track initial values for reset\r\n initialValue.dataset.init = 1;\r\n this.addItem(initialValue.innerText, initialValue.value);\r\n }\r\n }\r\n\r\n #configureSearchInput() {\r\n this.#searchInput.type = \"text\";\r\n this.#searchInput.autocomplete = \"off\";\r\n this.#searchInput.style.backgroundColor = \"transparent\";\r\n this.#searchInput.style.border = 0;\r\n this.#searchInput.style.outline = 0;\r\n this.#searchInput.style.maxWidth = \"100%\";\r\n this.#searchInput.ariaLabel = this.searchLabel;\r\n if (this.isDisabled()) {\r\n this.#searchInput.setAttribute(\"disabled\", \"\");\r\n }\r\n this.#adjustWidth();\r\n\r\n this.#searchInput.addEventListener(\"input\", (event) => {\r\n this.#adjustWidth();\r\n if (this.#searchInput.value.length >= this.suggestionsThreshold) {\r\n if (this.liveServer) {\r\n this.#loadFromServer(true);\r\n } else {\r\n this.#showSuggestions();\r\n }\r\n } else {\r\n this.#hideSuggestions();\r\n }\r\n });\r\n this.#searchInput.addEventListener(\"focus\", (event) => {\r\n if (this.#searchInput.value.length >= this.suggestionsThreshold) {\r\n this.#showSuggestions();\r\n }\r\n });\r\n this.#searchInput.addEventListener(\"focusout\", (event) => {\r\n this.#hideSuggestions();\r\n });\r\n // keypress doesn't send arrow keys\r\n this.#searchInput.addEventListener(\"keydown\", (event) => {\r\n // Keycode reference : https://css-tricks.com/snippets/javascript/javascript-keycodes/\r\n let key = event.keyCode || event.key;\r\n if (this.separator.length && this.separator.includes(event.key)) {\r\n event.preventDefault();\r\n let res = this.addItem(this.#searchInput.value, null);\r\n if (res) {\r\n this.#resetSearchInput();\r\n }\r\n return;\r\n }\r\n switch (key) {\r\n case 13:\r\n case \"Enter\":\r\n event.preventDefault();\r\n let selection = this.getActiveSelection();\r\n if (selection) {\r\n selection.click();\r\n } else {\r\n // We use what is typed if not selected and not empty\r\n if (this.allowNew && !this.#isSelected(this.#searchInput.value) && this.#searchInput.value) {\r\n let res = this.addItem(this.#searchInput.value, null);\r\n if (res) {\r\n this.#resetSearchInput();\r\n }\r\n }\r\n }\r\n break;\r\n case 38:\r\n case \"ArrowUp\":\r\n event.preventDefault();\r\n this.#keyboardNavigation = true;\r\n let newSelection = this.#moveSelectionUp();\r\n // If we use arrow up without input and there is no new selection, hide suggestions\r\n if (this.#searchInput.value.length == 0 && this.#dropElement.classList.contains(\"show\") && !newSelection) {\r\n this.#hideSuggestions();\r\n }\r\n break;\r\n case 40:\r\n case \"ArrowDown\":\r\n event.preventDefault();\r\n this.#keyboardNavigation = true;\r\n this.#moveSelectionDown();\r\n // If we use arrow down without input, show suggestions\r\n if (this.#searchInput.value.length == 0 && !this.#dropElement.classList.contains(\"show\")) {\r\n this.#showSuggestions();\r\n }\r\n break;\r\n case 8:\r\n case \"Backspace\":\r\n if (this.#searchInput.value.length == 0) {\r\n this.removeLastItem();\r\n this.#adjustWidth();\r\n this.#hideSuggestions();\r\n }\r\n break;\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n #moveSelectionUp() {\r\n let active = this.getActiveSelection();\r\n if (active) {\r\n let prev = active.parentNode;\r\n do {\r\n prev = prev.previousSibling;\r\n } while (prev && prev.style.display == \"none\");\r\n if (!prev) {\r\n return null;\r\n }\r\n active.classList.remove(...ACTIVE_CLASSES);\r\n prev.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n // Don't use scrollIntoView as it scrolls the whole window\r\n prev.parentNode.scrollTop = prev.offsetTop - prev.parentNode.offsetTop;\r\n return prev;\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n #moveSelectionDown() {\r\n let active = this.getActiveSelection();\r\n let next = null;\r\n if (active) {\r\n next = active.parentNode;\r\n do {\r\n next = next.nextSibling;\r\n } while (next && next.style.display == \"none\");\r\n if (!next) {\r\n return null;\r\n }\r\n active.classList.remove(...ACTIVE_CLASSES);\r\n next.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n // This is the equivalent of scrollIntoView(false) but only for parent node\r\n if (next.offsetTop > next.parentNode.offsetHeight - next.offsetHeight) {\r\n next.parentNode.scrollTop += next.offsetHeight;\r\n }\r\n return next;\r\n }\r\n return next;\r\n }\r\n\r\n /**\r\n * Adjust the field to fit its content\r\n */\r\n #adjustWidth() {\r\n if (this.#searchInput.value) {\r\n this.#searchInput.size = this.#searchInput.value.length + 1;\r\n } else {\r\n // Show the placeholder only if empty\r\n if (this.getSelectedValues().length) {\r\n this.#searchInput.placeholder = \"\";\r\n this.#searchInput.size = 1;\r\n } else {\r\n this.#searchInput.size = this.placeholder.length;\r\n this.#searchInput.placeholder = this.placeholder;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Add suggestions to the drop element\r\n * @param {array}\r\n */\r\n #buildSuggestions(suggestions = null) {\r\n while (this.#dropElement.lastChild) {\r\n this.#dropElement.removeChild(this.#dropElement.lastChild);\r\n }\r\n for (let i = 0; i < suggestions.length; i++) {\r\n let suggestion = suggestions[i];\r\n if (!suggestion.value) {\r\n continue;\r\n }\r\n let newChild = document.createElement(\"li\");\r\n let newChildLink = document.createElement(\"a\");\r\n newChild.append(newChildLink);\r\n newChildLink.classList.add(\"dropdown-item\");\r\n newChildLink.setAttribute(VALUE_ATTRIBUTE, suggestion.value);\r\n newChildLink.setAttribute(\"href\", \"#\");\r\n newChildLink.innerText = suggestion.label;\r\n if (suggestion.data) {\r\n for (const [key, value] of Object.entries(suggestion.data)) {\r\n newChildLink.dataset[key] = value;\r\n }\r\n }\r\n this.#dropElement.appendChild(newChild);\r\n\r\n // Hover sets active item\r\n newChildLink.addEventListener(\"mouseenter\", (event) => {\r\n // Don't trigger enter if using arrows\r\n if (this.#keyboardNavigation) {\r\n return;\r\n }\r\n this.removeActiveSelection();\r\n newChild.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n });\r\n // Moving the mouse means no longer using keyboard\r\n newChildLink.addEventListener(\"mousemove\", (event) => {\r\n this.#keyboardNavigation = false;\r\n });\r\n\r\n newChildLink.addEventListener(\"mousedown\", (event) => {\r\n // Otherwise searchInput would lose focus and close the menu\r\n event.preventDefault();\r\n });\r\n newChildLink.addEventListener(\"click\", (event) => {\r\n event.preventDefault();\r\n this.addItem(newChildLink.innerText, newChildLink.getAttribute(VALUE_ATTRIBUTE), newChildLink.dataset);\r\n this.#resetSearchInput();\r\n });\r\n }\r\n }\r\n\r\n reset() {\r\n this.removeAll();\r\n\r\n // Reset doesn't fire change event\r\n this.#fireEvents = false;\r\n let initialValues = this.#selectElement.querySelectorAll(\"option[data-init]\");\r\n for (let j = 0; j < initialValues.length; j++) {\r\n let initialValue = initialValues[j];\r\n this.addItem(initialValue.innerText, initialValue.value);\r\n }\r\n this.#adjustWidth();\r\n this.#fireEvents = true;\r\n }\r\n\r\n #resetSearchInput() {\r\n this.#searchInput.value = \"\";\r\n this.#adjustWidth();\r\n this.#hideSuggestions();\r\n\r\n // We use visibility instead of display to keep layout intact\r\n if (this.max && this.getSelectedValues().length === this.max) {\r\n this.#searchInput.style.visibility = \"hidden\";\r\n } else if (this.#searchInput.style.visibility == \"hidden\") {\r\n this.#searchInput.style.visibility = \"visible\";\r\n }\r\n }\r\n\r\n /**\r\n * @returns {array}\r\n */\r\n getSelectedValues() {\r\n let selected = this.#selectElement.selectedOptions;\r\n return Array.from(selected).map((el) => el.value);\r\n }\r\n\r\n /**\r\n * The element create with buildSuggestions\r\n */\r\n #showSuggestions() {\r\n if (!this.#dropElement.classList.contains(\"show\")) {\r\n this.#dropElement.classList.add(\"show\");\r\n }\r\n\r\n // Position next to search input\r\n this.#dropElement.style.left = this.#searchInput.offsetLeft + \"px\";\r\n\r\n // Get search value\r\n let search = this.#searchInput.value.toLocaleLowerCase();\r\n\r\n // Get current values\r\n let values = this.getSelectedValues();\r\n\r\n // Filter the list according to search string\r\n let list = this.#dropElement.querySelectorAll(\"li\");\r\n let found = false;\r\n let firstItem = null;\r\n let hasPossibleValues = false;\r\n for (let i = 0; i < list.length; i++) {\r\n let item = list[i];\r\n let text = item.innerText.toLocaleLowerCase();\r\n let link = item.querySelector(\"a\");\r\n\r\n // Remove previous selection\r\n link.classList.remove(...ACTIVE_CLASSES);\r\n\r\n // Hide selected values\r\n if (values.indexOf(link.getAttribute(VALUE_ATTRIBUTE)) != -1) {\r\n item.style.display = \"none\";\r\n continue;\r\n }\r\n\r\n hasPossibleValues = true;\r\n\r\n // Check search length since we can trigger dropdown with arrow\r\n let isMatched = search.length === 0 || text.indexOf(search) !== -1;\r\n if (this.showAllSuggestions || this.suggestionsThreshold === 0 || isMatched) {\r\n item.style.display = \"list-item\";\r\n found = true;\r\n if (!firstItem && isMatched) {\r\n firstItem = item;\r\n }\r\n } else {\r\n item.style.display = \"none\";\r\n }\r\n }\r\n\r\n // Special case if nothing matches\r\n if (!found) {\r\n this.#dropElement.classList.remove(\"show\");\r\n }\r\n\r\n // Always select first item\r\n if (firstItem) {\r\n if (this.#holderElement.classList.contains(\"is-invalid\")) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n }\r\n firstItem.querySelector(\"a\").classList.add(...ACTIVE_CLASSES);\r\n firstItem.parentNode.scrollTop = firstItem.offsetTop - firstItem.parentNode.offsetTop;\r\n } else {\r\n // No item and we don't allow new items => error\r\n if (!this.allowNew && !(search.length === 0 && !hasPossibleValues)) {\r\n this.#holderElement.classList.add(\"is-invalid\");\r\n } else if (this.validationRegex && this.#holderElement.classList.contains(\"is-invalid\")) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * The element create with buildSuggestions\r\n */\r\n #hideSuggestions() {\r\n if (this.#dropElement.classList.contains(\"show\")) {\r\n this.#dropElement.classList.remove(\"show\");\r\n }\r\n if (this.#holderElement.classList.contains(\"is-invalid\")) {\r\n this.#holderElement.classList.remove(\"is-invalid\");\r\n }\r\n this.removeActiveSelection();\r\n }\r\n\r\n /**\r\n * @returns {Number}\r\n */\r\n #getBootstrapVersion() {\r\n let ver = 5;\r\n // If we have jQuery and the tooltip plugin for BS4\r\n if (window.jQuery && $.fn.tooltip != undefined && $.fn.tooltip.Constructor != undefined) {\r\n ver = parseInt($.fn.tooltip.Constructor.VERSION.charAt(0));\r\n }\r\n return ver;\r\n }\r\n\r\n /**\r\n * Find if label is already selected (based on attribute)\r\n * @param {string} text\r\n * @returns {boolean}\r\n */\r\n #isSelected(text) {\r\n const opt = Array.from(this.#selectElement.querySelectorAll(\"option\")).find((el) => el.textContent == text);\r\n if (opt && opt.getAttribute(\"selected\")) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Checks if value matches a configured regex\r\n * @param {string} value\r\n * @returns {boolean}\r\n */\r\n #validateRegex(value) {\r\n const regex = new RegExp(this.validationRegex.trim());\r\n return regex.test(value);\r\n }\r\n\r\n /**\r\n * @returns {HTMLElement}\r\n */\r\n getActiveSelection() {\r\n return this.#dropElement.querySelector(\"a.\" + ACTIVE_CLASS);\r\n }\r\n\r\n removeActiveSelection() {\r\n let selection = this.getActiveSelection();\r\n if (selection) {\r\n selection.classList.remove(...ACTIVE_CLASSES);\r\n }\r\n }\r\n\r\n removeAll() {\r\n let items = this.#containerElement.querySelectorAll(\"span\");\r\n items.forEach((item) => {\r\n this.removeLastItem(true);\r\n });\r\n }\r\n\r\n /**\r\n * @param {boolean} noEvents\r\n */\r\n removeLastItem(noEvents) {\r\n if (noEvents) {\r\n this.#fireEvents = false;\r\n }\r\n let items = this.#containerElement.querySelectorAll(\"span\");\r\n if (!items.length) {\r\n return;\r\n }\r\n let lastItem = items[items.length - 1];\r\n this.removeItem(lastItem.getAttribute(VALUE_ATTRIBUTE));\r\n this.#fireEvents = true;\r\n }\r\n\r\n isDisabled() {\r\n return this.#selectElement.hasAttribute(\"disabled\") || this.#selectElement.hasAttribute(\"readonly\");\r\n }\r\n\r\n /**\r\n * @param {string} text\r\n * @param {string} value\r\n * @param {object} data\r\n * @return {boolean}\r\n */\r\n addItem(text, value = null, data = {}) {\r\n if (!value) {\r\n value = text;\r\n }\r\n\r\n if (this.max && this.getSelectedValues().length >= this.max) {\r\n // Replace value for single select\r\n if (this.max === 1) {\r\n this.removeLastItem(true);\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n if (this.validationRegex && !this.#validateRegex(text)) {\r\n this.#holderElement.classList.add(\"is-invalid\");\r\n return false;\r\n }\r\n\r\n const bver = this.#getBootstrapVersion();\r\n let opt = this.#selectElement.querySelector('option[value=\"' + value + '\"]');\r\n if (opt) {\r\n data = opt.dataset;\r\n }\r\n\r\n // create span\r\n let html = text;\r\n let span = document.createElement(\"span\");\r\n let classes = [\"badge\"];\r\n let badgeStyle = this.badgeStyle;\r\n if (data.badgeStyle) {\r\n badgeStyle = data.badgeStyle;\r\n }\r\n if (data.badgeClass) {\r\n classes.push(data.badgeClass);\r\n }\r\n if (bver === 5) {\r\n //https://getbootstrap.com/docs/5.1/components/badge/\r\n classes = [...classes, ...[\"me-2\", \"bg-\" + badgeStyle]];\r\n } else {\r\n // https://getbootstrap.com/docs/4.6/components/badge/\r\n classes = [...classes, ...[\"mr-2\", \"badge-\" + badgeStyle]];\r\n }\r\n span.classList.add(...classes);\r\n span.setAttribute(VALUE_ATTRIBUTE, value);\r\n\r\n if (this.allowClear && !this.isDisabled()) {\r\n const btn =\r\n bver === 5\r\n ? ''\r\n : '';\r\n html = btn + html;\r\n }\r\n\r\n span.innerHTML = html;\r\n this.#containerElement.insertBefore(span, this.#searchInput);\r\n\r\n if (this.allowClear && !this.isDisabled()) {\r\n span.querySelector(\"button\").addEventListener(\"click\", (event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.removeItem(value);\r\n document.activeElement.blur();\r\n });\r\n }\r\n\r\n // we need to create a new option\r\n if (!opt) {\r\n opt = document.createElement(\"option\");\r\n opt.value = value;\r\n opt.innerText = text;\r\n // Pass along data provided\r\n for (const [key, value] of Object.entries(data)) {\r\n opt.dataset[key] = value;\r\n }\r\n this.#selectElement.appendChild(opt);\r\n }\r\n\r\n // update select, we need to set attribute for isSelected\r\n opt.setAttribute(\"selected\", \"selected\");\r\n opt.selected = true;\r\n\r\n // Fire change event\r\n if (this.#fireEvents) {\r\n this.#selectElement.dispatchEvent(new Event(\"change\"), { bubbles: true });\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * @param {string} value\r\n */\r\n removeItem(value) {\r\n let item = this.#containerElement.querySelector(\"span[\" + VALUE_ATTRIBUTE + '=\"' + value + '\"]');\r\n if (!item) {\r\n return;\r\n }\r\n item.remove();\r\n\r\n // update select\r\n let opt = this.#selectElement.querySelector('option[value=\"' + value + '\"]');\r\n if (opt) {\r\n opt.removeAttribute(\"selected\");\r\n opt.selected = false;\r\n\r\n // Fire change event\r\n if (this.#fireEvents) {\r\n this.#selectElement.dispatchEvent(new Event(\"change\"), { bubbles: true });\r\n }\r\n }\r\n\r\n // Make input visible\r\n if (this.#searchInput.style.visibility == \"hidden\" && this.max && this.getSelectedValues().length < this.max) {\r\n this.#searchInput.style.visibility = \"visible\";\r\n }\r\n }\r\n}\r\n\r\nexport default Tags;\r\n"], + "mappings": "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", "names": [] }