一:jeesite中的角色分配form表单:
1.父页面是roleAssign.jsp,子页面是selectUserToRole.jsp;
2.父页面调用子页面用的jBox,代码如下

<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>
3.jBox会调用后台RoleController.java 代码如下:

1 /** 2 * 角色分配 -- 打开角色分配对话框 3 * @param role 4 * @param model 5 * @return 6 */ 7 @RequiresPermissions("sys:role:view") 8 @RequestMapping(value = "usertorole") 9 public String selectUserToRole(Role role, Model model) { 10 List<User> userList = systemService.findUser(new User(new Role(role.getId()))); 11 model.addAttribute("role", role); 12 model.addAttribute("userList", userList); 13 model.addAttribute("selectIds", Collections3.extractToString(userList, "name", ",")); 14 model.addAttribute("officeList", officeService.findAll()); 15 return "modules/sys/selectUserToRole"; 16 }
4.调用后台会回到子页面selectUserToRole.jsp 代码如下:

<%@ 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: {showLine:false,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(","); //点击选择项回调 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); 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); }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); selectedNodes=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>
5.一进子页面会调用初始化

$(document).ready(function(){ officeTree = $.fn.zTree.init($("#officeTree"), setting, officeNodes); selectedTree = $.fn.zTree.init($("#selectedTree"), setting, selectedNodes); });
6.officeNodes和selectedNodes都是用的<c:forEach>标签遍历从后台sys/role/usertorole接口中查到的变量,

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>];
查询回来的已选的把字体设置成红色是在<c:forEach>标签中设置的。
7.var pre_ids = "${selectIds}".split(",");var ids = "${selectIds}".split(",");初始话进入子页面两个变量取的是接口中查询回来的数据是一样的;
当把待选人员点到已选人员列表时ids变量会添加一个节点的id;pre_ids还不变;
这两个变量主要是判断已选列表可否添加移除的,添加移除代码如下:

