主要是(roleAssign.jsp , selectUserToRole.jsp )2个jsp页面的JS方法调用比较复杂,主页面要获取弹窗页面的数据
var pre_ids = h.find("iframe")[0].contentWindow.pre_ids;
var ids = h.find("iframe")[0].contentWindow.ids;
top.$.jBox.open("iframe:${ctx}/sys/role/usertorole?id=${role.id}",... 这个selectUserToRole.jsp页面就在一个iframe里面。
里面很多JQuery方法见注解。var officeNodes 的初始方法比较厉害,直接使用<c:forEach >
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<%@ page contentType="text/html;charset=UTF-8" %> <%@ include file="/WEB-INF/views/include/taglib.jsp"%> <html> <head> <title>分配角色</title> <meta name="decorator" content="default"/> </head> <body> <ul class="nav nav-tabs"> <li><a href="${ctx}/sys/role/">角色列表</a></li> <li class="active"><a href="${ctx}/sys/role/assign?id=${role.id}"><shiro:hasPermission name="sys:role:edit">角色分配</shiro:hasPermission><shiro:lacksPermission name="sys:role:edit">人员列表</shiro:lacksPermission></a></li> </ul> <div class="container-fluid breadcrumb"> <div class="row-fluid span12"> <span class="span4">角色名称: <b>${role.name}</b></span> <span class="span4">归属机构: ${role.office.name}</span> <span class="span4">英文名称: ${role.enname}</span> </div> <div class="row-fluid span8"> <span class="span4">角色类型: ${role.roleType}</span> <c:set var="dictvalue" value="${role.dataScope}" scope="page" /> <span class="span4">数据范围: ${fns:getDictLabel(dictvalue, 'sys_data_scope', '')}</span> </div> </div> <sys:message content="${message}"/> <div class="breadcrumb"> <form id="assignRoleForm" action="${ctx}/sys/role/assignrole" method="post" class="hide"> <input type="hidden" name="id" value="${role.id}"/> <input id="idsArr" type="hidden" name="idsArr" value=""/> </form> <input id="assignButton" class="btn btn-primary" type="submit" value="分配角色"/> <script type="text/javascript"> $("#assignButton").click(function(){ top.$.jBox.open("iframe:${ctx}/sys/role/usertorole?id=${role.id}", "分配角色",810,$(top.document).height()-240,{ buttons:{"确定分配":"ok", "清除已选":"clear", "关闭":true}, bottomText:"通过选择部门,然后为列出的人员分配角色。",submit:function(v, h, f){ var pre_ids = h.find("iframe")[0].contentWindow.pre_ids; var ids = h.find("iframe")[0].contentWindow.ids; //nodes = selectedTree.getSelectedNodes(); if (v=="ok"){ // 删除''的元素 if(ids[0]==''){ ids.shift(); pre_ids.shift(); } if(pre_ids.sort().toString() == ids.sort().toString()){ top.$.jBox.tip("未给角色【${role.name}】分配新成员!", 'info'); return false; }; // 执行保存 loading('正在提交,请稍等...'); var idsArr = ""; for (var i = 0; i<ids.length; i++) { idsArr = (idsArr + ids[i]) + (((i + 1)== ids.length) ? '':','); } $('#idsArr').val(idsArr); $('#assignRoleForm').submit(); return true; } else if (v=="clear"){ h.find("iframe")[0].contentWindow.clearAssign(); return false; } }, loaded:function(h){ $(".jbox-content", top.document).css("overflow-y","hidden"); } }); }); </script> </div> <table id="contentTable" class="table table-striped table-bordered table-condensed"> <thead><tr><th>归属公司</th><th>归属部门</th><th>登录名</th><th>姓名</th><th>电话</th><th>手机</th><shiro:hasPermission name="sys:user:edit"><th>操作</th></shiro:hasPermission></tr></thead> <tbody> <c:forEach items="${userList}" var="user"> <tr> <td>${user.company.name}</td> <td>${user.office.name}</td> <td><a href="${ctx}/sys/user/form?id=${user.id}">${user.loginName}</a></td> <td>${user.name}</td> <td>${user.phone}</td> <td>${user.mobile}</td> <shiro:hasPermission name="sys:role:edit"><td> <a href="${ctx}/sys/role/outrole?userId=${user.id}&roleId=${role.id}" onclick="return confirmx('确认要将用户<b>[${user.name}]</b>从<b>[${role.name}]</b>角色中移除吗?', this.href)">移除</a> </td></shiro:hasPermission> </tr> </c:forEach> </tbody> </table> </body> </html>
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<%@ page contentType="text/html;charset=UTF-8" %> <%@ include file="/WEB-INF/views/include/taglib.jsp"%> <html> <head> <title>分配角色</title> <meta name="decorator" content="blank"/> <%@include file="/WEB-INF/views/include/treeview.jsp" %> <script type="text/javascript"> var officeTree; var selectedTree;//zTree已选择对象 // 初始化 $(document).ready(function(){ officeTree = $.fn.zTree.init($("#officeTree"), setting, officeNodes); selectedTree = $.fn.zTree.init($("#selectedTree"), setting, selectedNodes); }); var setting = {view: {selectedMulti:false,nameIsHTML:true,showTitle:false,dblClickExpand:false}, data: {simpleData: {enable: true}}, callback: {onClick: treeOnClick}}; var officeNodes=[ <c:forEach items="${officeList}" var="office"> {id:"${office.id}", pId:"${not empty office.parent?office.parent.id:0}", name:"${office.name}"}, </c:forEach>]; var pre_selectedNodes =[ <c:forEach items="${userList}" var="user"> {id:"${user.id}", pId:"0", name:"<font color='red' style='font-weight:bold;'>${user.name}</font>"}, </c:forEach>]; var selectedNodes =[ <c:forEach items="${userList}" var="user"> {id:"${user.id}", pId:"0", name:"<font color='red' style='font-weight:bold;'>${user.name}</font>"}, </c:forEach>]; var pre_ids = "${selectIds}".split(","); var ids = "${selectIds}".split(","); //点击选择项回调 //包含3个tree的点击事件,比如点击officeTree中的节点,加载数据放入userTree中; function treeOnClick(event, treeId, treeNode, clickFlag){ $.fn.zTree.getZTreeObj(treeId).expandNode(treeNode); if("officeTree"==treeId){ $.get("${ctx}/sys/role/users?officeId=" + treeNode.id, function(userNodes){ $.fn.zTree.init($("#userTree"), setting, userNodes); }); } if("userTree"==treeId){ //alert(treeNode.id + " | " + ids); //alert(typeof ids[0] + " | " + typeof treeNode.id); //$.inArray搜索数组中指定值并返回它的索引(如果没有找到则返回-1) if($.inArray(String(treeNode.id), ids)<0){ selectedTree.addNodes(null, treeNode); ids.push(String(treeNode.id)); } }; if("selectedTree"==treeId){ if($.inArray(String(treeNode.id), pre_ids)<0){ selectedTree.removeNode(treeNode); ids.splice($.inArray(String(treeNode.id), ids), 1);//清除点击的node }else{ top.$.jBox.tip("角色原有成员不能清除!", 'info'); } } }; function clearAssign(){ var submit = function (v, h, f) { if (v == 'ok'){ var tips=""; if(pre_ids.sort().toString() == ids.sort().toString()){ tips = "未给角色【${role.name}】分配新成员!"; }else{ tips = "已选人员清除成功!"; } ids=pre_ids.slice(0);//如果省略 end 参数,则 index 之后的所有的所有元素都会包含在结果中 selectedNodes=pre_selectedNodes; //pre_ids,pre_selectedNodes 是用来重置的,设计的很巧妙 $.fn.zTree.init($("#selectedTree"), setting, selectedNodes); top.$.jBox.tip(tips, 'info'); } else if (v == 'cancel'){ // 取消 top.$.jBox.tip("取消清除操作!", 'info'); } return true; }; tips="确定清除角色【${role.name}】下的已选人员?"; top.$.jBox.confirm(tips, "清除确认", submit); }; </script> </head> <body> <div id="assignRole" class="row-fluid span12"> <div class="span4" style="border-right: 1px solid #A8A8A8;"> <p>所在部门:</p> <div id="officeTree" class="ztree"></div> </div> <div class="span3"> <p>待选人员:</p> <div id="userTree" class="ztree"></div> </div> <div class="span3" style="padding-left:16px;border-left: 1px solid #A8A8A8;"> <p>已选人员:</p> <div id="selectedTree" class="ztree"></div> </div> </div> </body> </html>
一个技巧点:为什么要把 model.addAttribute("selectIds", Collections3.extractToString(userList, "name", ",")); , 注意这里提取的是name, 我开始还以为作者失误,其实是故意的。因为在后面保存角色和用户的对应关系时,ids里面的name就找不到相应的user,也就是保存了新添加的用户。 User user = systemService.assignUserToRole(role, systemService.getUser(idsArr[i]));