diff --git a/package.json b/package.json index 56aafdb..82584d8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bootstrap5-tags", - "version": "1.1.2", + "version": "1.1.3", "description": "Replace select[multiple] with nices badges", "main": "bootstrap5-tags", "scripts": { diff --git a/readme.md b/readme.md index 73f527c..7389f31 100644 --- a/readme.md +++ b/readme.md @@ -49,6 +49,12 @@ Use attribute `data-allow-clear` in order to add a cross to remove items. +``` + *NOTE: don't forget the [] if you need multiple values!* ## Tips diff --git a/tags.min.js b/tags.min.js index 3993280..7f67bb6 100644 --- a/tags.min.js +++ b/tags.min.js @@ -1 +1 @@ -const ACTIVE_CLASS="is-active",ACTIVE_CLASSES=["is-active","bg-primary","text-white"],VALUE_ATTRIBUTE="data-value";class Tags{constructor(e){this.selectElement=e,this.selectElement.style.display="none",this.placeholder=this.getPlaceholder(),this.allowNew=!!e.dataset.allowNew,this.showAllSuggestions=!!e.dataset.showAllSuggestions,this.allowClear=!!e.dataset.allowClear,this.keyboardNavigation=!1,this.holderElement=document.createElement("div"),this.containerElement=document.createElement("div"),this.dropElement=document.createElement("ul"),this.searchInput=document.createElement("input"),this.holderElement.appendChild(this.containerElement),this.containerElement.appendChild(this.searchInput),this.holderElement.appendChild(this.dropElement),this.selectElement.parentNode.insertBefore(this.holderElement,this.selectElement.nextSibling),this.configureSearchInput(),this.configureHolderElement(),this.configureDropElement(),this.configureContainerElement(),this.buildSuggestions()}static init(e="select[multiple]"){let t=document.querySelectorAll(e);for(let e=0;e{this.keyboardNavigation=!1})}configureHolderElement(){this.holderElement.classList.add("form-control"),this.holderElement.classList.add("dropdown")}configureContainerElement(){this.containerElement.addEventListener("click",e=>{this.searchInput.focus()});let e=this.selectElement.querySelectorAll("option[selected]");for(let t=0;t{this.adjustWidth(),this.searchInput.value.length>=1?this.showSuggestions():this.hideSuggestions()}),this.searchInput.addEventListener("keydown",e=>{let t=e.keyCode||e.key;switch(t){case 13:case"Enter":let s=this.getActiveSelection();s?(this.addItem(s.innerText,s.getAttribute(VALUE_ATTRIBUTE)),this.resetSearchInput(),this.hideSuggestions(),this.removeActiveSelection()):this.allowNew&&(this.addItem(this.searchInput.value),this.resetSearchInput(),this.hideSuggestions()),e.preventDefault();break;case 38:case"ArrowUp":e.preventDefault(),this.keyboardNavigation=!0;let i=this.moveSelectionUp();0==this.searchInput.value.length&&this.dropElement.classList.contains("show")&&!i&&this.hideSuggestions();break;case 40:case"ArrowDown":e.preventDefault(),this.keyboardNavigation=!0,this.moveSelectionDown(),0!=this.searchInput.value.length||this.dropElement.classList.contains("show")||this.showSuggestions();break;case 8:case"Backspace":0==this.searchInput.value.length&&(this.removeLastItem(),this.adjustWidth(),this.hideSuggestions())}})}moveSelectionUp(){let e=this.getActiveSelection();if(e){let t=e.parentNode;do{t=t.previousSibling}while(t&&"none"==t.style.display);return t?(e.classList.remove(...ACTIVE_CLASSES),t.querySelector("a").classList.add(...ACTIVE_CLASSES),t.scrollIntoView(!0),t):null}return null}moveSelectionDown(){let e=this.getActiveSelection();if(e){let t=e.parentNode;do{t=t.nextSibling}while(t&&"none"==t.style.display);return t?(e.classList.remove(...ACTIVE_CLASSES),t.querySelector("a").classList.add(...ACTIVE_CLASSES),t.scrollIntoView(!1),t):null}return null}adjustWidth(){this.searchInput.value?this.searchInput.size=this.searchInput.value.length+1:this.getSelectedValues().length?(this.searchInput.placeholder="",this.searchInput.size=1):(this.searchInput.size=this.placeholder.length,this.searchInput.placeholder=this.placeholder)}buildSuggestions(){let e=this.selectElement.querySelectorAll("option");for(let t=0;t{this.keyboardNavigation||(this.removeActiveSelection(),i.querySelector("a").classList.add(...ACTIVE_CLASSES))}),l.addEventListener("mousemove",e=>{this.keyboardNavigation=!1}),l.addEventListener("click",e=>{e.preventDefault(),this.addItem(l.innerText,l.getAttribute(VALUE_ATTRIBUTE)),this.resetSearchInput(),this.hideSuggestions()})}}resetSearchInput(){this.searchInput.value="",this.adjustWidth()}getSelectedValues(){let e=this.selectElement.querySelectorAll("option:checked");return Array.from(e).map(e=>e.value)}showSuggestions(){this.dropElement.classList.contains("show")||this.dropElement.classList.add("show"),this.dropElement.style.left=this.searchInput.offsetLeft+"px";let e=this.searchInput.value.toLocaleLowerCase(),t=this.getSelectedValues(),s=this.dropElement.querySelectorAll("li"),i=!1,l=null,n=!1;for(let r=0;r',i.classList.add("pe-4")),i.innerHTML=s,this.containerElement.insertBefore(i,this.searchInput),this.allowClear&&i.querySelector("button").addEventListener("click",e=>{this.removeItem(t)});let l=this.selectElement.querySelector('option[value="'+t+'"]');l?l.setAttribute("selected","selected"):(l=document.createElement("option"),l.value=t,l.innerText=e,l.setAttribute("selected","selected"),this.selectElement.appendChild(l))}removeItem(e){let t=this.containerElement.querySelector("span["+VALUE_ATTRIBUTE+'="'+e+'"]');if(!t)return;t.remove();let s=this.selectElement.querySelector('option[value="'+e+'"]');s&&s.removeAttribute("selected")}}export default Tags; \ No newline at end of file +const ACTIVE_CLASS="is-active",ACTIVE_CLASSES=["is-active","bg-primary","text-white"],VALUE_ATTRIBUTE="data-value";class Tags{constructor(e){this.selectElement=e,this.selectElement.style.display="none",this.placeholder=this.getPlaceholder(),this.allowNew=!!e.dataset.allowNew,this.showAllSuggestions=!!e.dataset.showAllSuggestions,this.allowClear=!!e.dataset.allowClear,this.suggestionsThreshold=e.dataset.suggestionsThreshold?parseInt(e.dataset.suggestionsThreshold):1,this.keyboardNavigation=!1,this.holderElement=document.createElement("div"),this.containerElement=document.createElement("div"),this.dropElement=document.createElement("ul"),this.searchInput=document.createElement("input"),this.holderElement.appendChild(this.containerElement),this.containerElement.appendChild(this.searchInput),this.holderElement.appendChild(this.dropElement),this.selectElement.parentNode.insertBefore(this.holderElement,this.selectElement.nextSibling),this.configureSearchInput(),this.configureHolderElement(),this.configureDropElement(),this.configureContainerElement(),this.buildSuggestions()}static init(e="select[multiple]"){let t=document.querySelectorAll(e);for(let e=0;e{this.keyboardNavigation=!1})}configureHolderElement(){this.holderElement.classList.add("form-control"),this.holderElement.classList.add("dropdown")}configureContainerElement(){this.containerElement.addEventListener("click",e=>{this.searchInput.focus()});let e=this.selectElement.querySelectorAll("option[selected]");for(let t=0;t{this.adjustWidth(),this.searchInput.value.length>=this.suggestionsThreshold?this.showSuggestions():this.hideSuggestions()}),this.searchInput.addEventListener("focus",e=>{this.searchInput.value.length>=this.suggestionsThreshold&&this.showSuggestions()}),this.searchInput.addEventListener("focusout",t=>{setTimeout(function(){e.hideSuggestions()},100)}),this.searchInput.addEventListener("keydown",e=>{let t=e.keyCode||e.key;switch(t){case 13:case"Enter":let s=this.getActiveSelection();s?(this.addItem(s.innerText,s.getAttribute(VALUE_ATTRIBUTE)),this.resetSearchInput(),this.hideSuggestions(),this.removeActiveSelection()):this.allowNew&&(this.addItem(this.searchInput.value),this.resetSearchInput(),this.hideSuggestions()),e.preventDefault();break;case 38:case"ArrowUp":e.preventDefault(),this.keyboardNavigation=!0;let i=this.moveSelectionUp();0==this.searchInput.value.length&&this.dropElement.classList.contains("show")&&!i&&this.hideSuggestions();break;case 40:case"ArrowDown":e.preventDefault(),this.keyboardNavigation=!0,this.moveSelectionDown(),0!=this.searchInput.value.length||this.dropElement.classList.contains("show")||this.showSuggestions();break;case 8:case"Backspace":0==this.searchInput.value.length&&(this.removeLastItem(),this.adjustWidth(),this.hideSuggestions())}})}moveSelectionUp(){let e=this.getActiveSelection();if(e){let t=e.parentNode;do{t=t.previousSibling}while(t&&"none"==t.style.display);return t?(e.classList.remove(...ACTIVE_CLASSES),t.querySelector("a").classList.add(...ACTIVE_CLASSES),t.scrollIntoView(!0),t):null}return null}moveSelectionDown(){let e=this.getActiveSelection();if(e){let t=e.parentNode;do{t=t.nextSibling}while(t&&"none"==t.style.display);return t?(e.classList.remove(...ACTIVE_CLASSES),t.querySelector("a").classList.add(...ACTIVE_CLASSES),t.scrollIntoView(!1),t):null}return null}adjustWidth(){this.searchInput.value?this.searchInput.size=this.searchInput.value.length+1:this.getSelectedValues().length?(this.searchInput.placeholder="",this.searchInput.size=1):(this.searchInput.size=this.placeholder.length,this.searchInput.placeholder=this.placeholder)}buildSuggestions(){let e=this.selectElement.querySelectorAll("option");for(let t=0;t{this.keyboardNavigation||(this.removeActiveSelection(),i.querySelector("a").classList.add(...ACTIVE_CLASSES))}),l.addEventListener("mousemove",e=>{this.keyboardNavigation=!1}),l.addEventListener("click",e=>{e.preventDefault(),this.addItem(l.innerText,l.getAttribute(VALUE_ATTRIBUTE)),this.resetSearchInput(),this.hideSuggestions()})}}resetSearchInput(){this.searchInput.value="",this.adjustWidth()}getSelectedValues(){let e=this.selectElement.querySelectorAll("option:checked");return Array.from(e).map(e=>e.value)}showSuggestions(){this.dropElement.classList.contains("show")||this.dropElement.classList.add("show"),this.dropElement.style.left=this.searchInput.offsetLeft+"px";let e=this.searchInput.value.toLocaleLowerCase(),t=this.getSelectedValues(),s=this.dropElement.querySelectorAll("li"),i=!1,l=null,n=!1;for(let r=0;r'+s),i.innerHTML=s,this.containerElement.insertBefore(i,this.searchInput),this.allowClear&&i.querySelector("button").addEventListener("click",e=>{this.removeItem(t)});let l=this.selectElement.querySelector('option[value="'+t+'"]');l?l.setAttribute("selected","selected"):(l=document.createElement("option"),l.value=t,l.innerText=e,l.setAttribute("selected","selected"),this.selectElement.appendChild(l))}removeItem(e){let t=this.containerElement.querySelector("span["+VALUE_ATTRIBUTE+'="'+e+'"]');if(!t)return;t.remove();let s=this.selectElement.querySelector('option[value="'+e+'"]');s&&s.removeAttribute("selected")}}export default Tags; \ No newline at end of file