GitHub Logo

DualMultiSelect v

A free, simple and lightweight dual listbox plugin implemented with pure JavaScript.

Getting Started

DualMultiSelect integrates seamlessly with existing select elements, allowing you to use them without modifying your code.
Include the script using one of the methods below and follow the usage examples to get started.

Installation Options

Install via npm: npm install dualmultiselect

Include via CDN:

Or download from GitHub.

Usage

API

Since DualMultiSelect uses the original select element, you can use the same methods and properties you would use with a normal select element.
Additionally, when an option is selected, the change event is fired on the original select element allowing you to use event listeners as you normally would.
There is one caveat to this, which involves changing/selecting options:

Changing/Selecting Options
If you modify the selected options or HTML markup of the original <select> element programmatically, you must trigger the change event to update the DualMultiSelect instance:
document.querySelector('#mySelect').dispatchEvent(new Event('change'));

Methods

Styling

DualMultiSelect offers complete customization through CSS.
You can inspect the elements to view their structure and associated classes, allowing you to easily override the default styles.
Moreover, any classes applied to the original select element will automatically be transferred to the DualMultiSelect component, simplifying the styling process.

Options

All options are optional
Option Type Default Description
data UniversalOptionData null The data to initialize the DualMultiSelect element with. This will overwrite any current options
searchBar boolean | SearchFunction false Set to true to create a searchbar above the selectableList. If you want to use a custom SearchFunction pass that instead. *not compatible with selectableHeader
stackLists boolean false Whether to stack the lists on top of each other instead of side by side
stickyHeaders boolean false Whether to make the option group headers sticky
selectableHeader HTMLElement | string null Custom header for the selectable list
selectedHeader HTMLElement | string null Custom header for the selected list *not compatible with searchbar

Types

UniversalOptionData should be an array containing a combination of OptionElementData and OptGroupElementData objects:

OptionElementData (represents an <option> element):
Property Type Default Description
text string (required) N/A The text of the option or group
value string null The value of the option or group
selected boolean false Whether the option is selected or not
disabled boolean false Whether the option is disabled or not
hidden boolean false Whether the option is hidden or not (used for searching/filtering options).
When all child options of an optGroup are hidden, the optGroup will also be hidden
OptGroupElementData (represents an <optgroup> element):
Property Type Default Description
label string (required) N/A The label of the group
children Array (required) N/A An array of OptionElementData objects

SearchFunction - A function that takes the search query, an OptionElementData object and the parent OptGroupElementData object (if applicable) and returns a boolean.
The function should return true if the option should be shown or false if it should be hidden. Here is an example search function:

function searchFunction(searchQuery, optionData, optGroupData) => {
    const query = searchQuery.toLowerCase();
    return optionData.text.toLowerCase().includes(query) || (optGroupData && optGroupData.label.toLowerCase().includes(query));
}

Custom Data Example

Here is an example of using DualMultiSelect with custom data via the data option. The data format is the same when using the .setData() method.
Note that any current options are overwritten.

Search Bar Example

Setting the searchBar option to true will show a search bar above the selectable list.
The search bar will filter both lists by checking if the option group label, or option text contain the search term (case-insensitive).
Option groups will only be hidden if all their child options are also hidden.

Stacked Lists Example

The lists can be stacked on top of each other by setting the stackLists option to true.

Sticky Headers Example

The option group headers can be made sticky by setting the stickyHeaders option to true.

Custom Headers Example

You can add custom headers to the lists by passing an HTMLElement or a string to the selectableHeader or selectedHeader options. Alternatively you could override the css of the default headers to achieve the desired effect.

Torture Test

DualMultiSelect has been tested with 5000 options: 50 option groups, each with 100 options. The performance is acceptable, but it may be slow on older devices.
The following example demonstrates the performance of DualMultiSelect with a large number of options.

Contributing

If you would like to contribute to DualMultiSelect, please feel free to fork the repository and submit a pull request.
If you have any issues or have feature requests, please submit submit them on the GitHub repository.

Feature ideas: