Wednesday, February 26, 2014

JQuery async-treeview with unique set to true

I’ve been working in a project which uses JQuery treeview plugin to display a set of data which are queried from a database. This projects implementation is a bit old and so is the plugin. But it showed fairly well performance until recent where we had a heavy load of data added to our database. It became extremely slow loading, updating and adding folders to structure so that we frequently got unresponsive script errors.
Basic script to load a treeview is as follows:
   $("#tree").treeview({
        collapsed: true,
        animated: "medium",
        control: "#sidetreecontrol",
        unique: true
    });

Treeview as it is, requires whole tree structure available at the client side before render. So that is a lot of js to process mostly in browsers like IE. There were two options, one was to move on to newer and more efficient plugin and other was to try to use jquery.treeview.async.js which ships with treeview plugin to load data asynchronously.
I considered the second option first and found that with this extra code I could load the tree in chunks. In other words, in initial load it only needs root folder structure and when a node get expanded sub tree is loaded sending an ajax request back to server. It looked like exactly what we were looking for. So I went ahead added relevant functionality to use jquery.treeview.async.js following this blog post.
So that is the same script with few additional parameters ‘url’ and ‘ajax’:
$("#tree").treeview({
        collapsed: true,
        animated: "medium",
        control: "#treecontrol",
        unique: true,
 url: '/Home/GetTreeData/',
        ajax: {
            type: 'post'
        }
    });

It all worked fine until I set unique: true in the treeview because that’s how it was in pervious implementation. There is only one node open at a time when this attribute is set to true. The async treeview with unique set to true is the worst nightmare we could have because it started to send ajax requests for each and every node in the same level for a single expand or collapse. This happened because JQuery treeview handles unique by toggling the all other nodes. And async treeview extends the toggle function to send ajax requests and get child nodes which results a sequence of ajax calls back and forth. So setting unique true in an async tree was definitely not an option if efficiency is what you are after.
So I found a little work around to achieve the same functionality after some research. I simply extended the toggle function to send a second request to collapse any node that is already expanded in the same level for each click. And it reduced the amount of Json calls in a considerable amount. So it works the same as unique set to true but doesn’t send unnecessary ajax requests toggling all same level nodes.
Here is the code:
$("#tree").treeview({
        collapsed: true,
        animated: "medium",
        control: "#treecontrol",
        unique: false,
 url: '/Home/GetTreeData/',
        ajax: {
            type: 'post'
        },
        toggle: function () {
            var collpsable = $(this).parent().find(".collapsable");
            var id = $(this).attr("id")
            $.each(collpsable, function (index, element) {
                if (element.id !== id) {
                    element.children[0].click();
                }
            });
        }
    });



No comments:

Post a Comment