state plugin: how to do not save state for certain nodes?

2,394 views
Skip to first unread message

Vladimir

unread,
Jan 28, 2014, 1:59:08 PM1/28/14
to jst...@googlegroups.com
Hello!

I use jstree 3beta5 with state plugin. Several nodes have too many children. I want to keep a state of the such nodes always closed on page refresh to save a page loading time (I use ajax to open each node).

how to do not save state for certain nodes to keep them always closed on page refresh?

Thank you,
vladimir

Temuri Imnaishvili

unread,
Jan 28, 2014, 2:04:30 PM1/28/14
to jst...@googlegroups.com
+1

Would be nice to be able to supply array of nodes to persist state.

Thanks!

Vladimir

unread,
Jan 28, 2014, 5:02:06 PM1/28/14
to jst...@googlegroups.com
It seems that "array of nodes" is not suitable for an ajax tree, because this list changed on every user click. I never know the full list of such nodes on the time generationg json for root node.

May be one of these methods more suitable:
* additional attribute in json node format, something like "save_open_state:false|true|always_open|always_closed"
* additional config option for state plugin to set max children. For example "max_children:200"

James Gaunt

unread,
Jan 28, 2014, 6:24:50 PM1/28/14
to jst...@googlegroups.com
Agree this would be a very nice feature for reducing Ajax load.

I'd also suggest an option to only persist state required to open the tree as far as selected node(s).

Ivan Bozhanov

unread,
Jan 29, 2014, 2:49:55 AM1/29/14
to jst...@googlegroups.com
Hi all,

Pull the latest source from github. There is a callback function which you can use to filter state before it is restored. For example to remove selection:
"state" : { "filter" : function (k) { delete k.core.selected; return k; } },
Or to remove opened nodes:
"state" : { "filter" : function (k) { delete k.core.opened; return k; } },
Just examine the object ("k" here) and see what you can remove. Basically every active plugin has it's own key in the object, along with "core". Most plugins don't use state that is why not all your active plugins will have a key here.

Best regards,
Ivan

Vladimir

unread,
Jan 30, 2014, 3:53:29 PM1/30/14
to jst...@googlegroups.com
Hi Ivan,

TypeError: state.core is undefined
https://.../jstree/jstree.js
line: 2335

I have:
1) latest jstree trunk revision (213)
2) "state" : {"filter" : function (k) { alert(JSON.stringify(k.core.open)); return k; },
  "key" : "p57_opened"}

On page reload I see list of opened nodes (displayed in alert-popup), then javascriipt error described above.

Vladimir

unread,
Jan 30, 2014, 4:10:42 PM1/30/14
to jst...@googlegroups.com
I get this error when just 3 nodes are open on page refresh.
If one or two nodes are open - it works without this error.

Vladimir

unread,
Jan 30, 2014, 4:30:53 PM1/30/14
to jst...@googlegroups.com
mo info...

No matter if I use or not the "filter" config option of "state" plugin.
I get this error every tyme on page refresh.

This error appears in revision 213 or 212.
Revision 211 works without error (in this refision "filter" for "state" was added)

Thank you,
Vladimir

Ivan Bozhanov

unread,
Jan 31, 2014, 2:56:54 AM1/31/14
to jst...@googlegroups.com
Thank you for the detailed information - do ahead and get the latest code form github - it should work.

Vladimir

unread,
Jan 31, 2014, 2:24:35 PM1/31/14
to jst...@googlegroups.com
Hi Ivan,

Now it works, but... I still can not understand how this new "filter" config option can be useful for me.

This function executed immediately after loading root node. Right?
At this point I do not know should I open nodes from "k" array or should not. The decision is based on number of node's children. To know it I should load all nodes from "k" array before. But I do not want to load large nodes using state plugin to save tree loading time.

I think, the only point to know should I restore node state or not - is save_sate event.

When user open a node, I can see number of children and decide to restore (o do not restore) node state on future page refresh.

How I can use "filter" config option to keep large nodes closed on page refresh? Considering I can get number of node's children only after loading that node.

Than you,
Vladimir

Ivan Bozhanov

unread,
Jan 31, 2014, 3:08:40 PM1/31/14
to jst...@googlegroups.com
Sorry about that, it is not doable with the filter, you will have to dig a bit deeper, like so:
var to = null;
$('#your-tree').bind('open_node.jstree close_node.jstree', function () {
  if(to) { clearTimeout(to); }
  to = setTimeout(function () {
    var s = $.vakata.storage.get('jstree'); // if you use a custom key for state.key - replace jstree with your key
    // remove stuff depending on your criteria
    // you can obtain an instance using $('#your-tree').jstree(true) so that you can check if the node has too many children
    // like foreach s.core.opened -> if (instance.get_node(i).children.length > 0) remove it ... etc
    $.vakata.storage.set('jstree', s); // again - change the key if you configured i
  }, 150); // the timeout and 150 are important!
})

Vladimir

unread,
Feb 6, 2014, 3:23:30 PM2/6/14
to jst...@googlegroups.com
Hi Ivan!

It helps only partially... I followed your recommendation. Now, sometimes node's state not restored, but sometimes it is restored even after removing such node from s.core.open.

I use such code:

  var state_to;
  $('#tree').on('open_node.jstree', function(e,data) {
    if (state_to) { clearTimeout(state_to); }
    state_to = setTimeout(function () {
      var s = $.vakata.storage.get(params.state.key);
      //var instance = $("#tree").jstree(true);
      if (!s) return;
      var index = 0;
      var del = [];
      s.core.open.forEach(function(i) {
        if (data.instance.get_node(i).children.length > 100)
          del.push(index);
        index++;
      });
      del.forEach(function(i) {
        s.core.open.splice(i,1);
      });
      $.vakata.storage.set(params.state.key, s);
    }, 150);
    // I need tooltip
    data.instance.get_node(data.node, true).find('a').tooltip();
  });

I found that after deleting large node from s.core.open this node returns back to this array. How it is possible?

Thank you,
Vladimir

PS. Sorry for my delay.
Reply all
Reply to author
Forward
0 new messages