Skip to content

alexpechkarev/alpinejs-multiselect

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

alpinejs-multiselect

Alpine.js MultiSelect component

Features

  • Configurable pre-selected option
  • Fast search
  • Configurable searching values
  • Custom template

Dependency

Alpine.js MultiSelect

Installation

Install Alpine.js.

The example uses Alpine's Focus plugin, this is optional.

Specify your select element, data-search attribute value used to match against the search string, ignoring upper/lower case differences.

<select style="display:none;" id="multSelect">
    <option value="te_1" data-search="Arsenal">Arsenal</option>
    <option value="te_2" data-search="Tottenham Hotspur Spurs">Spurs</option>
    <option value="te_3" data-search="Manchester City">Man City</option>
    ...
</select>

Initiate the Apline.js component, pre-selected options can be defined by initializing selected property with an array of values. elementId references the select element id defined above.

 <div class="w-full" x-data="alpineMuliSelect({selected:['te_1', 'te_2'], elementId:'multSelect'})">

Add the Alpine component code into your application.

document.addEventListener("alpine:init", () => {
   Alpine.data("alpineMuliSelect", (obj) => ({
       elementId: obj.elementId,
       options: [],
       selected: obj.selected,
       selectedElms: [],
       show: false,
       search: '',
       open() {
           this.show = true
       },
       close() {
           this.show = false
       },
       toggle() {
           this.show = !this.show
       },
       isOpen() {
           return this.show === true
       },
       
       // Initializing component 
       init() {
           const options = document.getElementById(this.elementId).options;
           for (let i = 0; i < options.length; i++) {

               this.options.push({
                   value:  options[i].value,
                   text:   options[i].innerText,
                   search: options[i].dataset.search,
                   selected: Object.values(this.selected).includes(options[i].value)
               });

               if (this.options[i].selected) {
                   this.selectedElms.push(this.options[i])
               }
           }

           // searching for the given value
           this.$watch("search", (e => {
               this.options = []
               const options = document.getElementById(this.elementId).options;
               Object.values(options).filter((el) => {
                   var reg = new RegExp(this.search, 'gi');
                   return el.dataset.search.match(reg)
               }).forEach((el) => {
                   let newel = {
                       value: el.value,
                       text: el.innerText,
                       search: el.dataset.search,
                       selected: Object.values(this.selected).includes(el.value)
                   }
                   this.options.push(newel);
               })
           }));
       },
       // clear search field
       clear() {
           this.search = ''
       },
       // deselect selected options
       deselect() {
           setTimeout(() => {
               this.selected = []
               this.selectedElms = []
               Object.keys(this.options).forEach((key) => {
                   this.options[key].selected = false;
               })
           }, 100)
       },
       // select given option
       select(index, event) {
           if (!this.options[index].selected) {
               this.options[index].selected = true;
               this.options[index].element = event.target;
               this.selected.push(this.options[index].value);
               this.selectedElms.push(this.options[index]);

           } else {
               this.selected.splice(this.selected.lastIndexOf(index), 1);
               this.options[index].selected = false
               Object.keys(this.selectedElms).forEach((key) => {
                   if (this.selectedElms[key].value == this.options[index].value) {
                       setTimeout(() => {
                           this.selectedElms.splice(key, 1)
                       }, 100)
                   }
               })
           }
       },
       // remove from selected option
       remove(index, option) {
           this.selectedElms.splice(index, 1);
           Object.keys(this.selected).forEach((skey) => {
               if (this.selected[skey] == option.value) {
                   this.selected.splice(skey, 1);
               }
           });            
           Object.keys(this.options).forEach((key) => {
               if (this.options[key].value == option.value) {
                   this.options[key].selected = false;
               }
           });
       },
       // filter out selected elements
       selectedElements() {
           return this.options.filter(op => op.selected === true)
       },
       // get selected values
       selectedValues() {
           return this.options.filter(op => op.selected === true).map(el => el.value)
       }
   }));
});

Support


Please open an issue on GitHub

Licence


Released under the MIT Licence. See the bundled LICENCE file for details.

About

Alpine.js multi select component

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published