jQuery TreeView Ajax modification

October 18th, 2007

As part of my job, I wind up writing a lot of little gizmos, hacks, and toys for customers. One of my recent projects was to implement a sort order manager for items inside a taxonomy.

The path I chose to go down for the user interface was to use a treeview to display the categories of the taxonomy, and let the user order the children of a given node when they selected one. The problem is that the clients implementation has almost 1000 nodes in the taxonomy, and nearly 20000 pieces of content associated to those nodes. Obviously this was a case where ajax was going to come into play.

I began by using the ASP.Net treeview control - and quickly ran into significant hurdles. Silly microsoft, they force you to build the entire tree in memory before rendering the control. So even though you can use Ajax to load the information piecemeal to the browser, you’ve got a 1000 item treenode structure sitting on your server. Since a significant consideration is the initial render time for this page, that was not a very good option.

So, I decided to use jQuery and Myles Angell’s wonderful treeView plugin in order to render it. However this is still not Ajax, even though it uses extremely clean HTML. So I set about modifying the plugin to meet my specific needs.

The way the treeView plugin is laid out, the expansion click hits the function toggler(). toggler() then swaps the css classes that decide whether to show a + or - next to the node, and whether the “ul” beneath the “li” for the node we are on is hidden or not. It is extremely straightforward. In order to make it dynamically load the children, I have two main problems:

  • How do I tell the treeview plugin that children are in fact available, so that it doesn’t show the expand button if there are no children, and
  • Making it retrieve the actual HTML for the children.

I opted to solve the first problem in a simple way - if there are children for a given node, it appends an empty ul tag to the item, making it expandable. So the initial html works like so:

<ul id="#root">
  <li>Has children
    <ul></ul>
  </li>
  <li>Has no children</li>
</ul>

The fix for making it Ajax follows closely behind: in toggler(), we add the following code:

1  $$ = $(this).parent().find(">ul");
2  if($$.find(">li").length == 0)
3     //do ajax call to fill it
4     $.get(   settings.postback,
5        { expand:$(this).parent()[0].id },
6        function(msg){ 
7           $$.html(msg);
8           $$.treeview({
9              persist: "location",
10             collapsed: true,
11             unique: true,
12             postback: settings.postback
13          });
14       }
15    );

I’ve done a couple things here. The first thing to notice is that line “postback: settings.postback”. This means that you can have it load the additional data from any location - not just the URL the page originally came from. This means you have to add one parameter to your instantiation - something like ‘postback: “ajax.aspx”‘. Now let’s go through the mod line by line. 

On line 1, we find the list for the node we are currently looking at. We don’t trap for a zero length array here, because technically this action can only be triggered by an item which has a “ul” tag in it. Line 2 checks if we have any nodes already loaded for this parent node. If we do, then the rest of this code is skipped and we display what has already been retrieved. If we don’t have any nodes under this node, then we go ahead and retrieve the raw html from the server that goes within this node - a list of “li”s. We insert the html into the “ul” tag, then we initialize it by calling the treeview extension with some default options.

As you can see this is an extremely simple mod, but totally effective. It’s also much more desirable than hacking the ASP.net treeview control to do something simple.

Many thanks to Myles Angell for writing such a great plugin!

1 Comment(s)

  1. Comment by LeKhoi on December 5, 2007 11:50 pm

    Works like a charm, thanks so much for your work, really like the expand argument :-)

Comments RSS TrackBack Identifier URI

Leave a comment