Thursday, August 21, 2008

Oh ExtJS TreePanel Click, wherefore art thou?

ExtJS is a high quality JS UI library that really eases the cross-platform blues when it comes to designing online apps. Unfortunately I find the documentation can be a be a little obtuse from time to time.

Even the trusty Google librarian cannot answer some of the questions that pop up right off the bat and a fair amount of searching is required to get some info.

TreePanel Click
I have a TreePanel that I populate through lazy loading to save the amount of data I need to send off to the client in any one request. Unfortunately for the life of me I could not work out how to determine which node in the tree was clicked (so that I could fire off an Ajax request to populate another panel with data related to the clicked node).

Attaching Events
The first thing to do would obviously be to attach a click event listener somewhere so that we can pick up when were being prodded. If you're not familiar to JavaScript and ExtJS specifically you'd be inclined to attach an event to each of the nodes.

This is wasteful in the browser context as you should be taking advantage of event bubbling. So we simply attach a listener to the whole tree component:
  Ext.onReady(function(){
// Create initial root node
root = new Ext.tree.AsyncTreeNode({
text: 'Invisible Root',
id:'0'
});

// Create the tree
tree = new Ext.tree.TreePanel({
loader: new Ext.tree.TreeLoader({
url:'/companies',
requestMethod:'GET',
baseParams:{format:'json'}
}),
renderTo:'company-tree',
root: root,
rootVisible:false
});

// Expand invisible root node to trigger load of the first level of actual data
root.expand();

// Listen for mouse clicks
Ext.get('company-tree').on("click", function(){
// Code to determine which node was clicked ...
});
});
Where did that click go?
Never having used the TreePanel control before I had no real inkling how I was going to reap the relevant id from the node that was clicked. I tried several approaches but nothing was bearing any fruit till I found this article on the ExtJS forums discussing something similar.

Armed with a new weapon I was able to refactor the listener:
  // Listen for mouse clicks
Ext.get('company-tree').on("click", function(){
node = tree.getSelectionModel().getSelectedNode();
console.log("You clicked on", node.id);
});

That'll do.


2 comments:

Adam said...

Cool to see you getting into EXTJS - hows the new job going?

David M said...

You can just add the click listener to the tree panel config (not the nodes the root tree panel). This way you have access to the node and the event.

listeners: {
click: function (node, event) {

}
}

About Me

My photo
I love solving real-world problems with code and systems (web apps, distributed systems and all the bits and pieces in-between).