A dynamic, high-performance JQuery plugin that transforms standard selects into tree-nesting, searchable, grouped dropdowns with checkboxes, full module loader support (UMD), and customized styles.
Load jQuery (3.x+ recommended). The plugin is completely standalone and includes built-in inline SVGs, so Bootstrap 5 and FontAwesome are optional. Include the jqTreeSelect CSS and JavaScript files.
<!-- jqTreeSelect Custom Styles -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/umairwebdeveloper/jqTreeSelect/dist/jq-tree-select.min.css">
jqTreeSelect includes a UMD (Universal Module Definition) wrapper, allowing it to load cleanly in standard browsers, AMD modules, and Node/CommonJS module systems.
<!-- JQuery 3.x -->
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<!-- jqTreeSelect Custom Script -->
<script src="https://cdn.jsdelivr.net/gh/umairwebdeveloper/jqTreeSelect/dist/jq-tree-select.min.js"></script>
To get better form UI styling and support for tooltip count descriptions on selected elements, you can optionally include Bootstrap 5 CSS and JavaScript files in your project:
<!-- Optional: Bootstrap 5 for better UI -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
// Import jQuery and the plugin
const $ = require('jquery');
require('./jq-tree-select.js')($); // pass jQuery context
require(['jquery', 'jq-tree-select'], function($) {
// Plugin initialized
$('#mySelect').jqTreeSelect();
});
jqTreeSelect can be initialized in two different ways depending on your application needs:
Simply add the attribute
data-toggle="jq-tree-select" to your
native multi-select element. The plugin will
automatically instantiate it when the document
loads, reading configuration options directly from
any data-* attributes defined on the
element.
<!-- Auto-initialized tree with search enabled, width 320px -->
<select class="form-control" multiple
data-toggle="jq-tree-select"
data-search-enabled="true"
data-layout-width="320px">
<option value="1">Option A</option>
<option value="2">Option B</option>
</select>
Instantiate options programmatically by calling
.jqTreeSelect() on your jQuery
selectors.
<select id="manualSelect" class="form-control" multiple>
<option value="1">Option 1</option>
<option value="2" selected>Option 2</option>
</select>
$(document).ready(function() {
$('#manualSelect').jqTreeSelect({
search: {
enabled: true
},
actions: {
showSelectAll: true,
showClearAll: true
}
});
});
Toggle and customize different options in real-time, view the rendered widget live, and copy the instantly compiled JQuery or HTML data attributes markup.
The global options schema allows full customization. Grouped into structured nested namespaces.
layout)
| Option | Type | Default | Description |
|---|---|---|---|
layout.width |
String | "100%" |
Width of the dropdown wrapper (CSS
syntax like "300px",
"100%").
|
layout.height |
String | "36px" |
Height of the closed display element. |
layout.dropdownHeight
|
String | "400px" |
Maximum scrollable height of the dropdown items panel. |
layout.placeholder |
String | "Select..." |
Text displayed when no options are checked. |
actions)
| Option | Type | Default | Description |
|---|---|---|---|
actions.showSelectAll
|
Boolean | true |
Displays the "Select All" icon button in the header. |
actions.showClearAll
|
Boolean | true |
Displays the "Clear All" icon button in the header. |
actions.showReset |
Boolean | false |
Displays the "Reset to Defaults" icon button. |
actions.showTotalCount
|
Boolean | false |
Shows a badge with the total number of options. |
grouping)
| Option | Type | Default | Description |
|---|---|---|---|
grouping.nested |
Boolean | false |
Set to true to enable
infinite grouping support.
|
grouping.collapsible
|
Boolean | false |
If true, adds chevron toggles next to group/subgroup headers to expand/collapse. |
grouping.collapsedByDefault
|
Boolean | false |
When collapsible is
enabled, controls whether groups
start collapsed.
|
grouping.showExpandAll
|
Boolean | false |
Displays the "Expand All" header icon. |
grouping.showCollapseAll
|
Boolean | false |
Displays the "Collapse All" header icon. |
search)
| Option | Type | Default | Description |
|---|---|---|---|
search.enabled |
Boolean | false |
Renders a dynamic live search/filter input. |
search.placeholder |
String | "Search..." |
Placeholder placeholder inside the search box. |
Set options directly in your markup to configure individual instances. These automatically override the global defaults.
| Data Attribute | Equivilant JS Property | Example |
|---|---|---|
data-layout-width |
layout.width |
data-layout-width="350px"
|
data-layout-height |
layout.height |
data-layout-height="40px"
|
data-layout-dropdown-height
|
layout.dropdownHeight
|
data-layout-dropdown-height="250px"
|
data-layout-placeholder
|
layout.placeholder |
data-layout-placeholder="Choose
category..."
|
data-actions-show-select-all
|
actions.showSelectAll
|
data-actions-show-select-all="false"
|
data-actions-show-clear-all
|
actions.showClearAll
|
data-actions-show-clear-all="false"
|
data-actions-show-reset
|
actions.showReset |
data-actions-show-reset="true"
|
data-grouping-nested
|
grouping.nested |
data-grouping-nested="true"
|
data-grouping-collapsible
|
grouping.collapsible
|
data-grouping-collapsible="true"
|
data-search-enabled
|
search.enabled |
data-search-enabled="true"
|
data-search-placeholder
|
search.placeholder |
data-search-placeholder="Filter..."
|
Load and build options dynamically by passing a
javascript array of objects directly in the
data parameter.
$('#mySelect').jqTreeSelect({
data: [
{ value: "1", text: "Alpha Node" },
{ value: "2", text: "Beta Node", selected: true },
{ value: "3", text: "Disabled Node", disabled: true }
]
});
$('#mySelect').jqTreeSelect({
grouping: { nested: true },
data: [
{
groupName: "Fruits",
groupId: "g_fruits",
options: [
{ value: "f1", text: "Apple" },
{ value: "f2", text: "Banana", selected: true }
]
},
{
groupName: "Vegetables",
groupId: "g_vegetables",
options: [
{ value: "v1", text: "Spinach" }
]
}
]
});
Provide a groupPath (using slashes
/) to nested folders. The plugin
programmatically compiles nodes and subnodes to
arbitrary depth.
$('#mySelect').jqTreeSelect({
grouping: {
nested: true,
collapsible: true
},
data: [
{
value: "w1",
text: "Create Users",
groupPath: "Admin/Permissions/User Operations",
groupCollapsed: false
},
{
value: "w2",
text: "Edit Profiles",
groupPath: "Admin/Permissions/User Operations"
},
{
value: "r1",
text: "Read Logs",
groupPath: "Admin/Logs"
}
]
});
Expose and trigger interaction lifecycle hooks either via setting properties or native jQuery DOM event listeners.
| Callback Option | jQuery DOM Event | Triggers When |
|---|---|---|
onInit |
jqtree:init |
Widget layout is rendered and ready. |
onOpen |
jqtree:open |
Dropdown panel opens. |
onClose |
jqtree:close |
Dropdown panel closes. |
onChange |
jqtree:change |
Checked option changes. Passes array of selected values. |
onDestroy |
jqtree:destroy |
Widget layout is destroyed and replaced with native select. |
// Method A: JavaScript callbacks parameter
$('#mySelect').jqTreeSelect({
callbacks: {
onChange: function(detail) {
console.log("Selected values array: ", detail.selectedValues);
}
}
});
// Method B: Standard JQuery event listeners
$('#mySelect').on('jqtree:change', function(event, detail) {
console.log("Change registered on DOM: ", detail.selectedValues);
});
Trigger actions programmatically by passing the method name string as parameters.
| Method Call | Arguments | Returns | Description |
|---|---|---|---|
.jqTreeSelect('val')
|
None | Array |
Returns array of currently selected values. |
.jqTreeSelect('val',
Array)
|
['val1', 'val2'] |
jQuery Object |
Sets current selections and updates UI. |
.jqTreeSelect('selectAll')
|
None | None | Checks all non-disabled visible options. |
.jqTreeSelect('clear')
|
None | None | Unchecks all non-disabled options. |
.jqTreeSelect('reset')
|
None | None | Resets options to default state during page load. |
.jqTreeSelect('expandAll')
|
None | None |
Expands all subgroups (if
collapsible: true).
|
.jqTreeSelect('collapseAll')
|
None | None | Collapses all subgroups. |
.jqTreeSelect('disable')
|
None | None | Disables dropdown interactions and adds visual opacity. |
.jqTreeSelect('enable')
|
None | None | Enables dropdown interactions. |
.jqTreeSelect('refresh')
|
None | None | Destroys and fully rebuilds layout from original select. |
.jqTreeSelect('destroy')
|
None | None | Cleans layout wrappers, tooltips, and recovers native element display. |
// Clear all selections
$('#mySelect').jqTreeSelect('clear');
// Fetch current values
let currentList = $('#mySelect').jqTreeSelect('val');
console.log(currentList);
Got a problem, found a bug, or need help integrating the plugin? I'm always happy to help out.
Full Stack Web Developer
If you encounter any issues, require custom development, or want to discuss improvements for jqTreeSelect, please feel free to reach out directly via email.
umairashraf5252@gmail.com