jQuery Plugin For Multiple Select With Checkboxes - multi-select.js

File Size: 103 KB
Views Total: 158308
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
   
jQuery Plugin For Multiple Select With Checkboxes - multi-select.js

multi-select.js is a lightweight jQuery plugin that turns a native <select multiple> element into a dropdown with checkbox options.

It keeps the original select synchronized for form submission and includes optgroups, preset selections, custom templates, modal display, and keyboard navigation.

Features:

  • Checkbox dropdown generated from a native multiple select.
  • Original select value synchronization for form submission and change events.
  • Optgroup rendering with fieldset and legend markup.
  • Preset groups, including a select-all preset.
  • Keyboard controls for the trigger and option list.
  • ARIA expanded state on the dropdown trigger and native checkbox/radio semantics.
  • Custom HTML templates, labels, and state classes.
  • Optional modal backdrop.
  • Dropdown width and viewport-height handling for constrained layouts.
  • Disabled option state copied to the generated checkbox.

How to use it:

1. Load jQuery 3.x before jquery.multi-select.js.

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="/path/to/jquery.multi-select.js"></script>

2. Create a native multiple select.

<label for="languages">Select languages:</label>
<select id="languages" name="languages" multiple>
  <option value="JavaScript">JavaScript</option>
  <option value="C++">C++</option>
  <option value="Python">Python</option>
  <option value="Ruby">Ruby</option>
  <option value="PHP">PHP</option>
  <option value="Pascal">Pascal</option>
</select>

3. Initialize the checkbox dropdown.

$('#languages').multiSelect();

4. Style the generated dropdown. These selectors match the markup produced by the plugin.

.multi-select-container {
  display: inline-block;
  position: relative;
}

.multi-select-menu {
  position: absolute;
  left: 0;
  top: 0.8em;
  z-index: 1;
  float: left;
  min-width: 100%;
  background: #fff;
  margin: 1em 0;
  border: 1px solid #aaa;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
  display: none;
}

.multi-select-menuitem {
  display: block;
  font-size: 0.875em;
  padding: 0.6em 1em 0.6em 30px;
  white-space: nowrap;
}

.multi-select-legend {
  font-size: 0.875em;
  font-weight: bold;
  padding-left: 10px;
}

.multi-select-legend + .multi-select-menuitem {
  padding-top: 0.25rem;
}

.multi-select-menuitem + .multi-select-menuitem {
  padding-top: 0;
}

.multi-select-presets {
  border-bottom: 1px solid #ddd;
}

.multi-select-menuitem input {
  position: absolute;
  margin-top: 0.25em;
  margin-left: -20px;
}

.multi-select-button {
  display: inline-block;
  font-size: 0.875em;
  padding: 0.2em 0.6em;
  max-width: 16em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: -0.5em;
  background-color: #fff;
  border: 1px solid #aaa;
  border-radius: 4px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
  cursor: default;
}

.multi-select-button:after {
  content: "";
  display: inline-block;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 0.4em 0.4em 0 0.4em;
  border-color: #999 transparent transparent transparent;
  margin-left: 0.4em;
  vertical-align: 0.1em;
}

.multi-select-container--open .multi-select-menu {
  display: block;
}

.multi-select-container--open .multi-select-button:after {
  border-width: 0 0.4em 0.4em 0.4em;
  border-color: transparent transparent #999 transparent;
}

.multi-select-container--positioned .multi-select-menu {
  box-sizing: border-box;
}

.multi-select-container--positioned .multi-select-menu label {
  white-space: normal;
}

Optgroups:

Native <optgroup> elements become fieldsets with legends inside the generated menu.

<select id="skills" name="skills" multiple>
  <optgroup label="Frontend">
    <option value="html">HTML</option>
    <option value="css">CSS</option>
    <option value="js">JavaScript</option>
  </optgroup>
  <optgroup label="Backend">
    <option value="php">PHP</option>
    <option value="python">Python</option>
  </optgroup>
</select>
$('#skills').multiSelect();

Preset Selections:

The presets option adds radio-button shortcuts above the checkbox list. A preset can select every option or a specific set of option values.

