From 98287b377532ecd960ec960f09891f9f52a0843a Mon Sep 17 00:00:00 2001 From: Thomas Date: Fri, 20 Aug 2021 15:39:21 +0200 Subject: [PATCH] don't use scrollIntoView --- package.json | 2 +- tags.js | 10 +++++++--- tags.min.js | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 82584d8..acb415c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bootstrap5-tags", - "version": "1.1.3", + "version": "1.1.4", "description": "Replace select[multiple] with nices badges", "main": "bootstrap5-tags", "scripts": { diff --git a/tags.js b/tags.js index 7305163..6316ebf 100644 --- a/tags.js +++ b/tags.js @@ -214,7 +214,8 @@ class Tags { } active.classList.remove(...ACTIVE_CLASSES); prev.querySelector("a").classList.add(...ACTIVE_CLASSES); - prev.scrollIntoView(true); + // Don't use scrollIntoView as it scrolls the whole window + prev.parentNode.scrollTop = prev.offsetTop - prev.parentNode.offsetTop; return prev; } return null; @@ -235,7 +236,10 @@ class Tags { } active.classList.remove(...ACTIVE_CLASSES); next.querySelector("a").classList.add(...ACTIVE_CLASSES); - next.scrollIntoView(false); + // This is the equivalent of scrollIntoView(false) but only for parent node + if (next.offsetTop > next.parentNode.offsetHeight - next.offsetHeight) { + next.parentNode.scrollTop += next.offsetHeight; + } return next; } return null; @@ -376,7 +380,7 @@ class Tags { this.holderElement.classList.remove("is-invalid"); } firstItem.querySelector("a").classList.add(...ACTIVE_CLASSES); - firstItem.scrollIntoView(); + firstItem.parentNode.scrollTop = firstItem.offsetTop - firstItem.parentNode.offsetTop; } else { // No item and we don't allow new items => error if (!this.allowNew && !(search.length === 0 && !hasPossibleValues)) { diff --git a/tags.min.js b/tags.min.js index 7f67bb6..1c9fbd6 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.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 +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.parentNode.scrollTop=t.offsetTop-t.parentNode.offsetTop,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.offsetTop>t.parentNode.offsetHeight-t.offsetHeight&&(t.parentNode.scrollTop+=t.offsetHeight),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 o=0;o'+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