zTree 自定义规则的全选

计算覆盖区域,前端使用zTree,来显示全国各省市区。举个栗子:用户选中了南京下面的所有区域(雨花区。。), 这时候计算的覆盖区域应该为南京市,同理,所有江苏下面的市被选中,覆盖区域就为省。一开始想着还挺简单,后来发现太navie了。

 

为什么?

zTree的状态如,hide,disabled在判断节点是否全选时,不纳入计算范围,ztree会自动过滤这些节点。

简单地说,比如南京下面已经有三个区域已经被选则了,在新添加的覆盖区域中,这三个区域会被隐藏,这是全选南京市,其实不是真正的南京市,而应该是剩下的区域。但是ztree默认的getCheckNode做不到。因为这不通用,涉及到具体的业务规则。同理,在编辑一个区域时,子区域被勾选后,显示disabled,不能再勾选,也不能取消勾选,因为子关联了该区域,父区域必须包含。

 

在试了很多的解决方案后,发现通过UI的一个hide,或者disabled完全不能实现目前的功能时,静下来仔细的思考这个问题。问题的瓶颈在于对全选规则的判断。默认的全选规则不适合我们的业务。需要自定义我们的规则。于是,查看官方api,写了一个自己的算法,解决问题。

 

思路:

1. 选择了全国,就意味着全选了所有节点,判断规则为,当前选中的节点数和全国各地市的节点数是否一致。

           //获取当前的树对象
            var zTree = $.fn.zTree.getZTreeObj("treeDemo");
            
            //获取所有全选的的节点
            var isAllNodeChecked = function() {
                var allCheckNodes = zTree.getNodesByFilter(function(node) {
                    var status = node.getCheckStatus() || {};
                    return status.checked && !status.half;
                });

                return allCheckNodes.length == zNodes.length;
            }

            console.log('isAllNodeChecked->', isAllNodeChecked());

            //如果全选,直接返回086
            if (isAllNodeChecked()) {
                return ['086'];
            }

 

 

2. 遍历所有的叶子节点(区/县),根据这些叶子节点转化为市对象,市对象的key为市id,子为叶子节点的数组,根据市id获取市节点children的数量,和当前选择的子节点数量做对比,就知道是不是真正的全选。

    

          //过滤出所有的选中或者disabled的叶子节点
            function filterLeafNodes(node) {
                var isLeaf = node.level == 2;
                var isCheck = node.checked;
                var isDisabled = node.chkDisabled;

                return isLeaf && (isCheck || isDisabled);
            }

            //所有的叶子节点
            var leafNodeList = zTree.getNodesByFilter(filterLeafNodes);

            //市对象,由叶子节点转换而来
            var cityObj = {};
            //市id,为了保证顺序
            var cityIds = [];
           
            //叶子节点转化为市对象
            $.each(leafNodeList, function(_, node) {
                console.log(node.id, node.pId, node.name);

                var id = node.id;
                var pid = node.pId; //注意低版本的zTree,是node.pid;

                if (cityObj[pid]) {
                    cityObj[pid].push(id);
                } else {
                    cityIds.push(pid);
                    cityObj[pid] = [id];
                }   
            });

            console.log('cityObj->', cityObj);

     

3. 市对象转化为省对象,原理同上;

            //省
            var provObj = {};
             //省id,为了保证顺序
            var proIds = [];

            $.each(cityIds, function(_, id) {
                //市
                var parentNode = zTree.getNodeByParam('id', id);
                //市关联的区的数量
                var childrenLen = parentNode.children.length;
                //如果市的节点是真正的全选,市children的数量和改数量相同
                if (childrenLen == cityObj[id].length) {
                    //省
                    var ppid = parentNode.pId;
                    if (provObj[ppid]) {
                        provObj[ppid].push(id);
                    } else {
                        proIds.push(ppid);
                        provObj[ppid] = [id];
                    }                 
                } else {
                    $.merge(lastNode, cityObj[id]);
                }
            });

            console.log('provObj->', provObj);

            $.each(proIds, function(_, id) {
                //省
                var ppNode = zTree.getNodeByParam('id', id);
                console.log(ppNode.id, ppNode.name, ppNode.children.length);
                var len = ppNode.children.length;
                if (len == provObj[id].length) {
                    lastNode.push(id);
                } else {
                    $.merge(lastNode, provObj[id]);
                }
            });

 

这样就可以获取所有的覆盖区域。

 

最后,人生苦短,必须果敢。

 

测试页面:

 

https://github.com/hufeng/toys/blob/master/html/checkbox_1.html

下载zTree,把页面丢到zTree_v3/demo/cn/exhide.祝玩得愉快。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
<!DOCTYPE html> <HTML> <HEAD> <TITLE> ZTREE DEMO - checkbox</TITLE> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" href="zTreeStyle.css" type="text/css"> <script type="text/javascript" src="jquery-1.4.4.min.js"></script> <script type="text/javascript" src="jquery.ztree.core.js"></script> <script type="text/javascript" src="jquery.ztree.excheck.js"></script> <SCRIPT type="text/javascript"> var setting = {check: {enable: true},data: {simpleData: {enable: true}}}; var zNodes =[ { id:1, pId:0, name:"全选", open:true}, { id:11, pId:1, name:"报表", open:true}, { id:111, pId:11, name:"报表管理",open:true}, { id:112, pId:11, name:"报表概况",open:true}, { id:12, pId:1, name:"我的", open:true}, { id:121, pId:12, name:"修改密码",open:true}, { id:122, pId:12, name:"意见反馈",open:true} ]; $(document).ready(function(){ $.fn.zTree.init($("#treeDemo"), setting, zNodes); var zTree = $.fn.zTree.getZTreeObj("treeDemo"), type = { "Y":'ps', "N":'ps'}; zTree.setting.check.chkboxType = type; }); function aa(){ var treeObj=$.fn.zTree.getZTreeObj("treeDemo"); nodes=treeObj.getCheckedNodes(true); var nodes1 = treeObj.getNodes(); var aa1= treeObj.transformToArray(nodes1); for(var i=0; i < aa1.length;i++){ var node = treeObj.getNodeByParam("id",aa1[i].id ); treeObj.checkNode(node,true,true); treeObj.updateNode(node); } } </SCRIPT> </HEAD> <BODY> <div class="content_wrap"> <div class="zTreeDemoBackground left"> <ul id="treeDemo" class="ztree"></ul> </div> <button value="dianji" onclick="aa()" /> </div> </BODY> </HTML>

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值