Showing animated icon while populating TreeView with PopulateOnDemand

20. May 2009

TreeView server control in asp.net can use AJAX behind the scenes to populate child nodes when user clicks on the expand icon next to each node. If the loading process is fast, it works perfectly. But when child nodes are generated by a slow process (like a slow database query) then user experience is unacceptable. User would click on the expand and nothing would happen for a long time, leaving user wondering if the click really did anything.

In such scenarios, an animated icon that lets user know data is being loaded would help a lot. I spent couple of hours searching on the net to find a solution, but didn't find much. Finally, after some experiments, and some scattered information I found about client-side interaction with TreeView, I got my Progress Animation working. The trick was to define a client-side OnClick event for TreeView control, calling a JavaScript function. In that function, if the element that received the Click event is an IMG element (which is used to show the "Expand" icon) then I replace that with my animated GIF icon. That is all.

TreeView control is defined like this:


<asp:TreeView ID="TreeView1" runat="server" ShowLines="true"     onclick="OnExpandClick(event);" ontreenodepopulate="TreeView1_TreeNodePopulate"> </asp:TreeView>

The JavaScript function looks like this:

function OnExpandClick(evt) {
    var evt = evt || window.event; // event object
    var obj = evt.target || window.event.srcElement; // event target
    if (obj.tagName.toLowerCase() == "img" && obj.alt.toLowerCase().substring(0, 6) == "expand") {
        obj.src = "../images/ajax-loader.gif";
        obj.alt = "Loading ...";
    }
}

TreeView , , ,

Comments (2) -

5/26/2009 7:07:06 PM #
Great tip. Minor problem when user expand another node when the previous one not finished loading - the populating was cancelled by the loading image keeps unchanged.

Change the javascript as following will solve the problem. It saves the currently expanding node and revert the values back if necessary:

var prevExpandingNode;
var prevExpandingNodeSrc;
var prevExpandingNodeAlt;

function OnExpandClick(evt) {
    var evt = evt || window.event; // event object
    var obj = evt.target || window.event.srcElement; // event target
    if (obj.tagName.toLowerCase() == "img" && obj.alt.toLowerCase().substring(0, 6) == "expand") {
        if (prevExpandingNode != undefined) {
            if (prevExpandingNode.alt == "Loading ...") {
                prevExpandingNode.src = prevExpandingNodeSrc;
                prevExpandingNode.alt = prevExpandingNodeAlt;
            }
        }
        prevExpandingNode = obj;
        prevExpandingNodeSrc = obj.src;
        prevExpandingNodeAlt = obj.alt;
        obj.src = "/images/Loading.gif";
        obj.alt = "Loading ...";
    }
}
Sreenu Vadluri
Sreenu Vadluri
9/12/2009 4:12:25 PM #
hi,
Thank you very much it is working fine.