$('#languages').multiSelect({
  presets: [
    {
      name: 'All languages',
      all: true
    },
    {
      name: 'Frontend',
      options: ['JavaScript']
    },
    {
      name: 'Backend',
      options: ['Python', 'Ruby', 'PHP']
    }
  ]
});

Modal Dropdown:

Set modalHTML to insert a backdrop element. A wrapper class can apply centered modal styles only to this instance.

<div class="modal-example">
  <select id="modal-languages" name="modal-languages" multiple>
    <option value="JavaScript">JavaScript</option>
    <option value="Python">Python</option>
    <option value="PHP">PHP</option>
  </select>
</div>
$('#modal-languages').multiSelect({
  modalHTML: '<div class="multi-select-modal">'
});
.modal-example .multi-select-menu {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  max-height: 50%;
  min-width: 0;
  overflow: auto;
  border: none;
  border-radius: 0.3em;
  box-shadow: 0 1em 3em rgba(0, 0, 0, 0.4);
}

.multi-select-modal {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1;
  background: rgba(0, 0, 0, 0.4);
  display: none;
}

.multi-select-container--open .multi-select-modal {
  display: block;
}

All Plugin Options:

Generated Markup:

Option Description
containerHTML Outer container template. Default: <div class="multi-select-container">.
menuHTML Dropdown menu template. Default: <div class="multi-select-menu">.
buttonHTML Dropdown trigger template. Default: <span class="multi-select-button">.
menuItemsHTML Wrapper for generated option items. Default: <div class="multi-select-menuitems">.
menuFieldsetHTML Fieldset template used for each native optgroup. Default: <fieldset class="multi-select-fieldset">.
menuFieldsetLegendHTML Legend template used for each native optgroup label. Default: <legend class="multi-select-legend">.
menuItemHTML Template for each checkbox or preset label. Default: <label class="multi-select-menuitem">.
presetsHTML Wrapper for preset controls. Default: <div class="multi-select-presets">.
modalHTML Optional backdrop template for modal display. Default: undefined.

Labels And Selection:

Option Description
activeClass Class applied while the menu is open. Default: multi-select-container--open.
noneText Trigger text when no option is selected. Default: -- Select --.
allText Trigger text when every option is selected. Default: undefined.
presets Array of preset definitions. Each preset uses a name plus either all: true or an options array. Default: undefined.

Menu Positioning:

Option Description
positionedMenuClass Class applied when the menu would extend beyond the right edge of positionMenuWithin. Default: multi-select-container--positioned.
positionMenuWithin jQuery object that defines the horizontal boundary used for menu-width adjustment. Default: undefined.
viewportBottomGutter Minimum preferred distance in pixels between the menu and the viewport bottom before a maximum height is applied. Default: 20.
menuMinHeight Minimum menu height in pixels used by the viewport-height calculation. Default: 200.

Related Multiple Select Resources:

Changelog:

2026-09-21

2024-09-30

  • Changed the menu role to group and removed redundant menu-item roles from checkbox and radio controls.

2024-08-14

  • Added aria-expanded state updates to the multi-select button.

2024-01-23

  • Changed optgroup markup to use fieldsets and legends.

2022-02-04

  • Removed for attributes from labels associated with the hidden original select.

2022-01-22

  • Close the menu when focus leaves the component.

2021-05-22

  • Changed deprecated selectors.

2021-03-24

  • Added a parameter for presets that select all options.

2020-01-30

  • Added optgroup support.

2019-07-05

  • Added Up/Down Arrow keyboard navigation.

2019-06-13

  • Added an option for a modal background element.

2017-11-28

  • Prevented long dropdowns from extending beyond the viewport.

2017-11-18

  • Limited each page to one open menu at a time.

2016-10-25

  • Added preset groups of option values.
  • Prevented duplicate button-content updates.

2016-10-14

  • Improved checkbox alignment in the menu.
  • Added namespaces to event listeners.

2016-10-05

  • Ignored surrounding whitespace when constructing the button label.

This awesome jQuery plugin is developed by mysociety. For more Advanced Usages, please check the demo page or visit the official website.