tail-select-rails 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,11 +0,0 @@
1
- /**
2
- * tail.select - The vanilla JavaScript solution to make your <select> fields awesome!
3
- *
4
- * @author Ciprian Popescu <getbutterfly@gmail.com>
5
- * @version 1.0.2
6
- * @url https://getbutterfly.com/tail-select/
7
- * @github https://github.com/wolffe/tail.select.js
8
- * @license MIT License
9
- * @copyright Copyright 2020 - 2024 Ciprian Popescu <getbutterfly@gmail.com>
10
- */
11
- const tail={select:function(selector,options={}){const defaultOptions={multiTags:!1,multiCounter:!0,theme:"light",classNames:"tail-default",strings:{all:"All",none:"None",placeholder:"Select an option...",search:"Type in to search..."}},opts={...defaultOptions,...options},{multiTags:multiTags,multiCounter:multiCounter,theme:theme,classNames:classNames,strings:strings}=opts,originalSelects=document.querySelectorAll(selector);originalSelects.forEach(originalSelect=>{originalSelect.style.display="none";const customDropdown=document.createElement("div");customDropdown.classList.add("tail-select"),customDropdown.classList.add(originalSelect.id),customDropdown.classList.add(opts.classNames),customDropdown.dataset.theme=`tail-theme--${opts.theme}`,originalSelect.multiple?customDropdown.classList.add("tail--multiple"):customDropdown.classList.add("tail--single");const searchInput=document.createElement("input");searchInput.type="text",searchInput.classList.add("tail--search"),searchInput.placeholder=strings.placeholder||"Select an option...",searchInput.addEventListener("focus",()=>{searchInput.placeholder=strings.search||"Type in to search..."}),searchInput.addEventListener("blur",()=>{searchInput.placeholder=strings.placeholder||"Select an option..."}),searchInput.addEventListener("input",()=>filterOptions(originalSelect,searchInput));const tailFloatingToolbar=document.createElement("div");tailFloatingToolbar.classList.add("tail--toolbar");const toggleAllCheckbox=document.createElement("input");toggleAllCheckbox.type="checkbox",toggleAllCheckbox.value=strings.all||"All",toggleAllCheckbox.addEventListener("change",()=>toggleAll(originalSelect,toggleAllCheckbox));const toggleAllLabel=document.createElement("label");toggleAllLabel.textContent=strings.all||"All",toggleAllLabel.classList.add("all"),toggleAllLabel.appendChild(toggleAllCheckbox);const uncheckAllButton=document.createElement("button");if(uncheckAllButton.type="button",uncheckAllButton.textContent=strings.none||"None",uncheckAllButton.classList.add("uncheck"),uncheckAllButton.addEventListener("click",()=>uncheckAll(originalSelect)),opts.multiCounter){const counter=document.createElement("span");counter.textContent="0",counter.classList.add("tail--counter"),customDropdown.appendChild(counter)}const nestedList=document.createElement("div");nestedList.classList.add("tail--nested-dropdown"),nestedList.style.display="none",customDropdown.appendChild(searchInput),customDropdown.appendChild(tailFloatingToolbar),customDropdown.appendChild(nestedList),tailFloatingToolbar.appendChild(toggleAllLabel),tailFloatingToolbar.appendChild(uncheckAllButton),originalSelect.insertAdjacentElement("afterend",customDropdown);const selectedOptionsList=document.createElement("ul");function buildNestedList(){const fragment=document.createDocumentFragment(),optgroups=originalSelect.getElementsByTagName("optgroup");if(optgroups.length>0)for(let i=0;i<optgroups.length;i++){const optgroup=optgroups[i],optgroupItem=document.createElement("div");optgroupItem.classList.add("tail--optgroup");const optgroupLabel=document.createElement("label"),optgroupCheckbox=document.createElement("input");optgroupCheckbox.type="checkbox",optgroupCheckbox.value=optgroup.label,optgroupCheckbox.addEventListener("change",()=>toggleOptgroup(optgroupCheckbox)),optgroupLabel.appendChild(optgroupCheckbox);const optgroupLabelText=document.createElement("span");optgroupLabelText.textContent=optgroup.label,optgroupLabelText.classList.add("tail--optgroup-label"),optgroupLabel.appendChild(optgroupLabelText),optgroupItem.appendChild(optgroupLabel);const nestedOptionsList=document.createElement("div");nestedOptionsList.setAttribute("role","listbox"),nestedOptionsList.classList.add("tail--nested-dropdown-list");const options=optgroup.getElementsByTagName("option");for(let j=0;j<options.length;j++){const option=options[j],optionItem=document.createElement("div");optionItem.classList.add("tail--nested-dropdown-item");const optionCheckbox=document.createElement("input");optionCheckbox.type="checkbox",optionCheckbox.value=option.textContent;const optionLabel=document.createElement("label"),optionLabelText=document.createElement("span");optionLabelText.textContent=option.textContent,option.dataset.description&&(optionLabelText.innerHTML+=`<small>${option.dataset.description}</small>`),option.selected&&option.hasAttribute("selected")&&(optionCheckbox.checked=!0,updateCounter(originalSelect),updateCustomTextInput(originalSelect)),optionLabel.appendChild(optionCheckbox),optionLabel.appendChild(optionLabelText),optionItem.appendChild(optionLabel),nestedOptionsList.appendChild(optionItem)}optgroupItem.appendChild(nestedOptionsList),nestedList.appendChild(optgroupItem)}else{const options=originalSelect.getElementsByTagName("option");for(let j=0;j<options.length;j++){const option=options[j],optionItem=document.createElement("div");optionItem.classList.add("tail--nested-dropdown-item");const optionCheckbox=document.createElement("input");optionCheckbox.type="checkbox",optionCheckbox.value=option.textContent;const optionLabel=document.createElement("label"),optionLabelText=document.createElement("span");optionLabelText.textContent=option.textContent,option.dataset.description&&(optionLabelText.innerHTML+=`<small>${option.dataset.description}</small>`),option.selected&&option.hasAttribute("selected")&&(optionCheckbox.checked=!0,updateCounter(originalSelect),updateCustomTextInput(originalSelect)),optionLabel.appendChild(optionCheckbox),optionLabel.appendChild(optionLabelText),optionItem.appendChild(optionLabel),nestedList.appendChild(optionItem)}}customDropdown.setAttribute("role","combobox"),customDropdown.setAttribute("aria-haspopup","true"),customDropdown.setAttribute("aria-expanded","false"),attachOptionCheckboxListeners(),nestedList.appendChild(fragment)}function toggleAll(originalSelect,toggleAllCheckbox){const isChecked=toggleAllCheckbox.checked,optionCheckboxes=nestedList.querySelectorAll('input[type="checkbox"]');optionCheckboxes.forEach(checkbox=>{checkbox.checked=isChecked,updateOriginalOptionState(originalSelect,checkbox)})}function uncheckAll(originalSelect){const optionCheckboxes=nestedList.querySelectorAll('input[type="checkbox"]');optionCheckboxes.forEach(checkbox=>{checkbox.checked=!1,updateOriginalOptionState(originalSelect,checkbox)});const originalOptions=originalSelect.getElementsByTagName("option");for(let i=0;i<originalOptions.length;i++)originalOptions[i].selected=!1}function toggleOption(checkbox){if(originalSelect.multiple)updateOriginalOptionState(originalSelect,checkbox);else{const optionCheckboxes=nestedList.querySelectorAll('.tail--nested-dropdown-item input[type="checkbox"]');optionCheckboxes.forEach(cb=>cb.checked=!1),checkbox.checked=!0,updateOriginalOptionState(originalSelect,checkbox)}}function toggleOptgroup(optgroupCheckbox){const isChecked=optgroupCheckbox.checked,nestedOptionsList=optgroupCheckbox.closest(".tail--optgroup").querySelector(".tail--nested-dropdown-list"),optionCheckboxes=nestedOptionsList.querySelectorAll('input[type="checkbox"]');if(optionCheckboxes.forEach(checkbox=>{checkbox.checked=isChecked,toggleOption(checkbox)}),!originalSelect.multiple){const customDropdown=originalSelect.closest(".tail-select");if(customDropdown){const otherOptgroupCheckboxes=customDropdown.querySelectorAll('.tail--nested-dropdown-item input[type="checkbox"]');otherOptgroupCheckboxes.forEach(cb=>{cb!==optgroupCheckbox&&(cb.checked=!1,updateOriginalOptionState(originalSelect,cb))})}}updateOriginalOptionState(originalSelect,optgroupCheckbox)}function attachOptionCheckboxListeners(){const optionCheckboxes=nestedList.querySelectorAll('.tail--nested-dropdown-item input[type="checkbox"]');optionCheckboxes.forEach(checkbox=>{checkbox.addEventListener("change",()=>toggleOption(checkbox))})}function updateOriginalOptionState(originalSelect,checkbox,customDropdown){const optionValue=checkbox.value,option=Array.from(originalSelect.options).find(opt=>opt.value===optionValue||opt.textContent===optionValue);if(option){checkbox.checked?option.selected=!0:option.selected=!1;const event=new Event("change",{bubbles:!0});originalSelect.dispatchEvent(event)}const selectedOptions=Array.from(originalSelect.options).filter(opt=>opt.selected);originalSelect.multiple?searchInput.value=selectedOptions.map(opt=>opt.textContent).join(", "):selectedOptions.length>0&&searchInput?searchInput.value=selectedOptions[0].textContent:searchInput.value="",opts.multiTags&&originalSelect.multiple&&updateSelectedOptionsList(selectedOptionsList,selectedOptions);const selectedValues=selectedOptions.map(opt=>opt.value);for(var options=originalSelect.options,count=0,i=0;i<options.length;i++)options[i].selected&&count++;if(opts.multiCounter){let customId=originalSelect.id;if(customId){let counterElement=document.querySelector(`.${customId}`).querySelector(".tail--counter");counterElement&&(counterElement.textContent=count)}}}function filterOptions(originalSelect,searchInput){const searchTerm=searchInput.value.trim().toLowerCase(),optionItems=nestedList.querySelectorAll("div");optionItems.forEach(optionItem=>{const optionCheckbox=optionItem.querySelector('input[type="checkbox"]'),optionLabel=optionCheckbox.nextElementSibling.textContent.toLowerCase(),optgroupItem=optionItem.closest("div");optionCheckbox.style.display=optionLabel.includes(searchTerm)?"inline-block":"none"}),optionItems.forEach(optionItem=>{const optionCheckbox=optionItem.querySelector('input[type="checkbox"]'),optgroupItem=optionItem.closest("div"),nestedCheckboxes=optionItem.querySelectorAll('div input[type="checkbox"]:not([style="display: none;"])'),hasVisibleNestedCheckboxes=nestedCheckboxes.length>0;optgroupItem.style.display="inline-block"===optionCheckbox.style.display||hasVisibleNestedCheckboxes?"block":"none"})}function updateSelectedOptionsList(selectedOptionsList,selectedOptions){selectedOptionsList.innerHTML="",selectedOptions.forEach(opt=>{const listItem=document.createElement("li");listItem.textContent=opt.textContent,selectedOptionsList.appendChild(listItem)})}function updateCustomTextInput(originalSelect){const selectedOptions=Array.from(originalSelect.options).filter(opt=>opt.selected&&opt.hasAttribute("selected"));originalSelect.multiple?searchInput.value=selectedOptions.map(opt=>opt.textContent).join(", "):selectedOptions.length>0&&searchInput?searchInput.value=selectedOptions[0].textContent:searchInput.value="",opts.multiTags&&originalSelect.multiple&&updateSelectedOptionsList(selectedOptionsList,selectedOptions)}function updateCounter(originalSelect){let customId=originalSelect.id;if(customId){let counterElement=document.querySelector(`.${customId}`).querySelector(".tail--counter");if(counterElement){const count=Array.from(originalSelect.options).filter(opt=>opt.selected).length;counterElement.textContent=count}}}function toggleDropdownVisibility(){nestedList.style.display="block",customDropdown.setAttribute("aria-expanded","true")}function hideDropdown(){nestedList.style.display="none",customDropdown.setAttribute("aria-expanded","false")}function handleClickOutside(event){customDropdown.contains(event.target)||hideDropdown()}function handleKeyDown(event){"Escape"===event.key&&hideDropdown()}selectedOptionsList.classList.add("tail--selected-options-list"),opts.multiTags&&originalSelect.multiple&&customDropdown.insertAdjacentElement("afterend",selectedOptionsList),searchInput.addEventListener("focus",toggleDropdownVisibility),document.addEventListener("click",handleClickOutside),document.addEventListener("keydown",handleKeyDown),buildNestedList()})}};