-
-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathautocomplete.min.js
9 lines (9 loc) · 12.8 KB
/
autocomplete.min.js
1
2
3
4
5
6
7
8
9
var S={showAllSuggestions:!1,suggestionsThreshold:1,maximumItems:0,autoselectFirst:!0,ignoreEnter:!1,tabSelect:!1,updateOnSelect:!1,highlightTyped:!1,highlightClass:"",fullWidth:!1,fixed:!1,fuzzy:!1,startsWith:!1,fillIn:!1,preventBrowserAutocomplete:!1,itemClass:"",activeClasses:["bg-primary","text-white"],labelField:"label",valueField:"value",searchFields:["label"],queryParam:"query",items:[],source:null,hiddenInput:!1,hiddenValue:"",clearControl:"",datalist:"",server:"",serverMethod:"GET",serverParams:{},serverDataKey:"data",fetchOptions:{},liveServer:!1,noCache:!0,debounceTime:300,notFoundMessage:"",onRenderItem:(a,t,e)=>t,onSelectItem:(a,t)=>{},onClearItem:(a,t)=>{},onServerResponse:(a,t)=>a.json(),onServerError:(a,t,e)=>{a.name==="AbortError"||t.aborted||console.error(a)},onChange:(a,t)=>{},onBeforeFetch:a=>{},onAfterFetch:a=>{}},L="is-loading",E="is-active",d="show",f="next",p="prev",m=new WeakMap,A=0,g=0;function x(a,t=300){let e;return(...s)=>{clearTimeout(e),e=setTimeout(()=>{a.apply(this,s)},t)}}function T(a){return a.normalize("NFD").replace(/[\u0300-\u036f]/g,"")}function v(a){return a?T(a.toString()).toLowerCase():""}function k(a,t){if(a.indexOf(t)>=0)return!0;let e=0;for(let s=0;s<t.length;s++){let i=t[s];if(i!=" "&&(e=a.indexOf(i,e)+1,e<=0))return!1}return!0}function C(a,t){return a.parentNode.insertBefore(t,a.nextSibling)}function I(a){var t=document.createElement("textarea");return t.innerHTML=a,t.value}function b(a,t){for(let[e,s]of Object.entries(t))a.setAttribute(e,s)}function O(a){a.ariaLabel=a.innerText,a.innerHTML=a.innerText.split("").map(t=>t+"‍").join("")}function D(a,t="window"){return a.split(".").reduce((e,s)=>e[s],t)}var y=class{constructor(t,e={}){if(!(t instanceof HTMLElement)){console.error("Invalid element",t);return}m.set(t,this),A++,g++,this.s=t,this.E(e),this.r=!1,this.u=!1,this.h=!1,this.A=x(()=>{this.g(!0)},this.e.debounceTime),this.C(),this.T(),this.e.fixed&&(document.addEventListener("scroll",this,!0),window.addEventListener("resize",this));let s=this.v();s&&s.addEventListener("click",this),["focus","change","blur","input","keydown"].forEach(i=>{this.s.addEventListener(i,this)}),["mousemove","mouseenter","mouseleave"].forEach(i=>{this.i.addEventListener(i,this)}),this.k()}static init(t="input.autocomplete",e={}){document.querySelectorAll(t).forEach(i=>{this.getOrCreateInstance(i,e)})}static getInstance(t){return m.has(t)?m.get(t):null}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,e)}dispose(){g--,["focus","change","blur","input","keydown"].forEach(e=>{this.s.removeEventListener(e,this)}),["mousemove","mouseenter","mouseleave"].forEach(e=>{this.i.removeEventListener(e,this)});let t=this.v();t&&t.removeEventListener("click",this),this.e.fixed&&g<=0&&(document.removeEventListener("scroll",this,!0),window.removeEventListener("resize",this)),this.i.parentElement.removeChild(this.i),m.delete(this.s)}v(){if(this.e.clearControl)return document.querySelector(this.e.clearControl)}handleEvent=t=>{["scroll","resize"].includes(t.type)?(this.b&&window.cancelAnimationFrame(this.b),this.b=window.requestAnimationFrame(()=>{this[`on${t.type}`](t)})):this[`on${t.type}`](t)};E(t={}){this.e=Object.assign({},S);let e={...t,...this.s.dataset},s=i=>["true","false","1","0",!0,!1].includes(i)&&!!JSON.parse(i);for(let[i,r]of Object.entries(S)){if(e[i]===void 0)continue;let n=e[i];switch(typeof r){case"number":this.e[i]=parseInt(n);break;case"boolean":this.e[i]=s(n);break;case"string":this.e[i]=n.toString();break;case"object":if(Array.isArray(r))if(typeof n=="string"){let o=n.includes("|")?"|":",";this.e[i]=n.split(o)}else this.e[i]=n;else this.e[i]=typeof n=="string"?JSON.parse(n):n;break;case"function":this.e[i]=typeof n=="string"?window[n]:n;break;default:this.e[i]=n;break}}}C(){if(this.s.autocomplete="off",this.s.spellcheck=!1,b(this.s,{"aria-autocomplete":"list","aria-haspopup":"menu","aria-expanded":"false",role:"combobox"}),this.s.id&&this.e.preventBrowserAutocomplete){let t=document.querySelector(`[for="${this.s.id}"]`);t&&O(t)}this.n=null,this.e.hiddenInput&&(this.n=document.createElement("input"),this.n.type="hidden",this.n.value=this.e.hiddenValue,this.n.name=this.s.name,this.s.name="_"+this.s.name,C(this.s,this.n))}T(){this.i=document.createElement("ul"),this.i.id="ac-menu-"+A,this.i.classList.add("dropdown-menu","autocomplete-menu","p-0"),this.i.style.maxHeight="280px",this.e.fullWidth||(this.i.style.maxWidth="360px"),this.e.fixed&&(this.i.style.position="fixed"),this.i.style.overflowY="auto",this.i.style.overscrollBehavior="contain",this.i.style.textAlign="unset",C(this.s,this.i),this.s.setAttribute("aria-controls",this.i.id)}onclick(t){t.target.matches(this.e.clearControl)&&this.clear()}oninput(t){this.u||(this.n&&(this.n.value=null),this.showOrSearch())}onchange(t){let e=this.s.value,s=this.a.find(i=>i.label===e);this.e.onChange(s,this)}onblur(t){let e=t.relatedTarget;if(this.r&&e&&(e.classList.contains("modal")||e.classList.contains("autocomplete-menu"))){this.s.focus();return}setTimeout(()=>{this.hideSuggestions()},100)}onfocus(t){this.showOrSearch()}onkeydown(t){switch(t.keyCode||t.key){case 13:case"Enter":if(this.isDropdownVisible()){let s=this.getSelection();s&&s.click(),(s||!this.e.ignoreEnter)&&t.preventDefault()}break;case 9:case"Tab":if(this.isDropdownVisible()&&this.e.tabSelect){let s=this.getSelection();s&&(s.click(),t.preventDefault())}break;case 38:case"ArrowUp":t.preventDefault(),this.h=!0,this.d(p);break;case 40:case"ArrowDown":t.preventDefault(),this.h=!0,this.isDropdownVisible()?this.d(f):this.showOrSearch(!1);break;case 27:case"Escape":this.isDropdownVisible()&&(this.s.focus(),this.hideSuggestions());break}}onmouseenter(t){this.r=!0}onmousemove(t){this.r=!0,this.h=!1}onmouseleave(t){this.r=!1,this.removeSelection()}onscroll(t){this.f()}onresize(t){this.f()}getConfig(t=null){return t!==null?this.e[t]:this.e}setConfig(t,e){this.e[t]=e}setData(t){this.a=[],this.l(t)}enable(){this.s.setAttribute("disabled","")}disable(){this.s.removeAttribute("disabled")}isDisabled(){return this.s.hasAttribute("disabled")||this.s.disabled||this.s.hasAttribute("readonly")}isDropdownVisible(){return this.i.classList.contains(d)}clear(){let t=this.s.value;this.s.value="",this.n&&(this.n.value=""),this.e.onClearItem(t,this)}getSelection(){return this.i.querySelector("a."+E)}removeSelection(){let t=this.getSelection();t&&t.classList.remove(...this.c())}c(){return[...this.e.activeClasses,E]}w(t){if(t.style.display==="none")return!1;let e=t.firstElementChild;return e.tagName==="A"&&!e.classList.contains("disabled")}d(t=f,e=null){let s=this.getSelection();if(s){let i=t===f?"nextSibling":"previousSibling";e=s.parentNode;do e=e[i];while(e&&!this.w(e));e?(s.classList.remove(...this.c()),t===p?e.parentNode.scrollTop=e.offsetTop-e.parentNode.offsetTop:e.offsetTop>e.parentNode.offsetHeight-e.offsetHeight&&(e.parentNode.scrollTop+=e.offsetHeight)):s&&(e=s.parentElement)}else{if(t===p)return e;if(!e)for(e=this.i.firstChild;e&&!this.w(e);)e=e.nextSibling}if(e){let i=e.querySelector("a");i.classList.add(...this.c()),this.s.setAttribute("aria-activedescendant",i.id),this.e.updateOnSelect&&(this.s.value=i.dataset.label)}else this.s.setAttribute("aria-activedescendant","");return e}I(){return this.isDisabled()?!1:this.s.value.length>=this.e.suggestionsThreshold}showOrSearch(t=!0){if(t&&!this.I()){this.hideSuggestions();return}this.e.liveServer?this.A():this.e.source?this.e.source(this.s.value,e=>{this.setData(e),this.m()}):this.m()}O(t){let e=this.p(),s=document.createElement("span");return e.append(s),s.classList.add("dropdown-header","text-truncate"),s.innerHTML=t,e}D(t,e){let s=e.label;if(this.e.highlightTyped){let n=v(s).indexOf(t);n!==-1&&(s=s.substring(0,n)+`<mark class="${this.e.highlightClass}">${s.substring(n,n+t.length)}</mark>`+s.substring(n+t.length,s.length))}s=this.e.onRenderItem(e,s,this);let i=this.p(),r=document.createElement("a");if(i.append(r),r.id=this.i.id+"-"+this.i.children.length,r.classList.add("dropdown-item","text-truncate"),this.e.itemClass&&r.classList.add(...this.e.itemClass.split(" ")),r.setAttribute("data-value",e.value),r.setAttribute("data-label",e.label),r.setAttribute("tabindex","-1"),r.setAttribute("role","menuitem"),r.setAttribute("href","#"),r.innerHTML=s,e.data)for(let[n,o]of Object.entries(e.data))r.dataset[n]=o;if(this.e.fillIn){let n=document.createElement("button");n.type="button",n.classList.add("btn","btn-link","border-0"),n.innerHTML=`<svg width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M2 2.5a.5.5 0 0 1 .5-.5h6a.5.5 0 0 1 0 1H3.707l10.147 10.146a.5.5 0 0 1-.708.708L3 3.707V8.5a.5.5 0 0 1-1 0z"/>
</svg>`,i.append(n),i.classList.add("d-flex","justify-content-between"),n.addEventListener("click",o=>{this.s.value=e.label,this.s.focus()})}return r.addEventListener("mouseenter",n=>{if(this.h||!this.r)return;this.removeSelection();let o=i.querySelector("a");o.classList.add(...this.c()),this.s.setAttribute("aria-activedescendant",o.id)}),r.addEventListener("mousedown",n=>{n.preventDefault()}),r.addEventListener("click",n=>{n.preventDefault(),this.u=!0,this.s.value=I(e.label),this.n&&(this.n.value=e.value),this.e.onSelectItem(e,this),this.hideSuggestions(),this.u=!1}),i}m(){if(document.activeElement!=this.s)return;let t=v(this.s.value);this.i.innerHTML="";let e=0,s=null,i=[];for(let r of this.a){let n=this.e.showAllSuggestions||t.length===0,o=t.length==0&&this.e.suggestionsThreshold===0;!n&&t.length>0&&this.e.searchFields.forEach(h=>{let c=v(r[h]),u=!1;if(this.e.fuzzy)u=k(c,t);else{let w=c.indexOf(t);u=this.e.startsWith?w===0:w>=0}u&&(o=!0)});let l=o||t.length===0;if(n||o){if(e++,r.group&&!i.includes(r.group)){let c=this.O(r.group);this.i.appendChild(c),i.push(r.group)}let h=this.D(t,r);if(!s&&l&&(s=h),this.i.appendChild(h),this.e.maximumItems>0&&e>=this.e.maximumItems)break}}if(s&&this.e.autoselectFirst&&(this.removeSelection(),this.d(f,s)),e===0)if(this.e.notFoundMessage){let r=this.p();r.innerHTML=`<span class="dropdown-item">${this.e.notFoundMessage}</span>`,this.i.appendChild(r),this.S()}else this.hideSuggestions();else this.S()}p(){let t=document.createElement("li");return t.setAttribute("role","presentation"),t}S(){this.i.classList.add(d),this.i.setAttribute("role","menu"),b(this.s,{"aria-expanded":"true"}),this.f()}toggleSuggestions(t=!0){this.i.classList.contains(d)?this.hideSuggestions():this.showOrSearch(t)}hideSuggestions(){this.i.classList.remove(d),b(this.s,{"aria-expanded":"false"}),this.removeSelection()}getInput(){return this.s}getDropMenu(){return this.i}f(){let t=window.getComputedStyle(this.s),e=this.s.getBoundingClientRect(),s=t.direction==="rtl",i=this.e.fullWidth,r=this.e.fixed,n=null,o=null;r&&(n=e.x,o=e.y+e.height,s&&!i&&(n-=this.i.offsetWidth-e.width)),this.i.style.transform="unset",i&&(this.i.style.width=this.s.offsetWidth+"px"),n!==null&&(this.i.style.left=n+"px"),o!==null&&(this.i.style.top=o+"px");let l=this.i.getBoundingClientRect(),h=window.innerHeight;if(l.y+l.height>h){let c=i?e.height+4:e.height;this.i.style.transform="translateY(calc(-100.1% - "+c+"px))"}}k(){this.a=[],this.l(this.e.items);let t=this.e.datalist;if(t){let e=document.querySelector(`#${t}`);if(e){let s=Array.from(e.children).map(i=>{let r=i.getAttribute("value")??i.innerHTML.toLowerCase(),n=i.innerHTML;return{value:r,label:n}});this.l(s)}else console.error(`Datalist not found ${t}`)}this.L(),this.e.server&&!this.e.liveServer&&this.g()}L(){if(this.e.hiddenInput&&!this.e.hiddenValue)for(let t of this.a)t.label==this.s.value&&(this.n.value=t.value)}M(t){if(Array.isArray(t))return t;let e=[];for(let[s,i]of Object.entries(t))e.push({value:s,label:i});return e}l(t){t=this.M(t);for(let e of t){if(e.group&&e.items){e.items.forEach(r=>r.group=e.group),this.l(e.items);continue}let s=typeof e=="string"?e:e.label,i=typeof e!="object"?{}:e;i.label=e[this.e.labelField]??s,i.value=e[this.e.valueField]??s,i.label&&this.a.push(i)}}g(t=!1){this.o&&this.o.abort(),this.o=new AbortController,this.e.onBeforeFetch(this);let e=this.s.dataset.serverParams||{};typeof e=="string"&&(e=JSON.parse(e));let s=Object.assign({},this.e.serverParams,e);s[this.e.queryParam]=this.s.value,this.e.noCache&&(s.t=Date.now()),s.related&&(Array.isArray(s.related)?s.related:[s.related]).forEach(l=>{let h=document.getElementById(l);if(h){let c=h.value,u=h.getAttribute("name");u&&(s[u]=c)}});let i=new URLSearchParams(s),r=this.e.server,n=Object.assign(this.e.fetchOptions,{method:this.e.serverMethod||"GET",signal:this.o.signal});n.method==="POST"?n.body=i:(r.indexOf("?")==-1?r+="?":r+="&",r+=i.toString()),this.s.classList.add(L),fetch(r,n).then(o=>this.e.onServerResponse(o,this)).then(o=>{let l=D(this.e.serverDataKey,o)||o;this.setData(l),this.L(),this.o=null,t&&this.m()}).catch(o=>{this.e.onServerError(o,this.o.signal,this)}).finally(o=>{this.s.classList.remove(L),this.e.onAfterFetch(this)})}},M=y;export{M as default};
/**
* Bootstrap 5 autocomplete
* https://github.com/lekoala/bootstrap5-autocomplete
* @license MIT
*/
//# sourceMappingURL=autocomplete.min.js.map