Skip to content
Martin@MBP edited this page Mar 1, 2014 · 30 revisions

About Fancytree persistence extension.

Store and restore tree status using cookies:

  • Store key of active and focused node as cookie.
  • Store key list of expanded and selected nodes as cookie.
  • Restore tree state from cookies when page is reloaded.

Example

In addition to jQuery, jQueryUI and Fancytree, include jquery.cookie.js and query.fancytree.persist.js:

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" type="text/javascript"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js" type="text/javascript"></script>
  <script src="js/jquery.cookie.js" type="text/javascript"></script>

  <link href="skin-win8/ui.fancytree.css" rel="stylesheet" type="text/css">
  <script src="js/jquery.fancytree.js" type="text/javascript"></script>
  <script src="js/jquery.fancytree.persist.js" type="text/javascript"></script>

Enable persist extension and pass options:

$("#tree").fancytree({
  extensions: ["persist"],
  checkbox: true,
  persist: {
    // Available options with their default:
    cookieDelimiter: "~",    // character used to join key strings
    cookiePrefix: undefined, // 'fancytree-<treeId>-' by default
    cookie: { // settings passed to jquery.cookie plugin
      raw: false,
      expires: "",
      path: "",
      domain: "",
      secure: false
    },
    overrideSource: false,  // true: cookie takes precedence over `source` data attributes.
    types: "active expanded focus selected"  // which status types to store
  },
  [...]
});

Clear all status types:

$("#tree").fancytree("getTree").clearCookies("active expanded focus selected");

Persistence in a lazy world

If the tree uses lazy loading, things may get complicated. For example it may not be possible to re-activate a node on page reload, if this node is not part of the initial tree.
In this case we have to load all parent nodes before.

Two options are available:

  1. Use the loadKeyPath() to re-load nested nodes.
  2. Let the server evaluate the list of expanded nodes and return data accordingly.
Use loadKeyPath()

TODO

Recipes

[Howto] Support persistence in the backend

A sample using Python and CherryPy.

The server reads the key list of expanded nodes from the cookie and adds these child nodes to the response: (Python pseudo code)

def get_child_data_list(node_key, expanded_key_list):
    result_list = []
    # Read `node` objects from our database
    child_node_list = get_child_nodes(node_key)
    # Convert nodes to Fancytree data dicts
    for node in child_node_list:
        data = {"title": node.name, 
                "key": node.guid,
                "lazy": True}
        if node.guid in expanded_key_list:
            data["expanded"] = True
            data["children"] = get_child_data_list(node.guid, expanded_key_list)
        result_list.append(data)
            
    return result_list

@cherrypy.exposed
def getTreeNodes(rootKey):
    """This is the web service handler"""
    if rootKey == "root":
        expanded_key_list = get_cookie_value("fancytree-1-expanded").split("~")
    else:
        expanded_key_list = []

    result_list = get_child_data_list(rootKey, expanded_key_list)
    return to_json(result_list)
$("#tree").fancytree({
  [...]
  source: {
    url: "getTreeNodes",
    data: {rootKey: "root"}
  }, 
  lazyLoad: function(event, data){
    url: "getTreeNodes",
    data: {rootKey: data.node.key}
  }, 
  [...]
});
Clone this wiki locally