Created
October 13, 2025 07:43
-
-
Save croxton/6c4028fce4a9e744e6f49c720bdabf6b to your computer and use it in GitHub Desktop.
Vanilla Multi Select for htmx Booster Pack
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Multi Select | |
| * | |
| * Enhances <select multiple> | |
| */ | |
| import {Booster} from 'htmx-booster-pack'; | |
| import { multipleSelect } from 'multiple-select-vanilla'; | |
| import 'multiple-select-vanilla/dist/styles/css/multiple-select.css'; | |
| export default class MultiSelect extends Booster { | |
| ms = null; | |
| dirty = false; | |
| constructor(elm) { | |
| super(elm); | |
| this.mount(); | |
| } | |
| mount() { | |
| const elmMount = document.querySelector(this.elm); | |
| const form = elmMount.closest('form'); | |
| const submitBtn = form.querySelector('button[type="submit"]'); | |
| const label = elmMount.querySelector('label').textContent; | |
| this.options = { | |
| "showFilter": "false" | |
| }; | |
| const isMultiple = document.querySelector(this.elm + '> select').getAttribute('multiple') === 'multiple'; | |
| this.ms = multipleSelect(this.elm + '> select', { | |
| selectAll: false, | |
| filter: (this.options.showFilter === 'true'), | |
| filterPlaceholder: 'Search…', | |
| minimumCountSelected:0, | |
| renderOptionLabelAsHtml: true, | |
| showOkButton: true, | |
| placeholder: label, | |
| maxHeight: 252, | |
| formatCountSelected(count, total) { | |
| if (isMultiple) { | |
| return `${label} (${count})`; | |
| } | |
| }, | |
| formatAllSelected() { | |
| if (isMultiple) { | |
| return `${label} (All)`; | |
| } | |
| }, | |
| formatOkButton() { | |
| return 'Update'; | |
| }, | |
| onClick: () => { | |
| this.dirty = true; | |
| elmMount.classList.add('is-dirty'); | |
| }, | |
| onClose: (reason) => { | |
| if (this.dirty) { | |
| this.dirty = false; | |
| elmMount.classList.remove('is-dirty'); | |
| this.ms.focus(); | |
| form.dispatchEvent(new CustomEvent("updateResults")); | |
| } | |
| } | |
| }); | |
| } | |
| unmount() { | |
| this.ms?.destroy(); | |
| this.ms = null; // remove detached element | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment