Search code examples
javascriptjquerykendo-uikendo-treeview

Remember nodes expanded between page navigation


In my Asp.NET MVC 4 application, Page 1 has a Kendo treeview. On Page 1, user can click on a node X and expand its descendant nodes as deep as he wants. Then he clicks on node X and from there he goes to Page 2; he does some work for node X. Next, from Page 2, the user can go back to Page 1. I'd like once the user is back to Page 1, Page 1 should be able to show the same expanding & collapse status for node X and other nodes as originally. Please advise. Thank you.

Details:

Page 1, user clicks on Node X and expand its descendant nodes like:

  • Tree root
    • Node A
    • Node B
    • Node X
      • Node X.1
        • Node X.1.1
        • Node X.1.2
      • Node X.2
      • Node X.3
        • Node X.3.1
    • Node Y
    • Node Z
      • Node Z.1
      • Node Z.2

Then the user clicks on Node X and goes to Page 2 and does some work. Then, he click on a button or link to be back to Page 1. Once he is on Page 1 again, I would like the treeview widget should be able to show nodes as mentioned above.


Solution

  • Well, there are a bunch of problems to solve:

    1: How to maintain state between page reloads

    Some of your options: cookies, session / local storage, saving it to the server (e.g. by sending an ajax request to the server)

    2: How to know which nodes in a treeview are expanded

    Something like this should work:

    var expandedNodes = $("#treeview").find(".k-item").filter(function () {
        return $(this).attr("data-expanded") === "true";
    });
    

    3: How to serialize the list of expanded nodes so it can be restored

    This really depends on how you create your treeview: do you have a data source so that each node has a unique id? do you create the treeview from an html structure (<ul></ul>)? does each node have a unique text or can there be duplicates?

    Assuming each node has a unique text, you could simply serialize the text of each expanded node, e.g. in this form (with the pipe char as a delimiter):

    // note that you'd need to do this sorted by the node's nesting level, 
    // i.e. first level nodes need to come first, then second level etc,
    // so you can expand in the same order
    var serialized = "text1|text2|text3"; // store this using cookies or w/e 
    

    A simple implementation (which may not be enough for your case):

    $(expandedNodes).each(function () {
        serialized += tree.text(this) + "|";
    });
    

    and then ..

    4: How to deserialize the expanded nodes and expand the treeview accordingly

    You could do this to restore it:

    // load serialized from wherever you stored it, then ..
    var deserialized = serialized.split("|");
    $(deserialized).each(function () {
        var node = tree.findByText(this);
    
        tree.expand(node);
    });
    

    JSFiddle demo