Interactive Tree Views with Lazy Loading - jQuery Radix Tree
File Size: | 162 KB |
---|---|
Views Total: | 51 |
Last Update: | |
Publish Date: | |
Official Website: | Go to website |
License: | MIT |

Radix Tree is a feature-rich jQuery tree view plugin that transforms hierarchical data structures into interactive, accessible tree view components with advanced functionality like lazy loading, infinite scroll, and comprehensive keyboard navigation.
The plugin handles everything from simple nested lists to complex data explorers with thousands of nodes. It's ideal for dashboards, file browsers, and any interface requiring dynamic tree structures.
Features:
- Deep Nesting: Unlimited tree depth for complex hierarchical data
- Smart Checkboxes: Parent-child propagation with indeterminate states
- Lazy Loading: Load children on demand with configurable delays
- Infinite Scroll: Efficiently handle large datasets with pagination
- Keyboard Navigation: Full arrow-key and space/enter accessibility
- Badges & Tags: Visual indicators for node context and metadata
- Custom Callbacks: Extensive event handling for expand, collapse, click, and check actions
- Modern UI: SVG checkboxes with customizable CSS variables
- Disabled States: Selective node disabling for better UX control
Keyboard Navigation
- Arrow Up/Down: Navigate between nodes
- Arrow Right: Expand focused node
- Arrow Left: Collapse focused node
- Space/Enter: Toggle checkbox or expand/collapse
- Tab: Move focus into and out of tree
How to use it:
1. Include the required jQuery library (slim build) and plugin files:
<!-- jQuery is required --> <script src="/path/to/cdn/jquery.slim.min.js"></script> <!-- jQuery Radix Tree plugin --> <link href="css/jquery-multiselect.css" rel="stylesheet" /> <script src="js/jquery-multiselect.js"></script>
2. Create an empty DIV container where the tree will be rendered.
<div class="radix-tree"></div>
3. Prepare your hierarchical data structure. Each node can have several properties:
label
(string): The text displayed for the node.children
(array): An array of child node objects.open
(bool): Sets the node to be expanded by default.checked
(bool): The state of the node's checkbox.lazy
(bool): If true, children are loaded on demand via thelazyLoad
callback.badge
(string|number): An optional badge.tags
(array): An array of strings for optional tags.disabled
(bool): Disables the node and its children.infinite
(bool): Enables infinite scroll for the node.className
(string): A custom CSS class for the node's<li>
element.
const defaultData = [ { label: 'Universe', open: true, checked: false, children: [ { label: 'Galaxies', open: true, checked: false, children: [ { label: 'Milky Way', open: false, checked: false, }, { label: 'Andromeda', open: false, checked: false, lazy: true // Lazy load Andromeda star systems } ] }, { label: 'Black Holes', open: false, checked: false, children: [ { label: 'Supermassive', open: false, checked: false, lazy: true }, { label: 'Stellar-mass', open: false, checked: false, lazy: true } ] }, { label: 'Nebulae', open: false, checked: false, lazy: true // Lazy load nebulae } ] }, { label: 'Multiverse', open: false, checked: false, children: [ { label: 'Parallel Universe 1', checked: false, lazy: true }, { label: 'Parallel Universe 2', open: false, checked: false, lazy: true } ] } ];
4. Initialize the tree with your data structure:
$('.radix-tree').radixTree({ data: defaultData });
5. For performance, you can load node children asynchronously. Set lazy: true
on a node and provide a lazyLoad
function during initialization. The function receives the node and a done
callback.
function myLazyLoad(node, done) { // Fetch data from an API fetch(`/api/children?node=${node.label}`) .then(res => res.json()) .then(children => { done(children); }) .catch(err => { console.error("Lazy load failed", err); done([{ label: 'Error loading data' }]); }); } $('.radix-tree').radixTree({ data: [{ label: 'My Data', lazy: true }], lazyLoad: myLazyLoad, });
6. For very large datasets, combine lazy: true
and infinite: true
. The lazyLoad
callback receives additional opts
with page information. You call done(children, hasMore)
to signal if more pages are available.
function infiniteLazyLoad(node, done, opts) { const page = opts.page || 1; const pageSize = opts.pageSize || 20; // Fetch a page of data... const children = []; // Your fetched children const hasMore = true; // Did the API indicate more pages? done(children, hasMore); } $('.radix-tree').radixTree({ data: largeData, lazyLoad: infiniteLazyLoad, pageSize: 5, });
7. All default configuration options:
data
: An array of node objects that defines the structure and content of the tree.lazyLoad
: A callback function that fetches child nodes on demand for any node withlazy: true
. It receives the parentnode
and adone
function to pass the new children to.lazyLoadDelay
: A number in milliseconds that sets a global delay for alllazyLoad
operations.pageSize
: A number that specifies how many items to load at a time when using infinite scroll or paginated lazy loading.paginateThreshold
: An optional number. Pagination UI (like a "Load More" button) will only appear if thepageSize
is greater than or equal to this value.
$('.radix-tree').radixTree({ data: defaultData, lazyLoadDelay: 1000, // ms, default delay for lazy loading pageSize: 20, // default page size for infinite scroll/lazy load // paginateThreshold is now optional // Sample lazyLoad function for demo lazyLoad: function(node, done) { // Simulate async loading based on label setTimeout(function() { let children = []; switch (node.label) { case 'Planets': children = [ { label: 'Mercury', checked: false }, { label: 'Venus', checked: false }, { label: 'Earth', open: false, checked: false, lazy: true }, { label: 'Mars', checked: false }, { label: 'Jupiter', checked: false }, { label: 'Saturn', checked: false }, { label: 'Uranus', checked: false }, { label: 'Neptune', checked: false } ]; break; case 'Asteroid Belt': children = [ { label: 'Ceres', checked: false }, { label: 'Vesta', checked: false }, { label: 'Pallas', checked: false }, { label: 'Hygiea', checked: false } ]; break; case 'Alpha Centauri System': children = [ { label: 'Alpha Centauri A', checked: false }, { label: 'Alpha Centauri B', checked: false }, { label: 'Proxima Centauri', checked: false } ]; break; case 'Andromeda': children = [ { label: 'Star System 1', checked: false }, { label: 'Star System 2', checked: false } ]; break; case 'Supermassive': children = [ { label: 'Sagittarius A*', checked: false }, { label: 'M87*', checked: false } ]; break; case 'Stellar-mass': children = [ { label: 'Cygnus X-1', checked: false }, { label: 'V404 Cygni', checked: false } ]; break; case 'Nebulae': children = [ { label: 'Orion Nebula', checked: false }, { label: 'Crab Nebula', checked: false }, { label: 'Eagle Nebula', checked: false } ]; break; case 'Earth': children = [ { label: 'Moon', checked: false }, { label: 'ISS', checked: false } ]; break; case 'Parallel Universe 1': children = [ { label: 'Alt Galaxy', checked: false, lazy: true } ]; break; case 'Parallel Universe 2': children = [ { label: 'Alt Galaxy', checked: false, lazy: true } ]; break; case 'Alt Galaxy': children = [ { label: 'Alt Solar System', checked: false, lazy: true } ]; break; case 'Alt Solar System': children = [ { label: 'Alt Earth', checked: false, lazy: true } ]; break; case 'Alt Earth': children = [ { label: 'Alt Moon', checked: false }, { label: 'Alt Mars', checked: false } ]; break; default: children = [ { label: 'Loading complete', checked: false } ]; } done(children); }, settings.lazyLoadDelay); } });
8. Callback functions:
onExpand
: A callback function that executes when a node is expanded.onCollapse
: A callback function that executes when a node is collapsed.onClick
: A callback function that executes when a user clicks on a node's label.onCheck
: A callback function that executes when a node's checkbox state changes.
$('.radix-tree').radixTree({ data, onExpand: (node, detailsElem) => { console.log('Expanded:', node.label); }, onCollapse: (node, detailsElem) => { console.log('Collapsed:', node.label); }, onClick: (node, elem) => { alert('Clicked: ' + node.label); }, onCheck: (node, checkboxElem) => { console.log('Checked:', node.label, checkboxElem.checked); } });
9. API methods:
// Get all checked nodes const checked = $('.radix-tree').radixTree('getChecked'); // Set checkbox state $('.radix-tree').radixTree('setChecked', nodeId, true); // Expand/collapse nodes $('.radix-tree').radixTree('expand', nodeId); $('.radix-tree').radixTree('collapse', nodeId); // Data manipulation const currentData = $('.radix-tree').radixTree('getData'); $('.radix-tree').radixTree('setData', newData);
10. Override the default CSS variables for theming:
:root { --width: 12; --rounding: 4px; --accent: #696; --dark-grey: #ddd; --grey: #eee; --light-grey: #f8f8f8; --checkbox-size: 1.2em; --checkbox-border: 2px solid #bbb; --checkbox-radius: 6px; --checkbox-shadow: 0 1px 2px rgba(0,0,0,0.07); --checkbox-checked-bg: #4caf50; --checkbox-checked-border: 2px solid #388e3c; --checkbox-indeterminate-bg: #ffc107; --checkbox-indeterminate-border: 2px solid #ffa000; }
Changelog:
v1.0.2 (2025-06-28)
- Update
This awesome jQuery plugin is developed by dxmari. For more Advanced Usages, please check the demo page or visit the official website.