Search code examples
javascriptsortingjstree

jsTree sort function recycling


I have multiple jstrees on my hands. For each I added the sort plugin and configured:

  "core": { .. },
  "plugins": ['sort', ..],
  "sort": action_sort,
  ...

I then proceeded to write the following problematic function:

/** @param id_node{1,2}: Despite of what can be read here: https://www.jstree.com/api/#/?f=$.jstree.defaults.sort
 *   this function will receive 2 strings with the _id_s of the nodes to be sorted, not the nodes themselves.
 * @return 1 or -1. Will cause the nodes to be sorted alphanumerically using String.localeCompare(..). */
function action_sort(id_node1, id_node2)
{
    let node1 = $('#navtree').jstree(true).get_node(id_node1);
    let node2 = $('#navtree').jstree(true).get_node(id_node2);
    let code = node1.text.localeCompare(node2.text);
    return (code >= 0) ? 1 : -1;
}

The problem being that hard-coded string #navtree that obviously will only work for the very tree with this very id.

Now, in the documentation they state that the sorting function is executed in the tree's context. So I proceeded to experiment with $(this) obtaining a convoluted very large internal data structure on the growing tree.

Further experimentations attempted to find the first parent of $('#'+id_node1) holding the role='tree' attribute. However, at the time of sorting the node is still unobtainable this way.

Of course I might monkey around with currying or autogenerating custom sort functions for each tree.

But the real question is: Is there a simpler way for my action_sort(id_node1, id_node2) function to know the tree it is running in, exploiting that it is run in "the tree's context"? Or more to the point: To get a handle from which I might call .get_node(node_id)?


Solution

  • If you look at the default sort handler $.jstree.defaults.sort function, you would see that it uses a get_text function in the function's context. You could use this function in you code for any jsTree instance

    function (id_node1, id_node2) {
        return this.get_text(id_node1).localeCompare(this.get_text(id_node2));
    }