Question

I'm following this approach to expanding and collapsing all nodes in client JavaScript: http://www.telerik.com/help/aspnet/treeview/tree_expand_client_side.html

However, it's taking a REALLY long time to process this, and after expanding then collapsing, I get the "script unresponsive" error, so I was wondering if there was a way to speed this up for a rather large tree? Is there a better way to parse it? Currently, the tree is 4 levels deep.

Thanks.

Was it helpful?

Solution

I got around the "script unresponsive" errors by expanding and collapsing the tree asynchronously. In addition, I expand from the bottom (so you can see the nodes expand) and collapse from the top, but only when it gets to the last node in each branch, so visually it's far more interesting to the user. They can actually see it happen, and if it's not fast (IE7 and before is particularly slow), it's at least entertaining while they wait.

var treeView, nodes;

function expandAllNodesAsynchronously() {
    if (<%= expandedLoaded.ToString().ToLower() %>) {
        treeView = $find("<%= tv.ClientID %>");
        nodes = treeView.get_allNodes();
        if (nodes.length > 1) {
            doTheWork(expandOneNode, nodes.length);
        }
        return false;
    } else
        return true;
}

function expandOneNode(whichNode) {
    var actualNode = nodes.length - whichNode;
    if (nodes[actualNode].get_nextNode() == null) {
        nodes[actualNode].get_parent().expand();
    }
}

function collapseAllNodesAsynchronously() {
    treeView = $find("<%= tv.ClientID %>");
    nodes = treeView.get_allNodes();
    if (nodes.length > 1) {
        doTheWork(collapseOneNode, nodes.length);
    }
}

function collapseOneNode(whichNode) {
    if (nodes[whichNode].get_nextNode() == null && nodes[whichNode].get_parent() != nodes[0]) {
        nodes[whichNode].get_parent().collapse();
    }
}

function doTheWork(operation, cycles) { //, callback
    var self = this, // in case you need it
        cyclesComplete = 1,
        batchSize = 10; // Larger batch sizes will be slightly quicker, but visually choppier

    var doOneBatch = function() {
        var c = 0;
        while(cyclesComplete < cycles) {
            operation(cyclesComplete);
            c++;
            if(c >= batchSize) {
                // may need to store interim results here
                break;
            }
            cyclesComplete++;
        }
        if (cyclesComplete < cycles) {
            setTimeout(doOneBatch, 1); // "1" is the length of the delay in milliseconds
        }
        else {
            // Not necessary to do anything when done
            //callback(); // maybe pass results here
        }
    };

    // kickoff
    doOneBatch();
    return null;
};

OTHER TIPS

Start off getting your nodes with yourtreeViewInstance.get_nodes(), and then the child nodes as eachChildNode.get_nodes() and so on down the hierarchy.

Then you can expand each item by calling .set_expanded(true); on each node you want to expand.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top