filter filtered list with multiple words

799 Views Asked by At

I using the Jstree Plugin

I have a doubt, I wonder if it is possible to filter by multiple words as follows:

With the following structure:

Root node
    One Child Node
        node 1
        node 2
        node 3
    Two Child Node
        node 4
        node 5
        node 6

With the following search:

one child node 1

Bring as a result:

Root node
    One Child Node
        node 1

Have this possibility?

EDIT 1 The search code:

$('#jstree-q').keyup(function () {
            if(to) { clearTimeout(to); }
            to = setTimeout(function () {
                var v = $('#jstree-q').val();
                $('#jstree').jstree(true).search(v);
            }, 250);
        });
1

There are 1 best solutions below

2
On

I only just spotted that your query relates to jstree, but meanwhile I spent a happy half-hour building a possible solution for this just in jquery. I'll post it anyway, because it might be helpful for you.

The demo is here: http://jsfiddle.net/sifriday/ezhj1Lbt/

The approach I use was to build a path for li elements; for example the 'node 1' element would have the path 'Root node / One Child Node / node 1'. I then break the search phrase down into words, so your phrase 'One Child node 1' gives the array ['One', 'Child', 'node', 1']. I then show only the nodes where the path matches every word in the array. Here's the jquery code to build the paths:

function process(li, path) {
    $.data($(li).get(0), 'path', path)

    $(li).children("ul").each(function(jdx, ul) {
         $(ul).children("li").each(function(idx, child_li) {
             process($(child_li), path + " / " + $(child_li).children("span").text())
         });
    }); 
}

$(".search-tree>li").each(function(idx, li) {
    process($(li), $(li).children("span").text())    
});

and here's the jquery code to handle the search (this is case-sensitive, so you should search for 'One Child' rather than 'one child'):

$("#search-input").keyup(function() {
    // Hide everything to start with
    $(".search-tree li").hide()

    // Extract all the words from the search box
    var words = $("#search-input").val().split(" ");

    // Now go through the tree, and show <li>s that match the words
    $(".search-tree").find("li").each(function(idx, li) {
        // We only test the nodes, ie, the <li>s with no children
        if ($(li).find("ul").length == 0) {
            // Assume we will show the node...
            var show = true;
            // ...but decide to hide it if one of the words doesn't exist in the path
            $(words).each(function(jdx, word) {
                if ($.data($(li).get(0), 'path').indexOf(word) == -1) {
                    show = false
                }
            })
            // If the verdict was show=true, show this node and its parents
            if (show) {
                $(li).show()
                $(li).parents("li").show()
            }
        }
    });
});

I don't know my way around jstree, but it is possible you could rework this approach into the $.jstree.defaults.search.search_callback that Samuel mentions above.