JqTree is a tree widget.
The project is hosted on github, has a test suite.
var data = [
{
label: 'node1',
children: [
{ label: 'child1' },
{ label: 'child2' }
]
},
{
label: 'node2',
children: [
{ label: 'child3' }
]
}
];
$('#tree1').tree({
data: data,
autoOpen: true,
dragAndDrop: true
});
<script src="jquery-1.9.1.min.js"></script>
<script src="tree.jquery.js"></script>
<link rel="stylesheet" href="jqtree.css">
<script src="jquery.cookie.js"></script>
<div id="tree1"></div>
var data = [
{
label: 'node1',
children: [
{ label: 'child1' },
{ label: 'child2' }
]
},
{
label: 'node2',
children: [
{ label: 'child3' }
]
}
];
$(function() {
$('#tree1').tree({
data: data
});
});
$.getJSON(
'/some_url/',
function(data) {
$('#tree1').tree({
data: data
});
}
);
Define the contents of the tree. The data is a nested array of objects. This option is required.
It looks like this:
var data = [
{
label: 'node1',
children: [
{ label: 'child1' },
{ label: 'child2' }
]
},
{
label: 'node2',
children: [
{ label: 'child3' }
]
}
];
$('#tree1').tree({data: data});
You can also include other data in the objects. You can later access this data.
For example, to add an id:
{
label: 'node1',
id: 1
}
Load the node data from this url.
$('#tree1').tree({
dataUrl: '/example_data.json'
});
You can also set the data-url attribute on the dom element:
<div id="tree1" data-url="/example_data.json"></div>
<script>
$('#tree1').tree();
</script>
Open nodes initially.
Open all nodes initially:
$('#tree1').tree({
data: data,
autoOpen: true
});
Open first level nodes:
$('#tree1').tree({
data: data,
autoOpen: 0
});
Save and restore the state of the tree automatically. Saves in a cookie which nodes are opened and selected.
The state is saved in localstorage. In browsers that do not support localstorage, the state is saved in a cookie.
For this to work, please include jquery-cookie.
For this to work, you should give each node in the tree data an id field:
{
label: 'node1',
id: 123,
childen: [
label: 'child1',
id: 124
]
}
$('#tree1').tree({
data: data,
saveState: true
});
Example: save state in key 'tree1':
$('#tree1').tree({
data: data,
saveState: 'tree1'
});
Turn on dragging and dropping of nodes.
Example: turn on drag and drop.
$('#tree1').tree({
data: data,
dragAndDrop: true
});
Turn on selection of nodes.
Example: turn on selection of nodes.
$('#tree1').tree({
data: data,
selectable: true
});
You can set a function to override if a node can be selected. The function gets a node as parameter, and must return true or false.
For this to work, the option 'selectable' must be 'true'.
// Example: nodes with children cannot be selected
$('#tree1').tree({
data: data,
selectable: true
onCanSelectNode: function(node) {
if (node.children.length == 0) {
// Nodes without children can be selected
return true;
}
else {
// Nodes with children cannot be selected
return false;
}
}
});
The function is called for each created node. You can use this to define extra html.
$('#tree1).tree({
data: data,
onCreateLi: function(node, $li) {
// Add 'icon' span before title
$li.find('.jqtree-title').before('<span class="icon"></span>');
}
});
You can override this function to determine if a dom element can be used to move a node.
$('#tree1').tree({
data: data,
onIsMoveHandle: function($element) {
// Only dom elements with 'jqtree-title' class can be used
// as move handle.
return ($element.is('.jqtree-title'));
}
});
You can override this function to determine if a node can be moved.
$('#tree1').tree({
data: data,
dragAndDrop: true,
onCanMove: function(node) {
if (! node.parent.parent) {
// Example: Cannot move root node
return false;
}
else {
return true;
}
}
});
You can override this function to determine if a node can be moved to a certain position.
$('#tree1').tree({
data: data,
dragAndDrop: true,
onCanMoveTo: function(moved_node, target_node, position) {
if (target_node.is_menu) {
// Example: can move inside menu, not before or after
return (position == 'inside');
}
else {
return true;
}
}
});
Determine if text is autoescaped. The default is true.
Turn slide animation on or off. Default is true.
$('#tree1').tree({
slide: false
});
function loadData(data);
function loadData(data, parent_node);
Load data in the tree. The data is array of nodes.
You can replace the whole tree or you can load a subtree.
// Assuming the tree exists
var new_data = [
{
label: 'node1',
children: [
{ label: 'child1' },
{ label: 'child2' }
]
},
{
label: 'node2',
children: [
{ label: 'child3' }
]
}
];
$('#tree1').tree('loadData', new_data);
Load a subtree:
// Get node by id (this assumes that the nodes have an id)
var node = $('#tree1').tree('getNodeById', 100);
// Add new nodes
var data = [
{ label: 'new node' },
{ label: 'another new node' }
];
$('#tree1').tree('loadData', data, node);
function loadDataFromUrl(url);
function loadDataFromUrl(url, parent_node);
function loadDataFromUrl(parent_node);
Load data in the tree from an url using ajax. You can replace the whole tree or you can load a subtree.
$('#tree1').tree('loadDataFromUrl', '/category/tree/');
Load a subtree:
var node = $('#tree1').getNodeById(123);
$('#tree1').tree('loadDataFromUrl', '/category/tree/123', node);
You can also omit the url. In this case jqTree will generate a url for you. This is very useful if you use the load-on-demand feature:
var $tree = $('#tree1');
$tree.tree({
dataUrl: '/my_data/'
});
var node = $tree.tree('getNodeById', 456);
// jqTree will load data from /my_data/?node=456
$tree.tree('loadDataFromUrl', node);
You can also add an on_finished callback parameter that will be called when the data is loaded:
function loadDataFromUrl(url, parent_node, on_finished);
function loadDataFromUrl(parent_node, on_finished);
$('#tree1').tree(
'loadDataFromUrl',
'/category/tree/123',
null,
function() {
alert('data is loaded');
}
);
function toJson();
Get the tree data as json.
// Assuming the tree exists
$('#tree1').tree('toJson');
function getNodeById(id);
Get a tree node by node-id. This assumes that you have given the nodes in the data a unique id.
var $tree = $('#tree1');
var data = [
{ id: 10, name: 'n1' },
{ id: 11, name: 'n2' }
];
$tree.tree({
data: data
});
var node = $tree.tree('getNodeById', 10);
function selectNode(node);
Select this node.
// create tree
var $tree = $('#tree1');
$tree.tree({
data: data,
selectable: true
});
var node = $tree.tree('getNodeById', 123);
$tree.tree('selectNode', node);
function openNode(node);
function openNode(node, slide);
Open this node. The node must have child nodes.
Parameter slide: open the node using a slide animation (default is true).
// create tree
var $tree = $('#tree1');
$tree.tree({
data: data
});
var node = $tree.tree('getNodeById', 123);
$tree.tree('openNode', node);
To open the node without the slide animation, call with slide parameter is false.
$tree.tree('openNode', node, false);
function closeNode(node);
function closeNode(node, slide);
Close this node. The node must have child nodes.
Parameter slide: close the node using a slide animation (default is true).
var node = $tree.tree('getNodeById', 123);
$tree.tree('closeNode', node);
To close the node without the slide animation, call with slide parameter is false.
$tree.tree('closeNode', node, false);
Get the selected node. Returns the row data or false.
var node = $tree.tree('getSelectedNode');
function addNodeAfter(new_node_info, existing_node);
Add a new node after this existing node.
var node1 = $('#tree1', 'getNodeByName, 'node1');
$('#tree1').tree(
'addNodeAfter',
{
label: 'new_node',
id: 456
},
node1
);
function addNodeBefore(new_node_info, existing_node);
Add a new node before this existing node.
function addParentNode(new_node_info, existing_node);
Add a new node as parent of this existing node.
var node1 = $('#tree1', 'getNodeByName', 'node1');
$('#tree1').tree(
'addParentNode',
{
label: 'new_parent',
id: 456
},
node1
);
function removeNode(node);
Remove node from the tree.
$('#tree1').tree('removeNode', node);
function appendNode(new_node_info, parent_node);
Add a node to this parent node. If *parent_node* is empty, then the new node becomes a root node.
var parent_node = $tree.tree('getNodeById', 123);
$tree.tree(
'appendNode',
{
label: 'new_node',
id: 456
},
parent_node
);
To add a root node, leave *parent_node* empty:
$tree.tree(
'appendNode',
{
label: 'new_node',
id: 456
}
);
function updateNode(node, label);
function updateNode(node, data);
Update the title of a node. You can also update the data.
Update the label:
var node = $tree.tree('getNodeById', 123);
$tree.tree('updateNode', node, 'new label');
Update the data (including the label)
var node = $tree.tree('getNodeById', 123);
$tree.tree(
'updateNode',
node,
{
label: 'new label',
other_property: 'abc'
}
);
function moveNode(node, target_node, position);
Move a node. Position can be 'before', 'after' or 'inside'.
var node = $tree.tree('getNodeBydId', 1);
var target_node = $tree.tree('getNodeBydId', 2);
$tree.tree('moveNode', node, target_node, 'after');
function toggle(node);
function toggle(node, slide);
Open or close a node.
Parameter slide: a slide animation (default is true).
var node = $tree.tree('getNodeBydId', 1);
$tree.tree('toggle', node);
Triggered when a tree node is clicked.
// create tree
$('#tree1').tree({
data: data
});
// bind 'tree.click' event
$('#tree1').bind(
'tree.click',
function(event) {
// The clicked node is 'event.node'
var node = event.node;
alert(node.name);
}
);
Triggered when a tree node is selected.
$('#tree1').bind(
'tree.select',
function(event) {
var node = event.node;
alert(node.name);
}
);
Triggered when the user right-clicks a tree node. The event contains the following properties:
// bind 'tree.contextmenu' event
$('#tree1').bind(
'tree.contextmenu',
function(event) {
// The clicked node is 'event.node'
var node = event.node;
alert(node.name);
}
);
Triggered when the user moves a node.
Event.move_info contains:
$('#tree1').tree({
data: data,
dragAndDrop: true
});
$('#tree1').bind(
'tree.move',
function(event) {
console.log('moved_node', event.move_info.moved_node);
console.log('target_node', event.move_info.target_node);
console.log('position', event.move_info.position);
console.log('previous_parent', event.move_info.previous_parent);
}
);
You can prevent the move by calling event.preventDefault()
$('#tree1').bind(
'tree.move',
function(event) {
event.preventDefault();
}
);
You can later call event.move_info.move_info.do_move() to move the node. This way you can ask the user before moving the node:
$('#tree1').bind(
'tree.move',
function(event) {
event.preventDefault();
if (confirm('Really move?')) {
event.move_info.do_move();
}
}
);
Note that if you want to serialise the tree, for example to POST back to a server, you need to let tree complete the move first:
$('#tree1').bind(
'tree.move',
function(event)
{
event.preventDefault();
// do the move first, and _then_ POST back.
event.move_info.do_move();
$.post('your_url', {tree: $(this).tree('toJson')});
}
);
Called when the tree is initialized. This is particularly useful when the data is loaded from the server.
$('#tree1').bind(
'tree.init',
function() {
// initializing code
}
);
Called when a node is opened.
$('#tree1').bind(
'tree.open',
function(e) {
console.log(e.node);
}
);
Tree designed by Hernan D. Schlosman from The Noun Project