拿来主义: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插件使用的实例介绍 效果图如下: 文件结构如下:
随机推荐
- USG防火墙DHCP设置保留IP地址
在使用disp cur查看当前配置 然后使用undo修改 这样10.0.1.1网段到10.0.1.100之间的IP地址不会分出去
- 我发起了一个 .Net 开源 跨平台 GUI (界面开发框架)项目 HtmlCore
大家好 , 我发起了一个 .Net 开源 跨平台 GUI (界面开发框架)项目 , 名字叫 HtmlCore . 项目的一个主要目标是可以用 .Net 在 移动设备 上 开发 GUI 程序 (界面程 ...
- kindle試玩
Q:試玩感受如何? Pros 按這個版本,沒有燈,在光纖不好的時候看起來很累.但陽光好的時候看起來很爽 重量很輕,比手機邀請很多 看書很容易沉浸下去,這一點比收集好狠毒 Cons 網上說看pdf不大行 ...
- Python 回调函数
什么是回调函数? 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数: 这是官方的解释,理解上有点费 ...
- 创建用户自定义函数 SQL
//创建用户自定义函数------标量函数 create function dbo.bmrs(@bmh as int) returns int as begin declare @bmrs int s ...
- 算法实践--最长递增子序列(Longest Increasing Subsquence)
什么是最长递增子序列(Longest Increasing Subsquence) 对于一个序列{3, 2, 6, 4, 5, 1},它包含很多递增子序列{3, 6}, {2,6}, {2, 4, 5 ...
- docker stats top diff和cp
实战[root@localhost ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES1fb916fb0e13 ...
- Python日志模块logging&JSON
日志模块的用法 json部分 先开一段测试代码:注意 str可以直接处理字典 eval可以直接将字符串转成字典的形式 dic={'key1':'value1','key2':'value2'} ...
- webservice的简单使用,cxf框架的的使用
Web service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述.发布.发现.协调和配置这些应用程序,用于开发分布 ...
- RocketMQ入门(Filter)_5
RocketMQ中存储的消息对于消费者来说,并不完全都是他们需要的,因此需要对消息进行过滤. 订阅Topic主题 ,选择Tags都是我们简单的过滤.Topic是大分类,Tags是二级分类. Rocke ...