自写 zTree搜索功能 -- 关键字查询 -- 递归无限层

  一般搜索功能只是在“既定范围内(方便称呼)”匹配关键字,“既定范围”即我们已经知道搜索的范围:比如说一个文本库,一个下拉框,换而言之我们匹配的对象集大小已经确定了。然而这一点在ztree上不可行,为什么呢?在我考虑了一下ztree搜索功能实现逻辑的时候问了一句:那啥,这棵树的层级是固定的吗?还是说不确定有多少层?老哥看着我会心一笑:你按无限层来写~小生小腿肚子一抽。。因为树的层级不确定,所以搜索范围不确定,举个栗子:目标节点匹配成功,如果这个节点是子节点,那么它的父节点也应该是显示的,然后它父节点的父节点也应该是显示的,然后它父节点的父节点的父节点的...Orz...这仿佛永远写不到尽头了...没办法,只能:递归,找到目标节点的所有父节点和子节点。

逻辑关键点

  在上面的思维导图中我大致列出了逻辑,目标节点在什么情况下显示,什么情况下隐藏,这是我们必须清楚的关键点,下面我们具体看下目标节点存在的情况:

 

  到了这里,相信对于如何实现满足我们需求的搜索功能开发,已经能做到了然于心了,剩下的只是实现的方法,然而这完全不是事~(小生窃以为真正让人忧心的理不清功能的流程,至于实现方法你们都懂的吧?0.0..)

关于树节点

  要完成上述流程中各种方法,我们需要知道树节点的一系列属性,我们都知道有api这种神器,然而api有一个特点就是齐全(齐全得我们想精确的找到某一个属性或者方法时可能得一顿好找),这里我们想要的是如何快速得到自己想要的属性或者方法,我们在控制台打印出树节点集合:

var treeObj=$.fn.zTree.getZTreeObj("homeTree"); // 设置根节点
        var node = treeObj.getNodes(); // 获取根节点
        var nodes = treeObj.transformToArray(node); // 获取所有节点
        console.log(nodes);

   看图:我们能看到所有节点,其中有id,name等各种属性

  再看图:我们能看到任意节点的各种属性,有我们想要的子节点集合 childern,父节点属性 isParent ,节点id tId,父节点id parentTid...

万事俱备,动手

  下面看一下相关方法,很多小细节需要在真正编码过程中才能发现,这里为了方便展示就直接列举方法了。

  声明备用数组:

// 地区搜索
    var parentArray = [];
    var childArray = [];

   递归获取目标节点父节点集合:

// 递归获取目标节点所有父节点
    function getParentsNode(treeNode){
        var thisParentNode = treeNode.getParentNode(); //得到该节点的父节点
        if( thisParentNode != null ){ // 父节点存在
            parentArray.push(thisParentNode); // 储存至数组
            getParentsNode(thisParentNode); // 重调 
        }else{
            return false;
        }           
    }

 递归获取目标节点子节点集合:

// 递归获取目标节点所有子节点
    function getChildrenNode(treeNode){
        var thisIsParent = treeNode.isParent; // 获取目标节点 isParent 属性,判断是否为父节点
        if( thisIsParent == true ){
            var thisChildrenNode = treeNode.children; // 得到该节点的子节点集合
            for(var i=0;i<thisChildrenNode.length;i++){
                childArray.push(thisChildrenNode[i]); // 将该子节点加入数组中
                getChildrenNode(thisChildrenNode[i]); // 重调       
            }
        }else{
            return false;
        }
    }

  这里建议将匹配节点部分摘出来单独写一个方法,方便进行拓展匹配规则,这里我们假设除了匹配name还需要匹配节点的 entity_code 属性:

//匹配节点
    function matchNode(treeNode,num){
        var inputArea = $("input[name='searchArea']");
        var name = treeNode.name;
        var entityCode = treeNode.entity_code|| '';
        var val = inputArea.val(); // 获取检索值
        var numName = name.indexOf(val);
        var numCode = entityCode.indexOf(val);
        var num = -1;
        if( numName != -1 || numCode !=-1 ){
            num = 1;
        }
        if( numName == -1 && numCode == -1 ){
            num = -1;   
        }
        return num;
    }

节点匹配成功方法:

// 节点匹配成功
    function checkTrueArray(arr,treeNode){
        var thisTid = treeNode.tId;
        var thisLi = $("#"+thisTid);
        for(var n=0;n<arr.length;n++){
            var thisNodeId = arr[n].tId;
            var thisNodeLi = $("#"+thisNodeId);
            thisLi.show();
            thisNodeLi.show();
        }
    }

节点匹配失败方法:

