jsTree Node Expand/Collapse

前端 未结 4 577
故里飘歌
故里飘歌 2021-02-09 08:55

I ran into the excellent jstree jQuery UI plug in this morning. In a word - great! It is easy to use, easy to style & does what it says on the box. The one thing I have n

相关标签:
4条回答
  • 2021-02-09 09:09

    The above answer will construct tree again and again. The below code will open the node and collapse which are already opened and it does not construct tree again.

    .bind("open_node.jstree",function(event,data){
            closeOld(data);
            });
    

    and closeOld function contains:

    function closeOld(data)
    {
        if($.inArray(data.node.id, myArray)==-1){
                myArray.push(data.node.id);
                if(myArray.length!=1){
                    var arr =data.node.id+","+data.node.parents;
                    var res = arr.split(",");
                    var parentArray = new Array();
                    var len = myArray.length-1;
                    for (i = 0; i < res.length; i++) {
                        parentArray.push(res[i]);
                    }
                    for (var i=len;i >=0;i--){
                        var index = $.inArray(myArray[i], parentArray);
                    if(index==-1){
                        if(data.node.id!=myArray[i]){
                        $('#jstree').jstree('close_node',myArray[i]);
                            delete myArray[i];
                        }
                    }
                    }
            }
        }
    
    0 讨论(0)
  • 2021-02-09 09:12

    jsTree is great but its documentation is rather dense. I eventually figured it out so here is the solution for anyone running into this thread.

    Firstly, you need to bind the open_node event to the tree in question. Something along the lines of

    $("tree").jstree({"themes":objTheme,"plugins":arrPlugins,"core":objCore}).
    bind("open_node.jstree",function(event,data){closeOld(data)}); 
    

    i.e. you configure the treeview instance and then bind the open_node event. Here I am calling the closeOld function to do the job I require - close any other node that might be open. The function goes like so

    function closeOld(data)
    {
        var nn = data.rslt.obj;
        var thisLvl = nn;
        var levels = new Array();
        var iex = 0;
        while (-1 != thisLvl)
        {
            levels.push(thisLvl);
            thisLvl = data.inst._get_parent(thisLvl);
            iex++;
        }
    
        if (0 < ignoreExp)
        {
            ignoreExp--;
            return;
        }
    
        $("#divElements").jstree("close_all");
        ignoreExp = iex;
        var len = levels.length - 1;
        for (var i=len;i >=0;i--) $('#divElements').jstree('open_node',levels[i]);
    }
    

    This will correctly handle the folding of all other nodes irrespective of the nesting level of the node that has just been expanded.

    A brief explanation of the steps involved

    • First we step back up the treeview until we reach a top level node (-1 in jstree speak) making sure that we record every ancestor node encountered in the process in the array levels
    • Next we collapse all the nodes in the treeview
    • We are now going to re-expand all of the nodees in the levels array. Whilst doing so we do not want this code to execute again. To stop that from happening we set the global ignoreEx variable to the number of nodes in levels
    • Finally, we step through the nodes in levels and expand each one of them
    0 讨论(0)
  • 2021-02-09 09:18

    Yet another example for jstree 3.3.2. It uses underscore lib, feel free to adapt solution to jquery or vanillla js.

    $(function () {
        var tree = $('#tree');
        tree.on('before_open.jstree', function (e, data) {
            var remained_ids = _.union(data.node.id, data.node.parents);
            var $tree = $(this);
            _.each(
                    $tree
                        .jstree()
                        .get_json($tree, {flat: true}),
                    function (n) {
                        if (
                            n.state.opened &&
                            _.indexOf(remained_ids, n.id) == -1
                        ) {
                            grid.jstree('close_node', n.id);
                        }
                    }
            );
        });
        tree.jstree();
    });
    
    0 讨论(0)
  • 2021-02-09 09:23

    I achieved that by just using the event "before_open" and close all nodes, my tree had just one level tho, not sure if thats what you need.

    $('#dtree').on('before_open.jstree', function(e, data){
        $("#dtree").jstree("close_all");
    });
    
    0 讨论(0)
提交回复
热议问题