Introduction
jsTree is jquery plugin that provides interactive trees. It is absolutely free and open source. jsTree is easily extendable, themable and configurable, it supports HTML & JSON data sources, and AJAX loading.
Core Features in jsTree
- Drag & drop support
- Keyboard navigation
- Inline edit, create and delete
- Fuzzy searching
- Customizable node types
Overview
If you choose to download - all the files you need are in the dist/folder of the download
If you use CDNJS, then add the below css and script files.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" />
Include jQuery
jsTree requires 1.9.0 or greater in your webpage. You can use a CDN version or include a local copy.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script>
Setup a container
This is the element where you want the tree to appear, a <div> is enough. This example has a nested <ul> as there is no other data source configured (such as JSON).
<div id="jstree_example"></div>
How to create jsTree instance
Once the DOM is ready you can start creating jsTree instances.
$('#jstree_example').jstree({ })
How to Configure the instance
We can configure the instance by including themes, plugins and more.
- $('#jstree_example').jstree({
- "core" : {
- "themes" : {
- "variant" : "large"
- }
- },
- "plugins" : [ "wholerow", "checkbox" ]
- });
Populate tree using HTML
jsTree can turn a regular unordered list into a tree. The minimal required markup is a <ul> node with some nested <li> nodes with some text inside.
- <div id="jstree_example">
- <ul>
- <li>Root node 1</li>
- <li>Root node 2</li>
- </ul>
- </div>
-
You should have a container wrapping the <ul> and create the instance on that container. Like so: $('#jstree_example').jstree();
Populating the tree using JSON
jsTree needs a specific format to work with JSON. In the standard syntax no fields are required - pass only what you need.
Keep in mind you will be able to access any additional properties you specify - jsTree won't touch them and you will be able to use them later on (using the original property on each node).
To change the icon of the node use the icon property.
Specifying a string containing a / will display that image as the node icon. Using any other string will apply that class to the <i> element that is used to represent the icon.
You can use boolean false to make jsTree render the node with no icon.
You can set the state on a node using the state property.
Use any combination of the following: opened, selected, disabled.
Both li_attr and a_attr are passed directly to jQuery's attr function.
When using AJAX set children to boolean true and jsTree will render the node as closed and make an additional request for that node when the user opens it.
Any nested children should either be objects following the same format, or plain strings (in which case the string is used for the node's text and everything else is autogenerated).
- // Expected format of the node (there are no required fields)
- {
- id : "string" // will be autogenerated if omitted
- text : "string" // node text
- icon : "string" // string for custom
- state : {
- opened : boolean // is the node open
- disabled : boolean // is the node disabled
- selected : boolean // is the node selected
- },
- children : [] // array of strings or objects
- li_attr : {} // attributes for the generated LI node
- a_attr : {} // attributes for the generated A node
- }
Using the alternative JSON format
- $('#jstree_example').jstree({
- 'core' : {
- 'data' : [
- { "id" : "ajson1", "parent" : "#", "text" : "Simple root node" },
- { "id" : "ajson2", "parent" : "#", "text" : "Root node 2" },
- { "id" : "ajson3", "parent" : "ajson2", "text" : "Child 1" },
- { "id" : "ajson4", "parent" : "ajson2", "text" : "Child 2" },
- ]
- }
- });
Listening for events
jsTree triggers various events on the container.
To get more information about the event inspect its data argument.
In most cases where a node is involved you will get the whole node object passed in. If you get an ID string somewhere and want to inspect the node just use .get_node(). The internal node object is very similar to the JSON format used for loading, but has a few extra properties, which might be useful: Children is an array of all the IDs of the node's immediate children, children_d is an array of all the IDs of the node's descendants, parent is the IDs of the node's parent and parents is an array of all the IDs of the node's ancestors.
Please keep in mind that by default all modifications to the tree are prevented (create, rename, move, delete). To enable them set core.check_callback to true.
Below are refresh, select and delete functionality which triggers the event
$('#jstree_example').jstree(true).refresh()
$('#jstree_example').jstree('select_node', node)
$("#jstree_example").jstree(true).delete_node(node)
- $('#jstree_example').jstree({
- "core": {
- "check_callback": true,
- "data": []
- },
- }).bind("refresh.jstree", function (e, data) {
-
- }).bind("select_node.jstree", function (e, data) {
-
- }).bind("delete_node.jstree", function (e, data) {
-
- })
Plugins available in jsTree
jsTree has some functionality moved out of the core so you can only use it when you need it. To enable a plugin use the plugins config option and add that plugin's name to the array.
For example enabling all the plugins can be done this way: (enable only plugins you need)
"plugins" : [
"checkbox",
"contextmenu",
"dnd",
"massload",
"search",
"sort",
"state",
"types",
"unique",
"wholerow",
"changed",
"conditionalselect"
]
Changed Plugin
This plugin adds additional information about selection changes. Once included in the plugins config option, each changed.jstree event data will contain a new property named changed, which will give information about selected and deselected nodes since the last changed.jstree event
- $(function () {
- $("#jstree_example")
- .on("changed.jstree", function (e, data) {
- console.log(data.changed.selected);
- console.log(data.changed.deselected);
- })
- .jstree({
- "plugins" : [ "changed" ]
- });
- });
Checkbox plugin
This plugin renders checkbox icons in front of each node, making multiple selection much easier.
- $(function () {
- $("#jstree_example").jstree({
- "checkbox" : {
- "keep_selected_style" : false
- },
- "plugins" : [ "checkbox" ]
- });
- })
-
Conditionalselect plugin
This plugin overrides the activate_node function (the one that gets called when a user tries to select a node) and enables preventing the function invokation by using a callback.
- $(function () {
- $("#jstree_example").jstree({
- "conditionalselect" : function (node, event) {
- return false;
- },
- "plugins" : [ "conditionalselect" ]
- });
- });
Contextmenu plugin
This plugin makes it possible to right click nodes and shows a list of configurable actions in a menu.
- $(function () {
- $("#jstree_example").jstree({
- "core" : {
-
- "check_callback" : true
- },
- "plugins" : [ "contextmenu" ]
- });
- });
Drag & drop plugin
This plugin makes it possible to drag and drop tree nodes and rearrange the tree.
- $(function () {
- $("#jstree_example").jstree({
- "core" : {
- "check_callback" : true
- },
- "plugins" : [ "dnd" ]
- });
- });
Sort plugin
This plugin automatically arranges all sibling nodes according to a comparison config option function, which defaults to alphabetical order.
- $(function () {
- $("#jstree_example").jstree({
- "plugins" : [ "sort" ]
- });
- });
State plugin
This plugin saves all opened and selected nodes in the user's browser, so when returning to the same tree the previous state will be restored.
- $(function () {
- $("#jstree_example").jstree({
- "state" : { "key" : "demo2" },
- "plugins" : [ "state" ]
- });
- });
Types plugin
This plugin makes it possible to add predefined types for groups of nodes, which means to easily control nesting rules and icons for each group.
To set a node's type you can use set_type or supply a type property with the node's data.
- $(function () {
- $("#jstree_example").jstree({
- "types" : {
- "default" : {
- "icon" : "glyphicon glyphicon-flash"
- },
- "demo" : {
- "icon" : "glyphicon glyphicon-ok"
- }
- },
- "plugins" : [ "types" ]
- });
- });
Whole row plugin
Makes each node appear block level which makes selection easier. May cause a slow down for large trees in old browsers.
- $(function () {
- $("#jstree_example").jstree({
- "plugins" : [ "wholerow" ]
- });
- });
We have seen the features in jsTree from the above description. Now we will see how to create jsTree instance and load dynamic data to them.
JS
Let's say, we are fetching the tree data from database and the results are as below:
ClassID |
ClassName |
StudentID |
StudentName |
1 |
Class1 |
101 |
Srinath |
1 |
Class1 |
102 |
Thangabalu |
2 |
Class2 |
201 |
Krishna Vinoth |
2 |
Class2 |
202 |
Sivanesan |
2 |
Class2 |
203 |
Bommuraja |
We are planning to load the jsTree with PARENT as ClassID and CHILD as StudentID.
We can create jsTree nodes using json array or either we can use create_node event from jsTree
CREATE jsTree INSTANCE
using json array
- $(document).ready(function () {
- fnLoadJsTreeInstance()
- })
- function fnLoadJsTreeInstance() {
- var treeDataSource = fnGetTreeData()
-
- $('#divJsTreeExample').jstree({
- "core": {
- "data": treeDataSource
- },
- "types": {
- "folder": {
- "icon": "fa fa-folder"
- },
- "file": {
- "icon": "fa fa-file"
- }
- },
- "plugins": ["types"]
- }).bind('ready.jstree', function (e, data) {
- $('#divJsTreeExample').jstree('open_all')
- })
- }
- function fnGetTreeData() {
- var treeData = [
- { ClassID: 1, ClassName: 'Class1', StudentID: 101, StudentName: 'Srinath' },
- { ClassID: 1, ClassName: 'Class1', StudentID: 102, StudentName: 'Thangabalu' },
- { ClassID: 2, ClassName: 'Class2', StudentID: 201, StudentName: 'Krishna Vinoth' },
- { ClassID: 2, ClassName: 'Class2', StudentID: 202, StudentName: 'Sivanesan' },
- { ClassID: 2, ClassName: 'Class2', StudentID: 203, StudentName: 'Bommuraja' }
- ]
-
- var treeFinalResult = []
- var distinctClassID = {}
- $.each(treeData, function (i, data) {
- if (!distinctClassID[data.ClassID]) {
-
- distinctClassID[data.ClassID] = true
-
- treeFinalResult.push({
- id: data.ClassID,
- parent: "#",
- text: data.ClassName,
- type: "folder"
- })
-
- treeFinalResult.push({
- id: data.StudentID,
- parent: data.ClassID,
- text: data.StudentName,
- type: "file"
- })
- } else {
-
- treeFinalResult.push({
- id: data.StudentID,
- parent: data.ClassID,
- text: data.StudentName,
- type: "file"
- })
- }
- })
- return treeFinalResult
- }
Please note that every node should have an unique id. Parent is the value to group the items.
using create_node event
Pass the id and name to the create_node method which will trigger the event where it's bound in jsTree.
-
- $('#jstree_example').jstree(true).create_node('#', {
- id: data.ClassID,
- text: data.ClassName,
- type: "folder"
- }, "last", function (node) {
- $('#jstree_example').jstree('open_all')
- })
-
-
- jsTree.create_node(data.ClassID, {
- id: data.StudentID,
- text: data.StudentName,
- type: "file"
- }, "last", function(node) {
- $('#jstree_example').jstree('open_all')
- })
The above code will create a parent and child and triggers the create_node event. Now the node will be generated visually, but we have bound the node to the jsTree datasource.
- $(document).ready(function(){
- fnLoadJsTreeInstance()
- })
-
- function fnLoadJsTreeInstance(){
-
- $('#jstree_example').jstree({
- "core": {
- "data": []
- },
- "types": {
- "folder": {
- "icon": "fa fa-folder"
- },
- "file":{
- "icon": "fa fa-file"
- }
- },
- "plugins": ["types"]
- }).bind("create_node.jstree", function (e, data) {
-
- data.instance.settings.core.data.push( data.node )
- data.instance.refresh()
- }).bind("loaded.jstree", function (e, data) {
-
-
- })
- }
Summary
To load the jsTree, the main thing is to create the valid json(treeData). Then id & parent should be mapped correctly. Please post your queries if anything needs to be clarified.