Skip to content

About

Alpine.js multi select component

Topics

Resources

Stars

84 stars

Watchers

4 watching

Forks

Latest commit

 

History

14 Commits

Folders and files

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

Stars

84 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages