Overview
EasyTree,
uses the common folder/file UI to manipulate a nested
<ul>/<li>
document markup. The API provides a number of
functions that allow external code to access and manipulate
the internal state.
Dependencies
- easyjstree.com.skin-win8_ui.easytree.css
- //code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css
- easytree.min.js
- icons.gif →
Initialize
The tree lives in a <div id="tree">
: Use it to initialize the enclosed
list markup:
→ $('div#tree').easytree();
Alternatively, can specify an external json file via:
→ $('div#tree').easytree({dataUrl: '/some/path/data.json'});
To enable lazy loading, specify a handler during init:
→ $('div#tree').easytree({openLazyNode: openLazyNode});
The handler looks like this:
var counter = 0;
function openLazyNode(event, nodes, node, hasChildren) {
if (hasChildren) return false; // don't bother if previously loaded
counter++;
node.lazyUrl = '/Demos/LazyLoadingExample/'; // may be set as an option instead
node.lazyUrlJson = JSON.stringify({ // any json object here (optional)
text: counter
});
}
Also, you can specify event handlers in the initialization:
→ see the source of this page for examples.
API
EasyTree provides a number of functions that allow external code to access internal state, more details can be found in the global function pages. The demo below gives some examples of how to use the API.
Operations
Code to implement an operation appears when you click its button.
Operate on | |
New Text | |
Is folder |
function addNode() {
var sourceNode = {};
sourceNode.text = $('#nodeText').val();
sourceNode.isFolder = $('#nodeIsFolder').is(":checked");
var targetId = $('#lstNodes :selected').val();
easytree.addNode(sourceNode, targetId);
easytree.rebuildTree();
loadSelectBox();
}
function removeNodeX() {
var currentlySelected = $('#lstNodes :selected').val();
var node = easytree.getNode(currentlySelected);
if (!node) return;
easytree.removeNode(node.id);
easytree.rebuildTree();
loadSelectBox();
}
function activateNode() {
var currentlySelected = $('#lstNodes :selected').val();
var node = easytree.getNode(currentlySelected);
if (!node) {
easytree.activateNode(''); // deactivate all nodes
return;
}
easytree.activateNode(node.id);
}
function toggleNode() {
var currentlySelected = $('#lstNodes :selected').val();
easytree.toggleNode(currentlySelected);
loadSelectBox();
}
function openNode() {
var currentlySelected = $('#lstNodes :selected').val();
var node = easytree.getNode(currentlySelected);
if (!node) return;
node.isExpanded = true;
easytree.rebuildTree();
loadSelectBox();
}
function closeNode() {
var currentlySelected = $('#lstNodes :selected').val();
var node = easytree.getNode(currentlySelected);
if (!node) return;
node.isExpanded = false;
easytree.rebuildTree();
loadSelectBox();
}
Populating a select box
In the above examples, we need to repopulate the select
box with all of the tree nodes
after each operation that changes the tree contents.
We use a recursive call to addOptions()
for each node's children starting with the root
node. This is a handy technique when you have a tree to begin with.
// we have to reload selected box at the end of
// each function to ensure it is always up to date
function loadSelectBox() {
var select = $('#lstNodes')[0];
var currentlySelected = $('#lstNodes :selected').val();
select.length = 0; // clear select box
var root = new Option();
root.text = 'Root';
root.value = '';
select.add(root);
var allNodes = easytree.getAllNodes();
addOptions(allNodes, select, '-', currentlySelected);
}
function addOptions(nodes, select, prefix, currentlySelected) {
var i = 0;
for (i = 0; i < nodes.length; i++) {
var option = new Option();
option.text = prefix + ' ' + nodes[i].text;
option.value = nodes[i].id;
option.selected = currentlySelected == nodes[i].id;
select.add(option);
if (nodes[i].children && nodes[i].children.length > 0)
addOptions(nodes[i].children, select, prefix + '-', currentlySelected);
}
}
$(document).ready(function () {
loadSelectBox();
});
Internal Node Structure
Internally EasyTree uses a structure of 'nodes' to represent the tree. To interact with EasyTree or initialize EasyTree with a JSON object you must understand the node properties:
Property | Type | Description |
---|---|---|
children | array | Children is an array of nodes which represent the sub nodes |
isActive | bool | Whether or not a particular node is active. Only one node should be active and it will be highlighted |
isFolder | bool | Whether or not a node is a folder. Folders have a different icon by default, and are the only node type that can be dropped to |
isLazy | bool | If a node is lazy it will fire the 'openLazyNode' event when opened and then call the url defined in lazyUrl and populate its children withthe response |
isExpanded | bool | Whether or not a node is open |
iconUrl | string | Passing in a url to an image here will override the nodes default icon |
id | string | All nodes need an id, if one isn't passed in an id will be created automatically |
href | string | Allows a node to link to a different web page |
hrefTarget | string | Determines how a node should open a link, possible values are _blank , _self , _parent and _top . The default is '_self'. |
lazyUrl | string | If a node is lazy it will call the url defined here in order to populate its children. The url should return an array of nodes and can be populated either when the tree is first initialised or in the openLazyNode event |
lazyUrlJson | string | When lazyUrl is called anything defined in lazyUrlJson will be passed to the server in the same request |
liClass | string | Any classes passed in here will span the underlying li element when the tree is rendered |
text | string | The text that is displayed when the node is rendered |
textCss | string | Any classes passed in here will span the text element when the tree is rendered |
tooltip | string | Tooltip text displayed when hovering over the node |
uiIcon | string | Any jqueryUI icon class for example ui-icon-scissors . For this to work please make sure jqueryUI has been imported, more jqueryUI icons can be found here |