/* 
 | 
 * email: bigablecat@hotmail.com 
 | 
 * Date: 2018-04-14 
 | 
 */ 
 | 
  
 | 
/** 
 | 
 * @param zTreeId the ztree id used to get the ztree object 
 | 
 * @param searchField selector of your input for fuzzy search 
 | 
 * @param isHighLight whether highlight the match words, default true 
 | 
 * @param isExpand whether to expand the node, default false 
 | 
 *  
 | 
 * @returns 
 | 
 */     
 | 
 function fuzzySearch(zTreeId, searchField, isHighLight, isExpand){ 
 | 
    var zTreeObj = $.fn.zTree.getZTreeObj(zTreeId);//get the ztree object by ztree id 
 | 
    if(!zTreeObj){ 
 | 
        alert("fail to get ztree object"); 
 | 
    } 
 | 
    var nameKey = zTreeObj.setting.data.key.name; //get the key of the node name 
 | 
    isHighLight = isHighLight===false?false:true;//default true, only use false to disable highlight 
 | 
    isExpand = isExpand?true:false; // not to expand in default 
 | 
    zTreeObj.setting.view.nameIsHTML = isHighLight; //allow use html in node name for highlight use 
 | 
     
 | 
    var metaChar = '[\\[\\]\\\\\^\\$\\.\\|\\?\\*\\+\\(\\)]'; //js meta characters 
 | 
    var rexMeta = new RegExp(metaChar, 'gi');//regular expression to match meta characters 
 | 
     
 | 
    // keywords filter function  
 | 
    function ztreeFilter(zTreeObj,_keywords,callBackFunc) { 
 | 
        if(!_keywords){ 
 | 
            _keywords =''; //default blank for _keywords  
 | 
        } 
 | 
         
 | 
        // function to find the matching node 
 | 
        function filterFunc(node) { 
 | 
            if(node && node.oldname && node.oldname.length>0){ 
 | 
                node[nameKey] = node.oldname; //recover oldname of the node if exist 
 | 
            } 
 | 
            zTreeObj.updateNode(node); //update node to for modifications take effect 
 | 
            if (_keywords.length == 0) { 
 | 
                //return true to show all nodes if the keyword is blank 
 | 
                zTreeObj.showNode(node); 
 | 
                zTreeObj.expandNode(node,isExpand); 
 | 
                return true; 
 | 
            } 
 | 
            //transform node name and keywords to lowercase 
 | 
            if (node[nameKey] && node[nameKey].toLowerCase().indexOf(_keywords.toLowerCase())!=-1) { 
 | 
                if(isHighLight){ //highlight process 
 | 
                    //a new variable 'newKeywords' created to store the keywords information  
 | 
                    //keep the parameter '_keywords' as initial and it will be used in next node 
 | 
                    //process the meta characters in _keywords thus the RegExp can be correctly used in str.replace 
 | 
                    var newKeywords = _keywords.replace(rexMeta,function(matchStr){ 
 | 
                        //add escape character before meta characters 
 | 
                        return '\\' + matchStr; 
 | 
                    }); 
 | 
                    node.oldname = node[nameKey]; //store the old name   
 | 
                    var rexGlobal = new RegExp(newKeywords, 'gi');//'g' for global,'i' for ignore case 
 | 
                    //use replace(RegExp,replacement) since replace(/substr/g,replacement) cannot be used here 
 | 
                    node[nameKey] = node.oldname.replace(rexGlobal, function(originalText){ 
 | 
                        //highlight the matching words in node name 
 | 
                        var highLightText = 
 | 
                            '<span style="color: whitesmoke;background-color: darkred;">' 
 | 
                            + originalText 
 | 
                            +'</span>'; 
 | 
                        return     originalText;                     
 | 
                    }); 
 | 
                    zTreeObj.updateNode(node); //update node for modifications take effect 
 | 
                } 
 | 
                zTreeObj.showNode(node);//show node with matching keywords 
 | 
                return true; //return true and show this node 
 | 
            } 
 | 
             
 | 
            zTreeObj.hideNode(node); // hide node that not matched 
 | 
            return false; //return false for node not matched 
 | 
        } 
 | 
         
 | 
        var nodesShow = zTreeObj.getNodesByFilter(filterFunc); //get all nodes that would be shown 
 | 
        processShowNodes(nodesShow, _keywords);//nodes should be reprocessed to show correctly 
 | 
    } 
 | 
     
 | 
    /** 
 | 
     * reprocess of nodes before showing 
 | 
     */ 
 | 
    function processShowNodes(nodesShow,_keywords){ 
 | 
        if(nodesShow && nodesShow.length>0){ 
 | 
            //process the ancient nodes if _keywords is not blank 
 | 
            if(_keywords.length>0){  
 | 
                $.each(nodesShow, function(n,obj){ 
 | 
                    var pathOfOne = obj.getPath();//get all the ancient nodes including current node 
 | 
                    if(pathOfOne && pathOfOne.length>0){  
 | 
                        //i < pathOfOne.length-1 process every node in path except self 
 | 
                        for(var i=0;i<pathOfOne.length-1;i++){ 
 | 
                            zTreeObj.showNode(pathOfOne[i]); //show node  
 | 
                            zTreeObj.expandNode(pathOfOne[i],true); //expand node 
 | 
                        } 
 | 
                    } 
 | 
                });     
 | 
            }else{ //show all nodes when _keywords is blank and expand the root nodes 
 | 
                var rootNodes = zTreeObj.getNodesByParam('level','0');//get all root nodes 
 | 
                $.each(rootNodes,function(n,obj){ 
 | 
                    zTreeObj.expandNode(obj,true); //expand all root nodes 
 | 
                }); 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
     
 | 
    //listen to change in input element 
 | 
    $(searchField).bind('input propertychange', function() { 
 | 
        var _keywords = $(this).val(); 
 | 
        searchNodeLazy(_keywords); //call lazy load 
 | 
    }); 
 | 
  
 | 
    var timeoutId = null; 
 | 
  var lastKeyword = ''; 
 | 
    // excute lazy load once after input change, the last pending task will be cancled   
 | 
    function searchNodeLazy(_keywords) { 
 | 
        if (timeoutId) {  
 | 
            //clear pending task 
 | 
            clearTimeout(timeoutId); 
 | 
        } 
 | 
        timeoutId = setTimeout(function() { 
 | 
      if (lastKeyword === _keywords) { 
 | 
        return; 
 | 
      } 
 | 
            ztreeFilter(zTreeObj,_keywords); //lazy load ztreeFilter function  
 | 
            // $(searchField).focus();//focus input field again after filtering 
 | 
      lastKeyword = _keywords; 
 | 
        }, 500); 
 | 
    } 
 | 
} 
 |