├── README.md ├── dist └── x-selectpicker.js └── x-selectpicker-search.gif /README.md: -------------------------------------------------------------------------------- 1 | # X-Selectpicker 2 | 3 | X-Selectpicker is a simple selectpicker using the wonderful [Alpine.js](https://github.com/alpinejs/alpine) 4 | 5 | ## Install 6 | Add the following script to the end of your `` section. 7 | ```html 8 | 9 | ``` 10 | Make sure you have also installed [Alpine.js](https://github.com/alpinejs/alpine) as well. 11 | 12 | ## Usage 13 | 14 | Add the class `x-selectpicker` to any select element. Then you can fully customize the look and feel of your selectpicker by adding CSS classes to three HTML elements: the result div, the dropdown div, and each individual option div. 15 | 16 | In this example, I'm using [Tailwind CSS](https://tailwindcss.com/) to style my selectpicker: 17 | ```html 18 | 31 | ``` 32 | ![x-selectpicker-in-action](https://github.com/intellow/x-selectpicker/blob/master/x-selectpicker-search.gif "Sample Usage") 33 | 34 | 35 | ## Contributing 36 | Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. 37 | 38 | ## License 39 | [MIT](https://choosealicense.com/licenses/mit/) 40 | -------------------------------------------------------------------------------- /dist/x-selectpicker.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", function(){ 2 | // get the selects 3 | let selectpickers = document.getElementsByClassName('x-selectpicker'); 4 | 5 | Array.prototype.forEach.call(selectpickers, function(element, i) { 6 | createXselectpicker(element); 7 | }); 8 | }); 9 | 10 | 11 | function xSelectpicker(selected, placeholder, searchEnabled) { 12 | return { 13 | selected: selected, 14 | showOptions: false, 15 | placeholder: placeholder, 16 | searchEnabled: searchEnabled, 17 | search: '', 18 | newSelection(name, value) { 19 | this.placeholder = name; 20 | this.selected = value; 21 | this.showOptions = false; 22 | } 23 | } 24 | } 25 | 26 | function createXselectpicker(select) { 27 | // hide it 28 | select.classList.add('hidden'); 29 | let placeholder = "'Choose an Option'"; 30 | if(select.selectedIndex) { 31 | placeholder = "'" + select.options[select.selectedIndex].text + "'"; 32 | 33 | } else if(select.getAttribute('placeholder')) { 34 | placeholder = "'" + select.getAttribute('placeholder') + "'"; 35 | } 36 | 37 | let searchEnabled = false; 38 | if(select.getAttribute('search')) { 39 | searchEnabled = true; 40 | } 41 | // add a container to hold everything 42 | select.insertAdjacentHTML('beforebegin', '
'); 43 | let parent = document.getElementById(select.id +'_x_selectpicker_container'); 44 | // assign the classes on the select to the new parent 45 | let selectClasses = select.classList; 46 | Array.prototype.forEach.call(selectClasses, function(element, i) { 47 | if(element === 'hidden' || element === 'x-selectpicker') { 48 | // do nothing 49 | } else { 50 | parent.classList.add(element); 51 | } 52 | }); 53 | // put the original select element inside the new container 54 | parent.appendChild(select); 55 | 56 | // set x-model on select 57 | select.setAttribute('x-model', 'selected'); 58 | 59 | // create div to show selections 60 | parent.insertAdjacentHTML('beforeend', '
'); 61 | // create div to show options 62 | parent.insertAdjacentHTML('beforeend', '
'); 63 | 64 | let options = document.getElementById(select.id + '_options'); 65 | 66 | addOptions(select.id, ''); 67 | 68 | if (searchEnabled) { 69 | options.insertAdjacentHTML('afterbegin', ''); 70 | document.getElementById(select.id+'_selection').addEventListener("click", function () { 71 | setTimeout(() => { 72 | document.getElementById(select.id+'_search_input').focus(); 73 | }, 10); 74 | }); 75 | } 76 | } 77 | 78 | function updateOptionsTest(value, selectId) 79 | { 80 | hideOptions(selectId, value); 81 | } 82 | 83 | function hideOptions(selectId, searchText) 84 | { 85 | let selectpickerOptions = document.getElementById(selectId+'_options'); 86 | Array.prototype.forEach.call(selectpickerOptions.childNodes, function(element, i) { 87 | if(element.innerText.toLowerCase().includes(searchText.toLowerCase()) || element.id.includes('_search')) { 88 | element.removeAttribute('style'); 89 | } else { 90 | element.style.display = 'none'; 91 | } 92 | }); 93 | } 94 | 95 | function addOptions(selectId, searchText) 96 | { 97 | let originalSelect = document.getElementById(selectId); 98 | let selectOptions = originalSelect.options; 99 | let options = document.getElementById(selectId + '_options'); 100 | if(searchText.length > 0) { 101 | Array.prototype.forEach.call(selectOptions, function(element, i) { 102 | if(element.text.toLowerCase().includes(searchText.toLowerCase())) { 103 | options.insertAdjacentHTML('beforeend', '
' + element.text + '
'); 104 | } 105 | }); 106 | } else { 107 | Array.prototype.forEach.call(selectOptions, function(element, i) { 108 | options.insertAdjacentHTML('beforeend', '
' + element.text + '
'); 109 | }); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /x-selectpicker-search.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellow/x-selectpicker/307539259ff22675c734b3c9d06ed09a5c3a5b7f/x-selectpicker-search.gif --------------------------------------------------------------------------------