npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

bs5-multiselect

v1.0.0

Published

Bootstrap 5 multiselect dropdown with unlimited nesting, accordion groups, search, and jQuery .val() compatibility

Downloads

112

Readme

Bootstrap Multiselect

A jQuery plugin for Bootstrap 5 that transforms a <select multiple> into a searchable, nested dropdown with checkboxes, collapsible accordion groups, and unlimited nesting depth.

Features

  • Unlimited nesting depth (grandparent > parent > child > ...)
  • Collapsible accordion groups with expand/collapse all
  • Tri-state checkboxes (checked, unchecked, indeterminate)
  • Selecting a parent selects all children; selecting all children auto-checks the parent
  • Search/filter with debounced input
  • "Select all" with smart visible-only mode during search
  • Smart display text ("3 selected", "All selected")
  • Disabled options (individual or entire groups)
  • Parents can have their own values
  • Pre-select items via selected: true in data
  • Bootstrap 5.3 dark mode support (automatic via data-bs-theme)
  • Hidden native <select> stays in sync — $('#el').val() just works
  • No extra dependencies beyond jQuery and Bootstrap 5

Quickstart

1. Include dependencies

<!-- CSS -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="src/bootstrap-multiselect.css" rel="stylesheet">

<!-- JS -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<script src="src/bootstrap-multiselect.js"></script>

2. Add a select element

<select id="mySelect" multiple></select>

3. Initialize with JS data

$('#mySelect').multiselect({
    data: [
        {
            label: 'Group 1', value: 'grp1',
            children: [
                { label: 'Option A', value: 'a' },
                { label: 'Option B', value: 'b', selected: true },
                { label: 'Option C', value: 'c', disabled: true }
            ]
        },
        {
            label: 'Group 2', value: 'grp2', disabled: true,
            children: [
                { label: 'Option D', value: 'd' },
                { label: 'Option E', value: 'e' }
            ]
        },
        { label: 'Option F', value: 'f' }
    ]
});

Or initialize from HTML

<select id="mySelect" multiple>
    <optgroup label="Group 1">
        <option value="a">Option A</option>
        <option value="b" selected>Option B</option>
        <option value="c" disabled>Option C</option>
    </optgroup>
    <optgroup label="Group 2" disabled>
        <option value="d">Option D</option>
    </optgroup>
</select>

<script>
$('#mySelect').multiselect();
</script>

4. Read values

// Standard jQuery — returns array of selected values
$('#mySelect').val();

Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | data | Array\|null | null | JS data provider. Each item: { label, value?, children?, selected?, disabled? }. If null, parses from the <select> DOM. | | placeholder | string | 'Select...' | Text shown when nothing is selected. | | enableSearch | boolean | true | Show/hide the search input. | | searchPlaceholder | string | 'Search...' | Placeholder for the search input. | | selectAll | boolean | true | Show/hide the "Select all" checkbox. | | selectAllText | string | 'Select all' | Label for select-all. | | selectAllJustVisible | boolean | true | When searching, "Select all" only affects visible items. | | collapseAll | boolean | true | Start with all groups collapsed. | | maxHeight | number | 250 | Max height (px) of the scrollable options area. | | numberDisplayed | number | 3 | Max items to show as labels before switching to count text. | | nSelectedText | string | '# selected' | Text when count exceeds numberDisplayed. # is replaced with count. | | allSelectedText | string | 'All selected' | Text when everything is selected. Set to '' to disable. | | onChange | function\|null | null | Callback on selection change: function(selectedValues) {}. |

Methods

// Selection
$('#el').multiselect('select', 'value')         // Select by value (string or array)
$('#el').multiselect('deselect', 'value')        // Deselect by value
$('#el').multiselect('selectAll')                // Select all
$('#el').multiselect('deselectAll')              // Deselect all
$('#el').multiselect('getSelected')              // Get selected values array

// Expand / Collapse
$('#el').multiselect('expand')                   // Expand all groups
$('#el').multiselect('expand', 'groupValue')     // Expand specific group(s)
$('#el').multiselect('collapse')                 // Collapse all groups
$('#el').multiselect('collapse', 'groupValue')   // Collapse specific group(s)

// Enable / Disable
$('#el').multiselect('enable')                   // Enable widget
$('#el').multiselect('disable')                  // Disable widget
$('#el').multiselect('enableOptions', 'value')   // Enable specific option(s)
$('#el').multiselect('disableOptions', 'value')  // Disable specific option(s)

// Lifecycle
$('#el').multiselect('refresh')                  // Rebuild from data
$('#el').multiselect('destroy')                  // Remove widget, restore <select>

All methods that accept values take either a single string or an array of strings.

Dark Mode

The plugin automatically supports Bootstrap 5.3 dark mode. All colors use Bootstrap CSS variables that adapt when data-bs-theme="dark" is set on the <html> element.

// Toggle dark mode
document.documentElement.setAttribute('data-bs-theme', 'dark');

No extra CSS is required.

CSS Classes

All classes use the bsms- prefix. Override these to customize appearance.

| Class | Description | |-------|-------------| | .bsms-container | Root wrapper (position: relative; width: 100%) | | .bsms-display | Top bar / button (styled as form-select) | | .bsms-display-text | Selected items text (ellipsis overflow) | | .bsms-dropdown | Dropdown panel | | .bsms-search-wrap | Search input wrapper | | .bsms-search | Search <input> | | .bsms-select-all | Select-all row | | .bsms-expand-all | Expand/collapse all arrow | | .bsms-options | Scrollable options container | | .bsms-group | Group wrapper | | .bsms-group-header | Group header (arrow + checkbox + label) | | .bsms-arrow | Accordion arrow (.collapsed when closed) | | .bsms-group-children | Children container (.show when expanded) | | .bsms-leaf | Leaf option row (.selected when checked) | | .bsms-check | All checkboxes | | .bsms-disabled | Disabled option/group header | | .bsms-hidden | Hidden by search filter | | .bsms-no-results | "No results found" message |

Project Structure

bootstrap-multiselect/
  index.html                      # Demo page with live examples & full docs
  package.json                    # Project metadata
  src/
    bootstrap-multiselect.js      # jQuery plugin (source)
    bootstrap-multiselect.css     # Styles (source)
  dist/
    bootstrap-multiselect.js      # Unminified copy for distribution
    bootstrap-multiselect.min.js  # Minified JS (~19 KB)
    bootstrap-multiselect.css     # Unminified copy for distribution
    bootstrap-multiselect.min.css # Minified CSS (~3 KB)

For production, use the minified versions from dist/:

<link href="dist/bootstrap-multiselect.min.css" rel="stylesheet">
<script src="dist/bootstrap-multiselect.min.js"></script>

License

MIT