拿来主义:treeview插件父子节点问题
鄙人公司没有专门的前端,所以项目开发中都是前后端一起抡。最近用bootstrap用的比较频繁,发现bootstrap除了框架本身的样式组件外,还提供了多种插件供开发者选择。本篇博文讲的就是bootstrap的一个树形插件bootstrap-treeview。
最近项目权限模块中,需要将用户菜单做成可配置的。授权人员的授权操作是通过对树形菜单中的复选框进行勾选后保存来完成的,如下图所示:
bootstrap-treeview本身对勾选/取消的支持是没问题,问题在于复选框的业务逻辑上:
① 如果 勾选了父级节点,怎么让子节点全部变为勾选状态?
② 如果只选择了某个子节点,怎么让该节点所有的父节点全部变为选中状态?
博主开发的时候也是问了度娘,但很多网友的分享让自己这样前端薄弱的人看得头大,所以项目功能实现后,特意整理了自己的简洁实现,如博友有更好的方法,欢迎告知,共同进步。
首先,请求服务器后台获取的节点数据,通过树形插件的事件触发机制,在点击复选框做选中/取消操作的时候,去执行全选的代码:
function modify(id) {
BASE.ajax("permission/pers", {
id: id
}, function (data) {
$("#demoTree").treeview({
color: "#428bca",
data: data,
levels: 1, //显示时展开到几级
showIcon: false,
showCheckbox: true,
onNodeChecked: function (event, node) { //选中事件
checkAllNodes("checkNode", node);
},
onNodeUnchecked: function (event, node) { //取消事件
checkAllNodes("uncheckNode", node);
}
});
$("#modal").modal("show");
});
}
然后,通过对选中的当前节点进行遍历,对遍历出的节点执行选中;如果子节点还有子节点,很简单,递归一下就能搞定:
function checkAllNodes(method, node) {
var $tree = $('#modifyTree');
$(node.nodes).each(function (a, b) {
//判断子节点存在,就执行相应的选中/取消事件。
//each回调函数中参量:a表示节点索引,b表示节点对象
$tree.treeview(method, [b.nodeId, {
silent: true
}]);
if (b.nodes) //递归调用
checkAllNodes(method, b);
});
}
自此,点击父节点 选中/取消 所有子节点的功能就算ok了。基于同样的思想,要想实现选中某一子节点后同时选中所有的父节点,那么只需要在代码中继续添加:① 通过子节点判断父节点的存在;② 选中父节点;③ 递归判断。
于是,上面的函数代码中就可以这样添加:
function checkAllNodes(method, node) {
var $tree = $('#modifyTree');
if (node.parentId) {//如果父节点存在,选中/去除父节点
getParentNode(method, node, $tree);
}
$(node.nodes).each(function (a, b) {
$tree.treeview(method, [b.nodeId, {
silent: true
}]);
if (b.nodes)
checkAllNodes(method, b);
});
} function getParentNode(method, node, tree) {
tree.treeview(method, [node.parentId, {
silent: true
}]);
var pnode = tree.treeview('getNode', node.parentId);
if (pnode.parentId) //递归判断父节点是否还有父节点
getParentNode(method, pnode, tree);
}
自此,上面提到的两个问题就算是大功告成了。。。吗?稍等,如果这就算完成了,这篇博文记录对我实在没有多大意义。正当我喜滋滋的以为功能实现了的时候,突然发现了很大的bug,就是在通过子节点选中所有父节点的功能实现中,选中是没有问题,可是当取消某个子节点,无论兄弟节点是否有选中,父节点都一并被取消掉了。这肯定是有问题的。所以,自己又对取消事件单独做了判断,判断取消的时候,是否还有兄弟节点是处于选中状态,如果有,那么父节点就不执行取消了。代码如下:
function getParentNode(method, node, tree) {
if (method == "uncheckNode") { //如果是取消事件,当判断兄弟节点是否存在
var arr = tree.treeview('getSiblings', node);//获取兄弟节点
for (var i = 0; i < arr.length; i++) {
var brotherNode = arr[i];
if (brotherNode.state.checked) { //判断兄弟节点是否用选中状态
return;
}
}
}
tree.treeview(method, [node.parentId, {
silent: true
}]);
var pnode = tree.treeview('getNode', node.parentId);
if (pnode.parentId)
getParentNode(method, pnode, tree);
}
行文至此,上面的两个问题算是完美解决了。代码中的事件、属性,都是插件官网有详细说明的,插件使用过程中肯定需要根据业务需要去查询使用详情,再融合进自己的代码中的,不可生搬硬套。分享完结,希望能帮到一些人。如有疑惑或者更好的建议,留言讨论,不胜感激。。。
拿来主义:treeview插件父子节点问题的更多相关文章
- jquery递归遍历xml文件,形成ul-li序列,生成树结构(使用了treeview插件)
treeview插件从这里获得,下载的文件中有demo,看demo文件夹里面的index.html文件就差不多知道如何使用该控件了,在我做的项目里用到的部分代码截图如下(在引用下面的js文件前要先引用 ...
- jQuery.TreeView插件实现树状导航(十三)
一:jQuery.TreeView插件简介 该插件的特点: 1.支持静态的树,即一次性将全部数据加载到客户端. 2.支持异步树,即一次只加载一级或若干级节点,子节点可以异步加载数据. 3.支持节点级联 ...
- WinForm控件TreeView 只部分节点显示 CheckBox
WinForm控件TreeView 只部分节点显示 CheckBox 用过asp.net的应该知道,要在treeview中实现上述功能可以使用ShowCheckBox 属性指定那些节点显示check ...
- Devexpress TreeList控件绑定显示父子节点对像
今天一位同事咨询Devexpress TreeList控件绑定自动显示父子节点对像,但结果是不会显示带父子节点关系,而是将所有的节点作为父节点显示出来了,对像类的代码如下 public class I ...
- C# TreeView 拖拽节点到另一个容器Panel中简单实现
C# TreeView 拖拽节点到另一个容器Panel中简单实现 用了这么久C#拖拽功能一直没有用到也就没用过,今天因为项目需要,领导特地给我简单讲解了下拖拽功能,真是的大师讲解一点通啊.特地写一篇博 ...
- WPF TreeView 选择事件执行两次,获取TreeView的父节点的解决方法
1.TreeView选择事件执行两次 Very often, we need to execute some code in SelectedItemChanged depending on the ...
- json树递归js查询json父子节点
上代码,直接另存为html打开,看console控制台就可以看到效果了 <!DOCTYPE html> <html lang="en"> <head& ...
- unity 获得父子节点
与常识不同,unity中获得父子节点需要通过transform.即先获得父/子节点的transform,然后再通过父/子节点的transform获得父/子节点. 获得父节点gameObject: Ga ...
- jquery Treeview插件的使用及复选框的级联
本文是对jquery的Treeview插件使用的实例介绍 效果图如下: 文件结构如下:
随机推荐
- java_初始化器
1. 执行的顺序 package java20180129_1; public class Demo { // instance variable initializer 实例变量初始化器 Strin ...
- Excel技巧--实现交叉查询
如上图,要实现某个地区和某个产品的销售额查询显示.可以使用Match和Index函数的使用来实现: 1.产品名称和城市栏,制作成列表可选:使用“数据”-->“数据验证”的方法. 2.先在旁边空位 ...
- 被称为“开发者神器”的GitHub,到底该怎么用?
被称为“开发者神器”的GitHub,到底该怎么用? 原文:https://baijiahao.baidu.com/s?id=1594232691312740966&wfr=spider& ...
- error C4996: 'sprintf': This function or variable may be unsafe.
error C4996: 'sprintf': This function or variable may be unsafe. error C4996: 'sprintf': This func ...
- Struts vs spring mvc
1. 机制.spring mvc 的入口是servlet, 而struts是filter(这里要指出,filter和servlet是不同的.以前认为filter是servlet的一种特殊),这样就导致 ...
- 电商中的库存管理实现-mysql与redis
库存是电商系统的核心环节,如何做到不少卖,不超卖是库存关心的核心业务问题.业务量大时带来的问题是如何更快速的处理库存计算. 此处以最简模式来讨论库存设计. 以下内容只做分析,不能直接套用,欢迎 ...
- zabbix4.0下zabbix-agentd安装
转:http://www.safecdn.cn/monitor/2018/12/zabbix4-0-zabbix-agentd-install/316.html 一 安装源和Zabbix的依赖包: 1 ...
- hive mysql元数据,报错 Specified key was too long; max key length is 767 bytes
Specified key was too long; max key length is 767 bytes 此错误为hive 元数据mysql 字符集编码问题 如 show create tabl ...
- Dubbo+zookeeper面试题补充
什么是分布式?什么是集群?主要区别 分布式是将一个服务分个部分,然后通过远程调用方式进行.远程调用框架RPC框架,spring cloud,dubbo.集群是将同一个服务的多个副本部署在不同的集群上, ...
- MySQL中Checkpoint技术
个人读书笔记,详情参考<MySQL技术内幕 Innodb存储引擎> 1,checkpoint产生的背景数据库在发生增删查改操作的时候,都是先在buffer pool中完成的,为了提高事物操 ...