计算覆盖区域,前端使用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.祝玩得愉快。
相关推荐
本实例详细讲述了如何通过zTree实现满足项目需求Tree数据分层显示要求,通过zTree灵活的自定义属性,轻松完成Tree的改造
jquery ztree自定义编辑的树形菜单插件----------------------------------------------------------
jquery ztree自定义编辑的树形菜单插件代码
ztree自定义tag
ztree3.1插件,根据项目需要,添加了一些需要的控件,比如增、删、改等,数据库是oracle10g。如有疑问请给我留言。
ztree节点关键字搜索功能,可自定义搜索规则,不限层次,匹配失败父节点也会隐藏
ztree取消选择,实现checkbox、全选、取消全选功能,已经经过实际测试
ztree树选中节点弹出层编辑
最近项目中有一个比较大型的树节点加载,网上面也看过一些解决方案,感觉都不是很好,也有很多误区,比如单击节点时加载子...ztree fileter方法是在每次展开时都会执行,所以根据不同的请求达到异步加载子节点的需求。
ztree官网ztree官网ztree官网ztree官网ztree官网ztree官网ztree官网ztree官网ztree官网ztree官网ztree官网ztree官网ztree官网ztree官网ztree官网ztree官网ztree官网ztree官网ztree官网ztree官网ztree官网ztree官网...
主要介绍了jQuery插件zTree实现删除树节点的方法,结合实例形式分析了jQuery树插件zTree针对节点的遍历与删除操作相关技巧,需要的朋友可以参考下
这个demoo里面包含,使用ztree做的一个自定义控件。已经ztree常用方法、异步获取数据等的一个解决方案。
在ztree3.5 demo中加的页面demo\cn\super\radio_checkbox.html 页面上在组合功能演示--radio_checkbox共存中可以看到效果
ztree脚本、ztree下载、包含ztree文件、ztree的pdf教程、ztree的chm教程
zTree -- jQuery 树插件
主要介绍了jQuery实现自定义checkbox和radio样式的相关资料,需要的朋友可以参考下
非常好看的ztree样式,可以使用不同图标,可以兼容IE6,Hunter's Home zTree in Google zTree 功能演示 基本功能演示 不兼容 IE6 ...添加自定义控件 checkbox & radio 共存 右键菜单 下拉菜单 皮肤演示
zTree 是一个依靠 jQuery 实现的多功能 “树插件”。优异的性能、灵活的配置、多种功能的组合是 zTree 最大优点。
zTree组件api,官方可用chm版(zTree api)
ztree使用说明