7

I would like to start using Dynatree on my page, however I will probably need searching my tree by name. Do you know maybe how to do this?

JaSmin
  • 221
  • 2
  • 7
  • Refer this http://www.designchemical.com/blog/index.php/jquery/live-text-search-function-using-jquery/ Dynatree is a simple UL > LI – Rahul Sep 22 '12 at 04:12

4 Answers4

15

I needed to have not only matching nodes, but also the whole paths to these nodes. I wrote this functionality and it works for me.

Modifications for library:

var clear = true;

DynaTreeNode.prototype.search = function(pattern){

    if(pattern.length < 1 && !clear){
        clear = true;
        this.visit(function(node){
            node.expand(true);
            node.li.hidden = false;
            node.expand(false);
        });
    } else if (pattern.length >= 1) {
        clear = false;
        this.visit(function(node){
            node.expand(true);
            node.li.hidden = false;
        });

        for (var i = 0; i < this.childList.length; i++){
            var hide = {hide: false};
            this.childList[i]._searchNode(pattern, hide);
        }
    } 
},

DynaTreeNode.prototype._searchNode = function(pattern, hide){

    if (this.childList){
        // parent node

        var hideNode = true;
        for(var i = 0; i < this.childList.length; i++){
            var hideChild = {hide: false};
            this.childList[i]._searchNode(pattern, hideChild);
            hideNode = hideNode && hideChild.hide;
        }
        if(hideNode && !this._isRightWithPattern(pattern)){
            this._hideNode();
            hide.hide = true;
        } else {
            hide.hide = false;
        }

    } else {
        // leaf
        if (!this._isRightWithPattern(pattern)){
            this._hideNode();
            hide.hide = true;
        } else {
            hide.hide = false;
        }
    }
},

DynaTreeNode.prototype._isRightWithPattern = function(pattern){
    if((this.data.title.toLowerCase()).indexOf(pattern.toLowerCase()) >= 0){
        return true;
    }
    return false;
},

DynaTreeNode.prototype._hideNode = function(){
    if(this.li) {
      this.li.hidden = true;
    }
}

Use:

$("tree").dynatree("getRoot").search(pattern);
JaSmin
  • 221
  • 2
  • 7
  • Worked like a charm! Thanks! Btw, I think the usage should be `$("#tree")` -- your code is missing the `#`. – SNag Nov 11 '13 at 09:08
  • 3
    I'm trying to implement this, but I'm not sure how to do this. Please clarify for me! I don't know where I put this code. And what is pattern? the text for search?? – Joao Paulo Dec 04 '13 at 12:15
  • Exactly what I need, a pity I can upvote only once :) – mibutec Dec 11 '13 at 16:12
  • Brilliant. Now, after using this code for filter on a search term, I want to select a folder checkbox and have this cause ONLY those child nodes that are NOT hidden to be toggled. Anyone see an easy way to do it? I'll post if I figure it out. – Owen Feb 04 '14 at 21:09
1

There is currently no search function, but you could use something like this (not tested)

var match = null;
tree.visit(function(node){
    if(node.data.title === "foo"){
        match = node;
        return false; // stop traversal (if we are only interested in first match)
    }
});
alert("Found " + match);
mar10
  • 14,320
  • 5
  • 39
  • 64
  • Please add a tested and working search to your next version :) – Elisabeth Jan 30 '13 at 22:46
  • You have an error in your code. you need to check if match found. if there is no match in tree you are showing `Found null` – AaA Jul 05 '16 at 02:46
0

I've done it this way

<style>
span.occurance a.dynatree-title{background-color:#3AFF22;}
</style>


DynaTreeNode.prototype.find = function (needle) {
    needle = (needle || '');
    if (needle.length >= 1) {
        var occurs = [];
        this.visit(function (node) {
            $(node.span).removeClass('occurance'); //remove pervious findings
            if (node.data.title.indexOf(needle) != -1) {
                occurs.push(node);
                node._expandPath();
            }
        });
        for (indx in occurs) { // mark findings
            $(occurs[indx].span).addClass('occurance');
        }
    } else {
        $('span.dynatree-node.occurance').removeClass('occurance');
    }
},
DynaTreeNode.prototype._expandPath = function () {
    var path = [],
        node = this;
    while (node = node.getParent()) {
        path.push(node);
    }
    for (indx in path) {
        path[indx].expand(true)
    }
}

usage:

[your selector].dynatree("getRoot").find('needle');
Saeed
  • 123
  • 1
  • 1
  • 7
0

Thanks to @mar10 i made a small, simple function to search a node with title:

// If searchFrom is null, root is used
function seachFolderNodeWithName(name, searchFrom) {
    if (name == null) {
        return undefined;
    }

    if (searchFrom == null) {
        searchFrom = jQuery('#tree').dynatree("getRoot");
    }

    var match = undefined;

    searchFrom.visit(function (node) {
        if (node.data.title === name) {
            match = node;
            return false; // Break if found
        }
    });
    return match;
};
Justin
  • 2,960
  • 2
  • 34
  • 48