Multi-Select Dropdown With Checkboxes In JavaScript

Category: Form , Javascript , Recommended | November 11, 2022
Authoradmirhodzic
Last UpdateNovember 11, 2022
LicenseMIT
Views58,099 views
Multi-Select Dropdown With Checkboxes In JavaScript

multiselect-dropdown is a dependency-free vanilla JavaScript library that turns native <select multiple> elements into multi-select dropdowns with checkbox options, optional search, and a Select All control. Selected options appear as removable tags inside the generated control while the original select keeps the selected form values.

The script initializes automatically when the window loads and works from standard HTML <option> elements. HTML attributes handle the main per-select settings, and a small global configuration object controls shared labels, dimensions, and search-field styling.

Features:

  • Automatic enhancement of native <select multiple> elements.
  • Checkbox option list with removable selected tags.
  • Live text filtering for long option lists.
  • Select All control for the currently visible options.
  • Configurable selected-tag limit and placeholder text.
  • Native change events and selectedOptions state.
  • Dynamic option rebuilding through loadOptions().
  • Global labels, dimensions, padding, and search-field class settings.

How to Use It:

Load the JavaScript

Include multiselect-dropdown.js on the page. The script injects its default component styles into the document.

<script src="multiselect-dropdown.js"></script>

Basic Usage

Add the multiple attribute to a native <select>. The library finds every matching select on window load and creates the custom checkbox dropdown. An id is only needed when your own JavaScript must reference a specific select.

<select name="skills" id="skills" multiple>
  <option value="html">HTML</option>
  <option value="css" selected>CSS</option>
  <option value="javascript" selected>JavaScript</option>
  <option value="typescript">TypeScript</option>
</select>

Add Search and Select All

Set multiselect-search="true" to display the filter field. Add multiselect-select-all="true" when the dropdown also needs a Select All checkbox. A custom placeholder appears when the select has no selected options.

<select
  name="skills"
  id="skills"
  multiple
  multiselect-search="true"
  multiselect-select-all="true"
  multiselect-max-items="3"
  placeholder="Choose skills"
>
  <option value="html">HTML</option>
  <option value="css">CSS</option>
  <option value="javascript">JavaScript</option>
  <option value="typescript">TypeScript</option>
  <option value="react">React</option>
  <option value="vue">Vue</option>
</select>

Read Selected Values

Checkbox selections update the original <option> elements. Read selectedOptions from the native select when you need the current values.

const skillsSelect = document.getElementById('skills');
const selectedValues = Array.from(
  skillsSelect.selectedOptions,
  option => option.value
);
console.log(selectedValues);

Listen for Selection Changes

Each checkbox selection dispatches the native change event on the original select. A normal event listener can process the current values after every change.

const skillsSelect = document.getElementById('skills');
skillsSelect.addEventListener('change', function () {
  const values = Array.from(
    this.selectedOptions,
    option => option.value
  );
  console.log(values);
});

Replace Options Dynamically

Update the native option list first, then call loadOptions() on that select. The method rebuilds the generated checkbox list from the current <option> elements.

const skillsSelect = document.getElementById('skills');
skillsSelect.innerHTML = `
  <option value="react">React</option>
  <option value="vue">Vue</option>
  <option value="svelte">Svelte</option>
`;
skillsSelect.loadOptions();

HTML Configuration Attributes

Use these attributes directly on each <select multiple> element. They control behavior for that individual dropdown.

  • multiselect-search="true": Displays the search field and filters option labels as text is entered.
  • multiselect-select-all="true": Displays the Select All checkbox. When a search filter is active, it toggles the currently visible options.
  • multiselect-max-items="3": Sets the maximum number of individual selected tags shown in the control. The default limit is 5.
  • multiselect-hide-x="true": Hides the remove button inside selected tags. The remove button appears when this attribute is absent or set to another value.
  • placeholder="Choose skills": Sets the text shown when no option is selected. The fallback text is select.

Global JavaScript Options

Set window.MultiselectDropdownOptions before the window finishes loading when several multi-select controls should share the same labels or dimensions. The automatic initializer passes this object to every generated dropdown.

<script>
window.MultiselectDropdownOptions = {
  height: '12rem',
  placeholder: 'Choose options',
  txtSelected: 'chosen',
  txtAll: 'Select all',
  txtRemove: 'Remove',
  txtSearch: 'Filter',
  style: {
    width: '320px',
    padding: '4px 8px'
  },
  searchInput: {
    class: 'multiselect-filter'
  }
};
</script>
<script src="multiselect-dropdown.js"></script>
  • height: Sets the height of the generated option list. Default: 15rem.
  • placeholder: Sets the global fallback placeholder. Default: select.
  • txtSelected: Sets the text appended to the selected-item count. Default: selected.
  • txtAll: Sets the Select All label. Default: All.
  • txtRemove: Sets the title text for the selected-tag remove button. Default: Remove.
  • txtSearch: Sets the search input placeholder. Default: search.
  • style.width: Sets an inline width on every generated dropdown.
  • style.padding: Sets inline padding on every generated dropdown.
  • searchInput.class: Sets the class used on the generated search input. The fallback class is form-control.

Customize the Dropdown Styles

The script inserts a <style id="multiselect_dropdown_styles"> element and uses normal class names for the generated controls. Page CSS can target those generated elements. Place overriding rules after the injected defaults or use selectors with sufficient specificity.

.multiselect-dropdown {
  border-color: #94a3b8;
  border-radius: 8px;
}
.multiselect-dropdown-list-wrapper {
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.multiselect-dropdown span.optext {
  background-color: #e2e8f0;
}
.multiselect-dropdown-search {
  border: 1px solid #cbd5e1;
}

Alternatives & Related Resources:

FAQs:

Q: Why is the search field missing?
A: Add multiselect-search="true" to that <select multiple>. The global text settings change the search label, but the HTML attribute controls whether the field appears.

Q: Why does Select All only affect some options after a search?
A: Select All works on the option rows that remain visible after filtering. Options hidden by the current search keep their existing selected state.

Q: Can I change the option list after the dropdown has loaded?
A: Yes. Modify the native <option> elements, then call loadOptions() on that select to rebuild its generated list.

Q: Will the selected values submit with a normal HTML form?
A: The checkbox controls update the original select’s selected options. Keep the select’s name attribute when those values need to be included in form submission.

Q: Does the generated dropdown include ARIA and custom keyboard navigation?
A: The current script does not add ARIA roles or dedicated keyboard handlers to its generated dropdown elements. Projects with specific accessibility requirements should account for that behavior during component selection and testing.

Changelog:

11/12/2022

  • Fixed the Select All button behavior.

02/07/2022

  • Improved option handling.

02/03/2022

  • Added the ability to remove a selected option before opening the list.

You Might Be Interested In:


2 thoughts on “Multi-Select Dropdown With Checkboxes In JavaScript

  1. Joey Ireland

    How do you stop ios from having their native control take over ?

    Reply
  2. Mirko

    Hello, and thank you for the script! How can i put a select required? Thank you!

    Reply

Leave a Reply