-
-
Notifications
You must be signed in to change notification settings - Fork 604
TutorialLoadData
About initializing Fancytree and implementing lazy loading.
There are several ways to define the actual tree data:
- Format: plain Javascript object, JSON formatted string, or HTML DOM elements
(
<ul><li>
) - Mode: synchronous or asynchronous
- Trigger: immediate or lazy (on demand)
This information is passed using the source
and lazyLoad
options:
$("#tree").fancytree({
// This option defines the initial tree node structure:
source: ...,
// This callback is triggered when a node with 'lazy' attribute expanded for
// the first time:
lazyLoad: ...,
...
};
The data format for source
and lazyLoad
is similar: a - possibly nested -
list of node objects.
i.e. an array of nested objects
$("#tree").fancytree({
source: [
{title: "Node 1", key: "1"},
{title: "Folder 2", key: "2", folder: true, children: [
{title: "Node 2.1", key: "3", myOwnAttr: "abc"},
{title: "Node 2.2", key: "4"}
]}
],
...
};
The following attributes are available as 'node.PROPERTY':
expanded
, extraClasses
, folder
, hideCheckbox
, key
, lazy
, selected
, title
, tooltip
, unselectable
.
All other fields are considered custom and will be added to the nodes data
object as 'node.data.PROPERTY' (e.g. 'node.data.myOwnAttr').
Additional information:
Passing Tree Meta Data
It is possible to pass additional tree meta-data along with the list of children:
{
foo: "bar",
baz: 17,
children: [
{title: "Node 1", key: "1"},
{title: "Folder 2", key: "2", folder: true, children: [
{title: "Node 2.1", key: "3"},
{title: "Node 2.2", key: "4"}
]
}
]
}
The additional properties will be added to the trees data
object:
alert(tree.data.foo); // -> 'bar'
source
may be set to an jQuery.ajax()
settings object:
source: {
url: "/getTreeData",
cache: false
},
...
The ajax service is expected to return valid JSON data:
[{"title": "Node 1", "key": "1"},
{"title": "Folder 2", "key": "2", "folder": true, "children": [
{"title": "Node 2.1", "key": "3"},
{"title": "Node 2.2", "key": "4"}
]}
]
Note that this will be parsed and converted to the internal data format, so it is not the most efficient way to pass data. If Javascript is not available however, the UL markup will still be visible to the user.
$("#tree").fancytree();
<div id="tree">
<ul id="treeData" style="display: none;">
<li id="1">Node 1
<li id="2" class="expanded folder">Folder 2
<ul>
<li id="3">Node 2.1
<li id="4">Node 2.2
</ul>
<li id="k234" class="lazy folder">This is a lazy loading folder with key k234.</li>
</ul>
</div>
...
The id
attribute becomes the node.key
(a unique key is generated if omitted).
The title
attribute becomes node.tooltip
and is displayed on hover.
The following boolean node properties may be set using class attributes of the
<li>
tag:
active
, expanded
, focus
, folder
, lazy
, selected
, unselectable
.
All other classes will be added to node.extraClasses
, and thus become classes
of the generated tree nodes.
Additional data can be added to node.data. ...
using data attributes:
<ul>
<li class="folder">jQuery links
<ul>
<li class="active" data-foo="bar" data-selected="true">jQuery home</li>
<li data-json='{expanded: true, "like": 42}'>jQuery docs</li>
will create node.data.foo = "bar"
, node.data.like = 42
.
Note that special attributes will change the node status instead:
one node will be selected, the other expanded.
A special syntax allows to set node.data.href
and node.data.target
while
using a HTML markup that is functional even when JavaScript is not available:
<div id="tree">
<ul>
<li id="1"><a href="http://example.com" target="_blank">Go home</a></li>
will be parsed as node.data.href = "http://example.com"
,
node.data.target = "_blank"
.
It is possible to pass additional tree meta-data with the container or outer
<ul>
element:
<div id="tree" data-foo="bar">
<ul data-json='{"baz": "x", "like": 42}'>
<li id="1">node 1</li>
The additional properties will be added to the trees data
object:
tree.data.foo = "bar"
and tree.data.like = 42
.
source
may be a deferred promise as returned by $.ajax()
or $.getJSON()
.
$("#tree").fancytree({
source: $.ajax({
url: "/myWebService",
dataType: "json"
}),
lazyLoad: function(event, data){
data.result = $.getJSON("ajax-sub2.json");
},
[...]
});
source
may be callback that returns one of the above data formats.
source: function(){
return [{title: "node1", ...}, ...];
}
Single nodes may be marked 'lazy'. These nodes will generate ajax request when expanded for the first time. Lazy loading allows to present hierarchical structures of infinite size in an efficient way.
For example:
$("#tree").fancytree({
// Initial node data that sets 'lazy' flag on some leaf nodes
source: [
{title: "Child 1", key: "1", lazy: true},
{title: "Folder 2", key: "2", folder: true, lazy: true}
],
// Called when a lazy node is expanded for the first time
lazyLoad: function(event, data){
var node = data.node;
// Load child nodes via ajax GET /getTreeData?mode=children&parent=1234
data.result = {
url: "/getTreeData",
data: {mode: "children", parent: node.key},
cache: false
};
},
[...]
});
The data format for lazy loading is similar to that of the source option.
If node.lazy
is true and node.children
is null
or undefined, the lazyLoad
event is triggered, when this node is expanded.
Note that a handler can return an empty array ([]
) in order to mark the node
as 'no children available'. It then becomes a standard end-node which is no
longer expandable.
Lazy Loading Sequence Diagram
See the enableAspx
option to process ASPX WebMethod JSON object inside "d" property.
http://flask.pocoo.org/docs/security/#json-security
postProcess: function(event, data) {
// either modify the ajax response directly
data.response[0].title += " - hello from postProcess";
// or setup and return a new response object
// data.result = [{title: "set by postProcess"}];
},
// Reload the tree from previous `source` option
tree.reload().done(function(){
alert("reloaded");
});
// Optionally pass new `source`:
tree.reload({
url: ...
}).done(function(){
alert("reloaded");
});
This can be achieved using standard functionality and this simple pattern:
loadChildren: function(event, data) {
data.node.visit(function(subNode){
if( subNode.isUndefined() && subNode.isExpanded() ) {
subNode.load();
}
});
}
Documentation Home - Project Page - Copyright (c) 2008-2022, Martin Wendt (https://wwWendt.de)