// 节点匹配失败
    function checkFalseArray(arr,treeNode){
        var result = [];
        var result2 = [];
        var thisTid = treeNode.tId;
        var thisLi = $("#"+thisTid);
        var val = inputArea.val(); // 获取检索值
        var thisParent =  treeNode.getParentNode();  // 获取目标节点父节点
        if( thisParent != null ){  // 有父节点
            var thisBrotherArr =  treeNode.getParentNode().children; // 得到包含自身的兄弟数组
            for(var m=0;m<arr.length;m++){ // 匹配父节点
                var num = matchNode(arr[m]);
                if( num != -1 ){
                    result.push(arr[m]);
                }
            }
            var resultLength = result.length;
            for( var m=0;m<thisBrotherArr.length;m++ ){ // 匹配兄弟节点
                var num = matchNode(thisBrotherArr[m]);
                if( num != -1 ){
                    result2.push(thisBrotherArr[m]);
                }
            }
            var resultLength2 = result2.length;
            // 对于自身匹配失败的节点,要显示必须满足有父节点匹配成功,且兄弟级节点都匹配失败
            if( (resultLength == 0 && resultLength2 == 0) || resultLength2 != 0 ){
                thisLi.hide();
            }
            if( resultLength !=0 && resultLength2 == 0 ){
                thisLi.show();
            }
        }else{
            thisLi.hide();
        }    
    }

目标节点匹配失败 目标节点即有父节点又有子节点:

// 目标节点匹配失败 目标节点即有父节点又有子节点
    function checkAllArray(arr,arr2,treeNode){
        var result = [];
        var result2 = [];
        var thisTid = treeNode.tId;
        var thisLi = $("#"+thisTid);
        var val = inputArea.val(); // 获取检索值
        for(var m=0;m<arr.length;m++){ // 匹配子节点或父节点
            var num = matchNode(arr[m]);
            if( num != -1 ){
                result.push(arr[m]); // 匹配成功储存至数组
            }
        }
        var resultLength = result.length; // 获取匹配成功后返回的数组长度
        for(var m=0;m<arr2.length;m++){ // 匹配子节点或父节点
            var num = matchNode(arr2[m]);
            if( num != -1 ){
                result2.push(arr2[m]); // 匹配成功储存至数组
            }
        }
        var resultLength2 = result2.length; // 获取匹配成功后返回的数组长度
        if( resultLength == 0 && resultLength2 == 0 ){ // 子节点和父节点都匹配失败
            thisLi.hide();
        }else{ 
            thisLi.show(); // 有一种匹配成功或都匹配成功
        }
    }

定义搜索方法:

function searchArea(treeId, treeNode){ // 定义搜索方法
        var inputArea = $("input[name='searchArea']");
        var val = inputArea.val(); // 获取检索值
        var treeObj=$.fn.zTree.getZTreeObj("homeTree"); // 设置根节点
        var node = treeObj.getNodes(); // 获取根节点
        var nodes = treeObj.transformToArray(node); // 获取所有节点
        console.log(nodes);
        for(var i=0;i<nodes.length;i++){
            var thisNodePid = nodes[i].pId;
            var thisParentNode =  
            parentArray = [];
            childArray = [];
            getParentsNode(nodes[i]); // 获取目标节点所有父节点 返回数组
            getChildrenNode(nodes[i]); // 获取目标节点所有子节点 返回数组
            var num = matchNode(nodes[i]);
            if( nodes[i].isParent == false ){ 
                if( num != -1 ){
                    checkTrueArray(parentArray,nodes[i]);
                }else{
                    checkFalseArray(parentArray,nodes[i]);
                }
            }
            if( nodes[i].isParent == true ){
                if( num != -1 ){
                    checkTrueArray(parentArray,nodes[i]);  
                    checkTrueArray(childArray,nodes[i]);                  
                }else{
                    checkAllArray(parentArray,childArray,nodes[i]);
                }
            }            
        }
       
    }

调用搜索方法:

// 调用搜索方法
    $(".searchAreaBtn").click(function(treeId, treeNode){
        searchArea(treeId, treeNode);
    });
    var inputArea = $("input[name='searchArea']");
    inputArea.keyup(function(treeId, treeNode,e){
        var e = event || window.event;
        var val = inputArea.val();
        if( e.keyCode == 13 || val == "" ){
            searchArea(treeId, treeNode);
        }
    });

看效果(电脑ps出问题了,用美图秀秀拼的图~囧...):

转载于:https://my.oschina.net/tshblogs/blog/1840363

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ztree-input是一个通过使用zTree插件实现的下拉菜单功能。根据引用[1]中提供的代码,ztree-input的实现方式是通过在页面上添加一个input框,并绑定一个点击事件来显示下拉菜单。当点击input框时,会触发事件函数"showTree()",该函数会将zTree树状图显示在input框下方。同时,通过点击input框右侧的倒三角图标,可以收起或展开下拉菜单。在下拉菜单中选择相应的选项后,选中的值会存储在一个隐藏的input框中,供后续的处理使用。这样实现了一个具有下拉功能ztree-input。 从引用中可以看到,实现ztree-input还需要引入ztree所需的js和css文件。 最后,引用提供了一个可用的示例来实现点击input框出现下拉菜单的效果。这个示例经过亲测可用。 总结来说,ztree-input是通过使用zTree插件和一些相关的代码实现的一个具有下拉功能的输入框。用户可以点击输入框来显示一个下拉菜单,并在菜单中选择相应的选项。选中的值会存储在隐藏的input框中,方便后续处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [ztree实现下拉功能 input](https://blog.csdn.net/weixin_42599079/article/details/88897426)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [ztree树形菜单实现点击input框下拉功能 (内附有demo)](https://blog.csdn.net/z_zhy/article/details/87938669)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [zTree 实现点击input框出现下拉菜单(亲测可用)上一版的传错了](https://download.csdn.net/download/z_zhy/10997776)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值