MVC 纯Table实现树节点效果+授权
这几夜心里颇不平静, 奈何 JS水平有限,前台效果耗时四天,后台传值一天,直至昨夜丑时测试初步完成,其实就是一个给tree来授权,网上开源的插件很多,如treeview、treejs、easyui 等等,只是这里授权稍有不同,在新增角色的时候,可以同时对所有功能进行授权, 如下图,只能放在Table中去实现。一行一行的写js,最后写的差不多有个200多行。
项目原界面不方便截图,这里随手写个原生态的 Demo ,当然比较丑
如图所示,首先这是一个Table,无论枝节点还是叶节点都作为一行(tr),功能菜单列表中叶节点(无分支) 后对应新增、修改等六个功能(复选框)
先来说说前台需要实现的效果:
①点击枝节点,其下所有的节点(枝/叶)收缩/展开
②点击枝节点前的复选框,其下所有节点(枝/叶)、叶节点所在行的新增、修改等复选框勾选/取消
eg: 点击蓝圈中的复选框,则红框内所有的复选框都被勾选/取消
针对JQ,只要能给每个标签一个值,name、id之类的用以区别,就能使用Jquery选择器来确定该元素
给所有枝节点嵌套一个 id 为 spid 的标签<span>用来标识
<tr id="11000">
<td colspan="7"><input name="c0" id="1-0000c" type="checkbox"/><span id="spid" >1-0000</span></td>
</tr>
<tr id="11-000" style="text-indent: 10px">
<td><input name="c1" id="11-000c" type="checkbox"/><span>11-000</span></td>
<td><input name="A" id="11-000cA" type="checkbox"/></td>
<td><input name="B" id="11-000cB" type="checkbox"/></td>
<td><input name="C" id="11-000cC" type="checkbox"/></td>
<td><input name="D" id="11-000cD" type="checkbox"/></td>
<td><input name="E" id="11-000cE" type="checkbox"/></td>
<td><input name="F" id="11-000cF" type="checkbox"/></td>
</tr>
说白了,就是用Table的方式来实现一个Tree的效果,这里子节点和叶节点是用<tr>的缩进长度来达到层级节点的效果
针对收缩/展开
只要能够选择到枝节点里面的span标签,既可用toggle()来隐藏/展开子节点。根据命名的特点使用拼接id的方法来选择子节点,即可实现.
然后分情况,依次判断是鼠标点击的是几级枝节点,如果是一级,则只需要隐藏/展开其下的叶节点;如果是两级,要隐藏/展开其下的枝节点、叶节点;以此类推
比如当点击篮框所在的枝节点23-000时,叶节点231-00、23200、枝节点23300及叶节点2331-0、2332-0 均要隐藏/展开。
var lenth = $(this).parent().parent().attr('id').indexOf("-");
var s = $(this).parent().parent().attr('id').substring(0, lenth);
判断前,先得到当前对象所在的 tr 的 id 中的字符 - 的位置,根据该位置可知当前鼠标点击的是何级枝节点,然后隐藏/展开其下节点即可,此时对应的 lenth == 2 ,则有
$(this).parent().parent().siblings("#" + s + i + '-' + '00').toggle();
for (var q = 1; q < 6; q++) {
if ($("#" + s + i + q + '-' + '0').is(":hidden")){
$(this).parent().parent().siblings("#" + s + i + q + '-' + '0').toggle();
}
$(this).parent().parent().siblings("#" + s + i + q + '-' + '0').toggle();
}
若lenth == 3 ,即为最里层枝节点,则有
$(this).parent().parent().siblings("#" + s + i + '-' + '0').toggle();
若lenth ==1 ,即为最外面的枝节点(根节点),同样是按照id的拼接方法来判断,不同的是,需要多循环一层而已
$(this).parent().parent().siblings("#" + s + i + '-' + '000').toggle();
for (var j = 1; j < 6; j++) {
if ($("#" + s + i + j + '-' + '00').is(":hidden")) {
$(this).parent().parent().siblings("#" + s + i + j + '-' + '00').toggle();
}
$(this).parent().parent().siblings("#" + s + i + j + '-' + '00').toggle();
for (var p = 1; p < 6; p++) {
if ($("#" + s + i + j + p + '-' + '0').is(":hidden")) {
$(this).parent().parent().siblings("#" + s + i + j + p + '-' + '0').toggle();
}
$(this).parent().parent().siblings("#" + s + i + j + p + '-' + '0').toggle();
}
}
根据观察比较,发现就是一层一层的去选择节点,节点越靠外,最外是根节点,那么需要遍历的层次就越多,同理,越内侧,遍历次数就越少。用到了大量的 if else 语句,其中又和 for 语句相互嵌套,层层相扣,写完之后,我的感觉是,除了自己,估计很难有另外一个人能在短时间内明白,自己再也不要去维护自己写的这个菜单授权。仔细思索,其实是可以进行大量优化代码,比如:点击第三层需要循环第二层和第一层,点击第二层需要循环第一层,点击第一层需要循环其下的叶节点,那么我最后的解决方案时采用 直接放在一个方法里面,然后用$.each() 来遍历,把叶节点放在最下面,一层一层,这样一来,代码果然看的很舒服,质量也提高不少。
而对于单选/多选/全选/反选
相对来说判断的情况复杂一些,主要是需要结合后台逻辑,比如说:
三级叶节点勾选,则三级枝节点勾选、二级枝节点勾选、一级枝节点勾选
二级枝节点勾选,则其下所有子节点勾选,其上一级枝节点勾选
首先还是分情况讨论,思路如下
if 勾选授权行(叶节点)所在的第一列(11-000、12-000)
其所在行的每一个节点均勾选(新增、修改、删除等)
其上 各级直系枝节点勾选
else
if 勾选授权行所在的其他列(新增、修改、删除、修改、上传、下载)
当个数不少于1一个时,其第一列也要勾选(涉及到后台的传值), 其上 各级直系枝节点勾选
当个数为0时(点击两下),其第一列不勾选,其上父级节点的兄弟节点(大爹、二爹、小爹)若均无勾选,则祖父节点不勾选,
所有其一勾选,则祖父节点仍勾选,依次类推,直至根节点
else 勾选枝节点时
if 一级节点 逐级遍历,其下所有子节点勾选,其上若兄弟节点均无勾选,则父节点不勾选,若有其一勾选,则父节点勾选
if 二级节点 逐级遍历,其下所有子节点勾选,其上若兄弟节点均无勾选,则父节点不勾选,若有其一勾选,则父节点勾选,以此类推,直至祖父节点
if 三级节点 逐级遍历,其下所有子节点勾选,其上若兄弟节点均无勾选,则父节点不勾选,若有其一勾选,则父节点勾选,以此类推,直至曾祖父节点
如此,就把所有的情况都考虑进去,按部就班,一行一行的码js,即可达到要求,代码有点多,思路就是这样,这里就不贴详细代码
上面都是前台的效果,下面来说说后台传值,这里有些技巧,值得一说,我给每个授权对应的td 都赋有name 值,这里其值对应的是角色表中某功能数据中一个列,比如,选择11-000,新增、删除;则表中会授权列会记录 A、B 。写到这里,无非就是一些传值,直接记录用Ajax传递后台接受即可,用Push方法,具体的在 MVC与Ajax应用 中删除一节有详细记录。这里也不再赘述。写到这里,文中唯一值得说两句的便是下文。当对某个角色的权限进行修改时,初次加载该界面,Table 表中的复选框 会对照 该角色本身的功能及权限,会有勾选。说白了就是点击修改的时候,会有传值的动作,先去数据库中 根据该角色的主键信息,捞取其拥有的功能和对应的权限,根据这些数据Table表中的Checkbox 会有一个初始值。
这里用到了Each,不得不说真方便。
先在后台拿到 两列(功能列表、权限)的集合,然后传到前台View中(Authlist)
紧接着根据 @Html.Raw(Json.Encode(Authlist)) 将其转换为Json 数组
再对其遍历,最后根据其值给授权复选框一个初始值,具体如下:
function getcheck() {
$("input[type=checkbox]").prop("checked", false);
var data=@Html.Raw(Json.Encode(Authlist));
$.each(data,function(i, item) {
var array = item.WebFunctItem.toString().split(',');
var local = item.FunctID.toString().indexOf("0");
var sfunctid = item.FunctID.toString().substring(0, local); var lastnumber = item.FunctID.toString().substr(item.FunctID.length-1, 1);
if (lastnumber === "0") {
$("#" + sfunctid + '-' + Getzero(local) + 'u').prop("checked", true);
for (var i = 0; i < array.length; i++) {
$("#" + sfunctid + '-' +Getzero(local) + 'u'+array[i]).prop("checked", true);
}
}
else {
$("#" + item.FunctID.toString() + '-' + 'u').prop("checked", true);
for (var i = 0; i < array.length; i++) {
$("#" + item.FunctID.toString() + "-u" + array[i]).prop("checked", true);
}
}
});
}
写到这里,自然并没有结束,对于前台来说,效果仅仅实现了三分之一,其实最麻烦的是 ,挨个节点去做判断,这里是Table标签,只能挨个去遍历,新增的话还好说,当对角色权限做修改操作时,因较难判断出复选框状态的改变/不改变。比如,未做修改,或者仅对已存在的功能菜单作部分权限(增、删、改、查等)调整时,这时Ajax 传值,后台Update语句有效;如果勾选新的功能菜单,这是ajax传值,后台的Update语句无法完成,只能对新增的功能菜单执行Insert 方有效,此时,前台就需要判断哪些是对原有菜单的功能进行修改,哪些是新增的菜单及菜单下被授权的功能,如此,是很难做出判断,对此,后台逻辑控制为: 先删除该角色所有的功能,然后逐个新增 ,删除 和 新增的 sql 进行叠加,然后调用一个事物,以免中途语句执行失败可回滚至原始值。
最近都在忙于前台样式,这个项目进行到此处,着实让自己的JS水平 提高了一把,业务水平的最好的提高果真就是实践,然后不断的测试、测试、测试
市人皆大笑,举手揶揄之
MVC 纯Table实现树节点效果+授权的更多相关文章
- 转:zTree树控件扩展篇:巧用zTree控件实现文本框输入关键词自动模糊查找zTree树节点实现模糊匹配下拉选择效果
是否可以借助于zTree实现文本框输入关键词自动模糊匹配zTree下拉树,然后选择下拉树内节点显示在文本框内且隐藏下拉树. 看到这个需求脑子里头大致已经想到了要如何实现这样一个需求,当时是限于时间问题 ...
- ligerui_ligerTree_005_动态增加“树”节点
动态添加ligerTree节点:效果图: 源码地址:http://download.csdn.net/detail/poiuy1991719/8571255 <%@ page language= ...
- 使用zTree和json构建简单树节点
我们经常碰到须要构建树结构展示的情况,我推荐使用zTree和JSON. 比如: <? php /** * * 使用zTree和json构建树节点 * */ $arr = array( 0=> ...
- DOM树节点和事件
一.前言:DOM树节点是JS的基础语句.通过节点,能够取到HTML代码中的任意标签,从而对其进行修改和添加各种视觉效果. 二.DOM树节点 DOM节点分为三大类: 元素节点,属性节点,文本节点 ...
- EDM模板编写踩坑指南(非响应式,纯table有源码)
如果问你table布局,你肯定会嗤之以鼻?什么table布局?不是早已经淘汰了吗?但是如果让你写EDM邮件模板,table布局相对来说是最好的选择. 如果让你立刻写EDM,你在网上搜的话,得到的信息相 ...
- Easyui 实现点击不同树节点打开不同tab页展示不同datagrid表数据设计
实现点击不同树节点打开不同tab页展示不同datagrid表数据设计 by:授客 QQ:1033553122 测试环境 jquery-easyui-1.5.3 需求描述 如上图, 1.点击左侧树,叶子 ...
- zTree变异篇:如何让同级树节点平铺而非垂直显示
昨天有一个zTree的使用者在实际的项目中有着这样一个特殊的需求,要求同级树节点能够水平显示,根据设定的宽度自动换行,效果图如下所示: 通过在浏览器调试模式下观察其同级节点的css为: 这个dis ...
- 转:zTree树控件key配置之title:zTree树节点名称过长如何省略显示且鼠标移入节点上能够显示全称
当树节点的名称有些很长时,全部显示出来显得很拥挤的情况下,我们会想到用省略节点名称来代替,当鼠标移入节点时能够显示该节点的全称.这样我们应该如何做呢? 首先,我们要在树的节点内多增加一个属性用于设置该 ...
- LigerUI树节点选中之后节点背景太短
LigerUI树节点选中之后的效果如下: 可以看出,节点的背景太短,不能适应树的宽度 理想的效果应该是节点选中之后,节点背景和树的宽度一样 虽然没有找到官方的解决办法 但是,通过查询LigerUI的A ...
随机推荐
- 为什么很多应用都安装在/usr/local目录下?
首先,Linux的官方文档FHS对该目录的说明:http://www.linuxbase.org/betaspecs/fhs/fhs/ch04s09.html The /usr/local hiera ...
- java集合的复习
1:自定义的linkedList链表 https://blog.csdn.net/qq_33471403/article/details/80109620 2:用linked https://b ...
- ZAB协议与Paxos算法
ZooKeeper并没有直接采用Paxos算法,而是采用一种被称为ZAB(ZooKeeper Atomic Broadcast)的一致性协议 ZooKeeper是一个典型的分布式数据一致性的解决方案, ...
- Manacher算法学习笔记 | LeetCode#5
Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...
- __x__(32)0908第五天__Photoshop的基本操作
1. 设置 Photoshop 的单位为 像素px 2. 标尺 显示与隐藏 Ctrl + r 3. 放大与缩小 Ctrl + 1 放大到100% Ctrl + 0 适应屏幕 Alt + ...
- 7. Buffer_包描述文件_npm常用指令_fs文件读写_模块化require的规则
1. Buffer 一个和数组类似的对象,不同是 Buffer 是专门用来保存二进制数据的. 特点: 大小固定: 在创建时就确定了,且无法调整 性能较好: 直接对计算机的内存进行操作 每个元素大小为1 ...
- ubuntu16.04 anaconda的安装和卸载
第一次安装: 1.直接从官网下载了anaconda安装包,然后bash ...sh安装. 2.过程中主要需要选择安装路径,为了把安装的软件都放在一起,我新建了一个install_software在系统 ...
- 小程序上拉加载更多数据(onReachBottom)
<!--pages/test/test.wxml--> <block wx:for="{{list}}" wx:key="item.id"&g ...
- js图片预加载与延迟加载
图片预加载的机制原理:就是提前加载出图片来,给前端的服务器有一定的压力. 图片延迟加载的原理:为了缓解前端服务器的压力,延缓加载图片,符合条件的时候再加载图片,当然不符合的条件就不加载图片. 预加载 ...
- HDU 6311 Cover (无向图最小路径覆盖)
HDU 6311 Cover (无向图最小路径覆盖) Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...