1class EticeoDualListBox{constructor(selectId,containerId,name,titleContent,titleSelected){this.selectElement=document.getElementById(selectId);this.containerElement=document.getElementById(containerId);this.name=name;this.titleContent=titleContent;this.titleSelected=titleSelected;this.init()} 2init(){this.createLayout();this.populateContentContainer();this.bindEvents()} 3createLayout(){this.container=document.createElement('div');this.container.className='container-dual-list-box';const contentWrapper=document.createElement('div');contentWrapper.className='content-wrapper';const contentTitle=document.createElement('h5');contentTitle.innerHTML=`${this.titleContent} (<span id="${this.name}-content-count">0</span>)`;contentWrapper.appendChild(contentTitle);this.contentContainer=document.createElement('div');this.contentContainer.className='content-container';contentWrapper.appendChild(this.contentContainer);const selectedWrapper=document.createElement('div');selectedWrapper.className='selected-wrapper';const selectedTitle=document.createElement('h5');selectedTitle.innerHTML=`${this.titleSelected} (<span id="${this.name}-selected-count">0</span>)`;selectedWrapper.appendChild(selectedTitle);this.selectedContainer=document.createElement('div');this.selectedContainer.className='selected-container';selectedWrapper.appendChild(this.selectedContainer);this.buttonsContainer=document.createElement('div');this.buttonsContainer.className='buttons-container';this.searchBar=document.createElement('input');this.searchBar.type='text';this.searchBar.className='search-bar form-control';this.searchBar.placeholder='Recherche';this.contentContainer.appendChild(this.searchBar);this.addButton=document.createElement('button');this.addButton.innerHTML='<i class="fas fa-arrow-right"></i>';this.addButton.className='btn btn-primary btn-sm';this.addButton.type='button';this.removeButton=document.createElement('button');this.removeButton.innerHTML='<i class="fas fa-arrow-left"></i>';this.removeButton.className='btn btn-danger btn-sm';this.removeButton.type='button';this.buttonsContainer.appendChild(this.addButton);this.buttonsContainer.appendChild(this.removeButton);this.container.appendChild(contentWrapper);this.container.appendChild(this.buttonsContainer);this.container.appendChild(selectedWrapper);this.containerElement.appendChild(this.container);this.hiddenInput=document.createElement('input');this.hiddenInput.type='hidden';this.hiddenInput.name=this.name;this.containerElement.appendChild(this.hiddenInput)} 4populateContentContainer(){const options=Array.from(this.selectElement.options);options.forEach(option=>{const itemDiv=document.createElement('div');itemDiv.className='item';itemDiv.textContent=option.textContent;itemDiv.dataset.value=option.value;if(option.selected){itemDiv.classList.add('selected-item');this.selectedContainer.appendChild(itemDiv)}else{this.contentContainer.appendChild(itemDiv)}});this.updateHiddenInput()} 5bindEvents(){this.searchBar.addEventListener('input',()=>{const filter=this.searchBar.value.toLowerCase();const items=this.contentContainer.querySelectorAll('.item');items.forEach(item=>{const text=item.textContent.toLowerCase();item.style.display=text.includes(filter)?'':'none'})});const disableOtherContainer=(currentContainer,otherContainer)=>{const items=otherContainer.querySelectorAll('.selected');items.forEach(item=>item.classList.remove('selected'));otherContainer.style.pointerEvents='none'};const enableBothContainers=()=>{this.contentContainer.style.pointerEvents='auto';this.selectedContainer.style.pointerEvents='auto'};this.contentContainer.addEventListener('click',event=>{if(event.target.classList.contains('item')){event.target.classList.toggle('selected');if(event.target.classList.contains('selected')){disableOtherContainer(this.contentContainer,this.selectedContainer);this.updateHiddenInput()}else{enableBothContainers();this.updateHiddenInput()}}});this.selectedContainer.addEventListener('click',event=>{if(event.target.classList.contains('selected-item')){event.target.classList.toggle('selected');if(event.target.classList.contains('selected')){disableOtherContainer(this.selectedContainer,this.contentContainer);this.updateHiddenInput()}else{enableBothContainers();this.updateHiddenInput()}}});this.addButton.addEventListener('click',()=>{const selectedItems=this.contentContainer.querySelectorAll('.item.selected');
5selectedItems.forEach(itemDiv=>{itemDiv.classList.remove('selected');itemDiv.classList.remove('item');itemDiv.classList.add('selected-item');this.selectedContainer.appendChild(itemDiv)});enableBothContainers();this.updateHiddenInput()});this.removeButton.addEventListener('click',()=>{const selectedItems=this.selectedContainer.querySelectorAll('.selected-item.selected');selectedItems.forEach(itemDiv=>{itemDiv.classList.remove('selected');itemDiv.classList.remove('selected-item');itemDiv.classList.add('item');this.contentContainer.appendChild(itemDiv)});enableBothContainers();this.updateHiddenInput()})} 6updateHiddenInput(){const selectedValues=Array.from(this.selectedContainer.querySelectorAll('.selected-item')).map(item=>item.dataset.value);this.hiddenInput.value=selectedValues.join(',');const contentCount=this.contentContainer.querySelectorAll('.item').length;const selectedCount=this.selectedContainer.querySelectorAll('.selected-item').length;document.getElementById(`${this.name}-content-count`).textContent=contentCount;document.getElementById(`${this.name}-selected-count`).textContent=selectedCount} 7getSelectedValues(){return this.hiddenInput.value.split(',')}}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.