binding my own event handler to click.jstree for individual nodes

5,615 views
Skip to first unread message

Kevin Pauli

unread,
Jun 22, 2010, 5:33:05 PM6/22/10
to jsTree
I am wanting to use jstree as a navigation mechanism, where the user
clicks on nodes in the tree to cause different content to be loaded in
a different pane.

How would one bind event handlers that get fired when the user clicks
on a node?

As a simple test I tried this:

var treeNode = $('<li/>')
var treeNodeLink = $('<a/>').appendTo(treeNode);
treeNodeLink.text('node text');
treeNodeLink.bind('click.jstree', function() {
alert('clicked ' + treeNode.text());
});

But it doesn't seem to do anything.

vakata

unread,
Jun 23, 2010, 3:51:16 AM6/23/10
to jsTree
Jut bind to the "select_node.jstree" event.

Regards,
Ivan

Kevin Pauli

unread,
Jun 23, 2010, 9:07:43 AM6/23/10
to jsTree
Thanks for the response! I tried that too... All the examples I can
find bind the event to the entire tree, and then use the data.rslt.obj
to find out which node was selected. Notice that I am wanting to bind
to the <li/> itself, not to the whole tree (the <ul/>. I want to do
it this way so that I don't have to go find the node that was
selected, it would be available in the closure. Binding to the
individual <li/> elements would really fit nicely with the rest of my
architecture.

Is it perhaps not working because the jstree method destroys the
original jquery <li/> objects, and recreates them? That would destroy
any event that I had already bound to the <li/>. That would also
explain some other odd behavior I am seeing... I have attached some
data to my <li/> elements using the jQuery data() function, and when I
try to retrieve it later, in response to the selected_node event, the
data is gone!

Does anyone have any suggestions for how to make the jstree() method
(using the html_data plugin) keep my original <li/> elements?

Kevin Pauli

unread,
Jun 23, 2010, 9:55:21 AM6/23/10
to jsTree
Here is what I am trying. I get the tree created with the 5 nodes,
but I can't seem to get the binding to select_node on individual nodes
to work.

<html>
<head>
<title>Test Page</title>
<script type="text/javascript" src="../thirdparty/jquery-ui-1.8.2/
development-bundle/jquery-1.4.2.js">
</script>
<script type="text/javascript" src="../thirdparty/jsTree.v.1.0rc/
jquery.jstree.js">
</script>
</head>
<body>
<div id="content"/>
<script type="text/javascript">
$(function(){
var myTree = $('<ul/>').appendTo($('#content'));
for (var i = 1; i <= 5; i++) {
var node = $('<li><a>Node ' + i + '</a></
li>').appendTo(myTree);

node.bind('select_node.jstree', function(event, data){
alert('clicked node ' + i);
});
}
myTree.jstree({
"plugins": ["themes", "html_data", "ui"]
});
});
</script>
</body>
</html>

Kevin Pauli

unread,
Jun 23, 2010, 10:04:51 AM6/23/10
to jsTree
And here is another way I've tried. This is binding to the whole tree
(which I don't like, but I can live with), however what I can't live
with is how it's blanking out my data! The first alert tells me the
node I clicked on but the second alert always says "data: null".

<html>
<head>
<title>Test Page</title>
<script type="text/javascript" src="../thirdparty/jquery-ui-1.8.2/
development-bundle/jquery-1.4.2.js">
</script>
<script type="text/javascript" src="../thirdparty/jsTree.v.1.0rc/
jquery.jstree.js">
</script>
</head>
<body>
<div id="content"/>
<script type="text/javascript">
$(function(){
var myTree = $('<ul/>').appendTo($('#content'));
for (var i = 1; i <= 5; i++) {
var node = $('<li><a>Node ' + i + '</a></
li>').appendTo(myTree);
node.data('myData', 'data for node ' + i);
}

myTree.bind('select_node.jstree', function(event, data){
var rsltObj = data.rslt.obj;
alert('clicked: ' + rsltObj.text());
alert('data: ' + rsltObj.data('myData'));

vakata

unread,
Jun 23, 2010, 10:18:36 AM6/23/10
to jsTree
Try replacing the last two blocks with this:

$("#content")
.jstree({
"plugins": ["themes", "html_data", "ui"]
})
.bind("select_node.jstee", function (event, data) {
alert(data.inst.get_text(data.rslt.obj));
alert(data.rslt.obj.data("myData"));
});

1) You need to specify the container (not the UL node) as the jstree
selector
2) Binding is also done on the same container - internally event
delegation is used

Cheers,
Ivan

Kevin Pauli

unread,
Jun 23, 2010, 10:19:51 AM6/23/10
to jsTree
Well, I've worked around the issue by storing my node-related data in
the tree itself (the top-level <ul/>) and then looking it up when the
event fires. Not ideal... it would be more jQuery-friendly to
preserve the existing <li/> elements when using the "html_data"
plugin.

Still... very nice widget and I appreciate the work!

Pls consider preserving existing <li/> elements in a future release,
as well as supporting binding to individual nodes.

vakata

unread,
Jun 23, 2010, 10:28:45 AM6/23/10
to jsTree
Well,

actually the LI nodes are preserved ... just the needed CSS classes
are applied :)
As for individual binding - event delegation is a lot faster and I
cannot think of a downside :) Why do you need to bind individually -
in the event you get the individual node selected - just filter out
nodes you do not need to process.

Cheers,
Ivan

Kevin Pauli

unread,
Jun 23, 2010, 2:47:27 PM6/23/10
to jsTree
Sorry, that was just an assumption I was making about not preserving
the original nodes. If you are preserving them then do you have an
explaination for why the data I attached with jQuery.data() is
disappearing, causing "data: null" to be displayed in the alert box in
this example?

vakata

unread,
Jun 23, 2010, 4:36:18 PM6/23/10
to jsTree
Sorry about that - I will fix it tomorrow - I located it :)

Cheers,
Ivan

vakata

unread,
Jun 25, 2010, 3:35:07 AM6/25/10
to jsTree
Fixed in the latest commit - I actually used the original HTML, but
not the nodes, so that data was lost. Now it is OK.

Cheers,
Ivan
Reply all
Reply to author
Forward
0 new messages