if("userTree"==treeId){ //alert(treeNode.id + " | " + ids); //alert(typeof ids[0] + " | " + typeof treeNode.id); 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); }else{ top.$.jBox.tip("角色原有成员不能清除!", 'info'); } }
8.确定分配调用form表单的提交事件

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;
idsArr用了赋值语句和三目运算符,idsArr实际就是把ids中的数据遍历添加到idsArr中;把所有人员列表的id添加到idsArr中最后在后台对已经添加的人员做处理。
form表单如下:

<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>
9.角色分配的后台代码

/** * 角色分配 * @param role * @param idsArr * @param redirectAttributes * @return */ @RequiresPermissions("sys:role:edit") @RequestMapping(value = "assignrole") public String assignRole(Role role, String[] idsArr, RedirectAttributes redirectAttributes) { if(Global.isDemoMode()){ addMessage(redirectAttributes, "演示模式,不允许操作!"); return "redirect:" + adminPath + "/sys/role/assign?id="+role.getId(); } StringBuilder msg = new StringBuilder(); int newNum = 0; for (int i = 0; i < idsArr.length; i++) { User user = systemService.assignUserToRole(role, systemService.getUser(idsArr[i])); if (null != user) { msg.append("<br/>新增用户【" + user.getName() + "】到角色【" + role.getName() + "】!"); newNum++; } } addMessage(redirectAttributes, "已成功分配 "+newNum+" 个用户"+msg); return "redirect:" + adminPath + "/sys/role/assign?id="+role.getId(); }

@Transactional(readOnly = false) public User assignUserToRole(Role role, User user) { if (user == null){ return null; } List<String> roleIds = user.getRoleIdList(); if (roleIds.contains(role.getId())) { return null; } user.getRoleList().add(role); saveUser(user); return user; }
10.类似下图:
二:jeesite中的类似角色分配ajax调用:
1.父页面调用子页面的代码:主要是点击按钮调用后台方法转换一个试图作为子页面,子页面点击确定分配和清除调用的方法,确定分配的时候会用ajax调用后台确定分配的事件。

<input id="assignButton" type="button" value="ajax分配角色" onclick="assignRole()"/> <script type="text/javascript"> function assignRole(){ top.$.jBox.open("iframe:${ctx}/role/role/openchildWin", "分配角色",810,600,{ buttons:{"确定分配":"ok", "清除已选":"clear", "关闭":true}, bottomText:"通过选择部门,然后为列出的人员添加人员。",submit:function(v, h, f){ var ids = h.find("iframe")[0].contentWindow.ids; var pre_ids = h.find("iframe")[0].contentWindow.pre_ids; var submitData = h.find("iframe")[0].contentWindow.submitData; if (v=="ok"){ // 删除''的元素 if(ids[0]==""){ ids.shift(); pre_ids.shift(); } if(pre_ids.sort().toString() == ids.sort().toString()){ top.$.jBox.tip("未选择表!", 'info'); return false; }; for (var i = 0; i<submitData.length; i++) { var map2 = {}; var nameTemp ={}; nameTemp['name'] = submitData[i].name;//名字 map2['people'] = assetTemp; var rlnListTemp = []; var rlnTemp = {}; rlnTemp['id'] = submitData[i].id;//编号 rlnTemp['rln'] = "include"; rlnListTemp.push(rlnTemp); var rlnjson = {}; rlnjson['resId']=rlnListTemp map2['rlnInfo'] = rlnjson; var json = JSON.stringify(map2); $.ajax({ type: "POST", dataType: "", url:"${ctx}/role/role/addRole", data:{"info":json}, success : function(result) { //$.fn.zTree.init($("#waitchooseTree"), setting, result).expandAll(true); alertx("添加成功!"); }, error : function() {alertx("失败");} }); } 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>
2.子页面代码如下:

<%@ page contentType="text/html;charset=UTF-8" %> <%@ include file="/WEB-INF/views/include/taglib.jsp"%> <%@ include file="/WEB-INF/views/include/head.jsp"%> <html> <head> <title>分配角色</title> <%@include file="/WEB-INF/views/include/treeview.jsp"%> <meta name="decorator" content="default"/> <script type="text/javascript"> var pre_ids = []; var ids = []; var submitData = []; $(document).ready(function() { var selectedTree;//zTree已选择对象 var setting = { view : {showLine:false}, data : { simpleData : {enable : true,idKey : "id",pIdKey : "pId",rootPId : '0'}}, callback : {onClick :treeOnClick} }; var settingRed = { view : {showLine:false, fontCss: { 'color': 'red' } }, data : { simpleData : {enable : true,idKey : "id",pIdKey : "pId",rootPId : '0'}}, callback : {onClick :treeOnClick} }; function gettree() { $.getJSON("${ctx}/project/project/myproject?type=1",function(data) { $.fn.zTree.init($("#mesresourTree"), setting, data).expandAll(true); }); $.getJSON("${ctx}/projectemporay/projectemporary/schemalView?assettype=schema",function(data) { selectedTree = $.fn.zTree.init($("#selectedTree"), settingRed, data); debugger for(var i = 0 ;i<data.length;i++){ var selectedlinfo = {}; selectedlinfo['id'] = String(data[i].id); selectedlinfo['name'] = String(data[i].name); ids.push(selectedlinfo); pre_ids.push(selectedlinfo); } }); } gettree(); //点击选择项回调 function treeOnClick(event, treeId, treeNode, clickFlag){ $.fn.zTree.getZTreeObj(treeId).expandNode(treeNode); if("mesresourTree"==treeId){ var map2 = {}; map2['id'] = treeNode.id; map2['name'] = treeNode.name; var json = JSON.stringify(map2); $.ajax({ type: "POST", dataType: "", url:"${ctx}/role/role/allPeople", data:{"info":json}, success : function(result) { $.fn.zTree.init($("#waitchooseTree"), setting, result).expandAll(true); }, error : function() {alertx("失败");} }); } var selectedId = []; if("waitchooseTree"==treeId){ debugger for(var j=0;j<ids.length;j++){ if(ids[j]==""){ ids.shift(); }else{ selectedId.push(ids[j].id+ids[j].name) } } if($.inArray(String(treeNode.id+treeNode.name), selectedId)<0){ debugger selectedTree.setting.view.fontCss["color"] = 'Black'; selectedTree.addNodes(null, treeNode); var tempInfo = {}; tempInfo['name'] = String(treeNode.name); tempInfo['id'] = String(treeNode.id); ids.push(tempInfo); submitData.push(tempInfo); } }; var pre_selectedId = []; for(var j=0;j<pre_ids.length;j++){ if(pre_ids[j]==""){ pre_ids.shift(); }else{ pre_selectedId.push(pre_ids[j].id+pre_ids[j].name) } } var submitId = []; for(var j=0;j<submitData.length;j++){ if(submitData[j]==""){ submitData.shift(); }else{ submitId.push(submitData[j].id+submitData[j].name) } } for(var j=0;j<ids.length;j++){ if(ids[j]==""){ ids.shift(); }else{ selectedId.push(ids[j].id+ids[j].name) } } if("selectedTree"==treeId){ if($.inArray(String(treeNode.id+treeNode.name), pre_selectedId)<0){ selectedTree.removeNode(treeNode); ids.splice($.inArray(String(treeNode.id+treeNode.name), selectedId), 1); submitData.splice($.inArray(String(treeNode.id+treeNode.name), submitId), 1); }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 = "未给角色添加新成员!"; }else{ tips = "已选表清除成功!"; } ids=pre_ids.slice(0); $.getJSON("${ctx}/role/role/cleartree",function(data) { selectedTree = $.fn.zTree.init($("#selectedTree"), setting, data); }); top.$.jBox.tip(tips, 'info'); } else if (v == 'cancel'){ // 取消 top.$.jBox.tip("取消清除操作!", 'info'); } return true; }; tips="确定清除已选的人员?"; top.$.jBox.confirm(tips, "清除确认", submit); }; }); </script> </head> <body> <div id="assignRole" class="row-fluid span12" style="width:95%;"> <div class="span4" style="border-right: 1px solid #A8A8A8;"> <p>部门:</p> <div id="mesresourTree" class="ztree"></div> </div> <div class="span3"> <p>待选人员:</p> <div id="waitchooseTree" 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>
3.贴一段后台代码类似这种:注意不是转页面的只是要返回的数据记得要加@ResponseBody

@ResponseBody @RequestMapping(value = "users") public List<Office> users(String id, HttpServletResponse response) throws Exception { List<Office> list = officeService.findAll(); return list; } @ResponseBody @RequestMapping(value = "users") public List<Map<String, Object>> users(String officeId, HttpServletResponse response) throws Exception { List<Map<String, Object>> mapList = Lists.newArrayList(); DataRole dataRole=new DataRole(); dataRole.setId(officeId); List<User> UserList = dataRoleService.findOfficeIdUser(dataRole); for (User e : UserList) { Map<String, Object> map = Maps.newHashMap(); map.put("id", e.getId()); map.put("pId", 0); map.put("name", e.getName()); mapList.add(map); } return mapList; }
注意:1.ajax中用selectedTree.setting.view.fontCss["color"] = 'Black';改变字体颜色,选中的列表初始化调用var settingRed设置字体为红色,添加的节点设置字体颜色为黑色。
2.submitData是添加的节点的数据(这个数据是从待选列表中点击到已选准备提交的数据),提交调用ajax使用。
3.pre_ids比对可否从已选列表中移除,ids比对可否添加到已选列表,初始进页面时pre_ids和ids数据一样,都是查询后台已选数据。
4.父页面中拿子页面的变量(注意:全局变量)h.find("iframe")[0].contentWindow.pre_ids;我们可以在debugger中查看iframe数组变量下的contentWindow-->window--->location--->pathname
确定页面不错。页面不错的话拿window下的全局变量,也可以调用方法。