此文章是基于  EasyUI+Knockout实现经典表单的查看、编辑

一. 相关文件介绍

  1. role.jsp:角色管理界面

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>角色管理</title>
<%@ include file="/common/head.jsp"%>
</head>
<body>
<div class="toolbar">
<a href="#" plain="true" class="easyui-linkbutton" icon="icon-arrow_refresh" title="刷新" data-bind="click:refreshClick">刷新</a>
<a href="#" plain="true" class="easyui-linkbutton" icon="icon-add" title="新增" data-bind="click:addClick">新增</a>
<a href="#" plain="true" class="easyui-linkbutton" icon="icon-edit" data-bind="click:editClick" title="编辑">编辑</a>
<a href="#" plain="true" class="easyui-linkbutton" icon="icon-cross" title="删除" data-bind="click:deleteClick">删除</a>
<a href="#" plain="true" class="easyui-linkbutton" icon="icon-save" data-bind="click:saveClick" title="保存">保存</a>
</div> <table id="gridlist" data-bind="datagrid:grid">
<thead>
<tr>
<th field="id" hidden="true"></th>
<th field="roleName" align="left" width="150" editor="{type:'validatebox',options:{required: true }}">角色名称</th>
<th field="roleSeq" align="left" width="100" editor="text" >排序 </th>
<th field="description" align="left" width="200" editor="text">描述 </th>
<th field="permit" align="center" width="200" formatter="formatterPermit">操作 </th>
</tr>
</thead>
</table> <script type="text/html" id="permission-template">
<div class="container" style="margin:5px;height:525px;">
<div>
<span class="icon32 icon-group32" style="padding-left:48px;font-weight:bold; font-size:14px;color:#666;" data-bind="text:role.roleName">角色名称</span>
<span data-bind="text:role.description" style="margin-left:10px;"></span>
</div> <div class="easyui-tabs" data-bind="easyuiTabs:tab">
<div title="菜单权限" >
<table id="gridlist" data-bind="treegrid:grid">
<thead>
<tr>
<th field="chk" checkbox="true"></th>
<th field="menuName" align="left" width="150">菜单 </th>
<!--
<th field="id" align="left" width="80" >编码 </th>
-->
<th field="description" align="left" width="200" >备注说明 </th>
</tr>
</thead>
</table>
</div> <div title="按钮权限">
<table data-bind="treegrid:grid2"></table>
</div> </div>
</div> <div style="text-align:center;clear:both">
<a class="easyui-linkbutton" data-options="iconCls:'icon-ok'" data-bind="click:confirmClick" href="javascript:void(0)" >确定</a>
<a class="easyui-linkbutton" data-options="iconCls:'icon-cancel'" data-bind="click:cancelClick" href="javascript:void(0)">取消</a>
</div>
</script> <script type="text/html" id="members-template">
<div style="margin:5px;">
<div style="border-bottom:1px solid #CCC; margin-bottom:5px;">
<span id="role_name" class="icon32 icon-group32" style="padding-left:48px;font-weight:bold; font-size:14px;color:#666;" data-bind="text:roleName">角色名称</span>
</div>
<div style="margin-bottom:10px;height:20px;">
<label>描述:</label><input data-bind="value:description" type="text" readonly=true class="z-txt" style="width:430px;color:#666;vertical-align:middle">
</div>
<div> 成员:</div>
<select id="user_groups" data-bind="options:members,optionsText:memberText ,value:selectValue" size="10" style="width:475px; line-height:30px;height:195px;padding:5px"></select>
<div style="margin-top:2px;">
<a href="#" class="easyui-linkbutton" id="group_add" plain="true" iconCls="icon-group-add" data-bind="click:addClick">添加</a>
<a href="#" class="easyui-linkbutton" id="group_delete" plain="true" iconcls="icon-group-delete" data-bind="click:deleteClick">删除</a>
<a href="#" class="easyui-linkbutton" id="group_clear" plain="true" iconCls="icon-clear" data-bind="click:clearClick">清空</a>
</div>
</div>
<div style="text-align:center;">
<a class="easyui-linkbutton" data-options="iconCls:'icon-ok'" data-bind="click:confirmClick" href="javascript:void(0)" >确定</a>
<a class="easyui-linkbutton" data-options="iconCls:'icon-cancel'" data-bind="click:cancelClick" href="javascript:void(0)">取消</a>
</div>
</script> <script type="text/html" id="choose-members-template">
<div style="margin:5px;height:425px;overflow:auto;">
<div style="border-bottom:1px solid #CCC; margin-bottom:5px;">
<span class="icon32 icon-org32" style="padding-left:48px;font-weight:bold; font-size:14px;color:#666;">
机构成员<input type="checkbox" style="vertical-align:middle;margin-left:5px;" data-bind="checked:checkAllOrganize"/>全选</span>
</div> <ul style="margin:0;padding:0;clear:both" data-bind="foreach:organizes">
<li style="float:left;list-style:none;margin:3px;"><input type="checkbox" data-bind="value:id,checked:checked" style="vertical-align:middle" /><label data-bind="text:organizeName" ></label></li>
</ul> <div style="border-bottom:1px solid #CCC; margin-bottom:5px;clear:both">
<span class="icon32 icon-user32" style="padding-left:48px;font-weight:bold; font-size:14px;color:#666;">
用户成员<input type="checkbox" style="vertical-align:middle;margin-left:5px;" data-bind="checked:checkAllUser"/>全选</span>
</div> <ul style="margin:0;padding:0;clear:both" data-bind="foreach:users">
<li style="float:left;list-style:none;margin:3px;"><input type="checkbox" data-bind="value:id,checked:checked" style="vertical-align:middle"/><label data-bind="text:userName"></label></li>
</ul>
</div>
<div style="text-align:center;clear:both">
<a class="easyui-linkbutton" data-options="iconCls:'icon-ok'" data-bind="click:confirmClick" href="javascript:void(0)" >确定</a>
<a class="easyui-linkbutton" data-options="iconCls:'icon-cancel'" data-bind="click:cancelClick" href="javascript:void(0)">取消</a>
</div>
</script> <%@ include file="/common/foot.jsp"%>
<script src="viewModel/sys/role.js"></script>
<script type="text/javascript">
using(['validatebox','messager','dialog']);
var data = ${model};
ko.bindingViewModel(new viewModel(data));
var formatterPermit = function (value, row) {
var html = '<a href="javascript:;" onclick=\'permissionTab(' + JSON.stringify(row) + ')\'><span class="icon icon-set1">&nbsp;</span>[编辑权限]</a>';
html += '<a href="javascript:;" onclick=\'memberDialog(' + JSON.stringify(row) + ')\' style="margin-left:10px"><span class="icon icon-users ">&nbsp;</span>[管理成员]</a>';
return html;
};
</script>
</body>
</html>

  

  2. role.js:实现角色管理功能、列表,编辑权限、管理成员功能

function viewModel() {
var self = this; this.grid = {
size: { w: 4, h: 40 },
url: rootPath+'/sys/role!list.do',
queryParams: ko.observable(),
loadFilter: function (d) {
return {rows:d,total:d.length};
}
};
this.gridEdit = new com.editGridViewModel(self.grid);
this.grid.onDblClickRow = self.gridEdit.begin;
this.grid.onClickRow = self.gridEdit.ended; this.refreshClick = function () {
window.location.reload();
}; this.addClick = function () {
self.gridEdit.addnew({});
}; this.editClick = function () {
var row = self.grid.datagrid('getSelected');
var index = self.grid.datagrid('getRowIndex', row);
self.gridEdit.begin(index, row);
}; this.deleteClick = self.gridEdit.deleterow; this.saveClick = function () {
self.gridEdit.ended();
var post = {};
post.list = self.gridEdit.getChanges(['id', 'roleName', 'roleSeq', 'description']);
if (self.gridEdit.ended() && post.list._changed) {
com.ajax({
url: rootPath+'/sys/role!edit.do',
data: ko.toJSON(post),
success: function (d) {
com.message('success', '保存成功!');
self.grid.queryParams({});
}
});
} };
} var permissionTab = function (row) {
com.dialog({
title: "角色授限",
width: 800,
height: 600,
html: "#permission-template",
viewModel: function (win) {
var self = this;
this.role = ko.mapping.fromJS(row);
this.tab = {
onSelect: function (title, index) {
if (title == '按钮权限') {
//取得菜单权限中的选中行,并重新加开到按钮权限列表中
var temp = {},data = [],panel = self.grid2.treegrid('getPanel');
utils.eachTreeRow(self.grid.treegrid('getData'), function (node) {
if (node.checked) {
data.push(utils.filterProperties(node, ['children', 'description'], true));
temp[node.id] = node;
}
});
self.grid2.treegrid('loadData', data); //checkbox点击处理函数
var checkHandler = function (obj,value) {
if (!obj.length) return;
var map = { "0": rootPath+"/content/images/checknomark.gif", "1": rootPath+"/content/images/checkmark.gif" };
obj.attr("src", map[value]).attr("value", value);
temp[obj.attr("menuId")]["btn_" + obj.attr("buttonId")] = parseInt(obj.attr("value"));
}; //注册checkbox点击事件
panel.find("td[field]").unbind("click").click(function () {
var img = $(this).find("img"), value = img.attr("value") == "1" ? "0" : "1";
checkHandler(img, value); if (img.attr("buttonId")== "_checkall")
panel.find("img[menuId=" + img.attr("menuId") + "]").each(function () {
checkHandler($(this), value);
});
}); //注册全选checkbox的事件
panel.find(".datagrid-header .icon-chk_unchecked").unbind("click").click(function () {
var chk = $(this),
value = chk.hasClass("icon-chk_checked") ? "0" : "1",
iconcls = chk.hasClass("icon-chk_checked") ? "icon-chk_unchecked" : "icon-chk_checked";
chk.removeClass("icon-chk_unchecked").removeClass("icon-chk_checked").addClass(iconcls); panel.find("img").each(function () {
checkHandler($(this), value);
});
});
}
}
}; this.grid = {
height: 460,
width: 774,
url: rootPath+'/sys/menu!getEnabled.do?roleId='+row.id,
idField: 'id',
queryParams: ko.observable(),
treeField: 'menuName',
singleSelect: false,
onCheck: function (node) {
node.checked = true;
},
onUncheck: function (node) {
node.checked = false;
},
onCheckAll:function(rows){
utils.eachTreeRow(rows, function (node) { node.checked = true; });
},
onUncheckAll: function (rows) {
utils.eachTreeRow(rows, function (node) { node.checked = false; });
},
loadFilter: function (d) {
var formatterChk = function (buttonId) {
return function (value, row) {
if (value >= 0)
return '<img menuId="' + row.id + '" buttonId="' + buttonId + '" value="' + value + '" src="' + rootPath + '/content/images/' + (value ? "checkmark.gif" : "checknomark.gif") + '"/>';
};
}
var cols = [[]];
for (var i in d.buttons)
cols[0].push({ field: 'btn_'+d.buttons[i].id, width: 50, align: 'center', title: utils.formatString('<span class="icon {1}">{0}</span>', d.buttons[i].buttonName, d.buttons[i].buttonIcon), formatter: formatterChk(d.buttons[i].id) });
self.grid2.columns(cols); return utils.toTreeData(d.menus, 'id', 'parentId', "children");
}
}; this.grid2 = {
height: 460,
width: 774,
idField: 'id',
treeField: 'menuName',
frozenColumns: [[
{ field: 'menuName', width: 150, title: '菜单' },
{
field: 'btn__checkall',
width: 50,
align: 'center',
title: '<span class="icon icon-chk_unchecked">全选</span>',
formatter: function (v, r) {
for (var i in r) {
if (i.indexOf("btn_") > -1 && r[i] > -1) {
return '<img menuId="' + r.id + '" buttonId="_checkall" src="' + rootPath + '/content/images/' + (v ? "checkmark.gif" : "checknomark.gif") + '"/>';
}
}
}
}
]],
columns: ko.observableArray(),
loadFilter: function (d) {
return utils.toTreeData(d, 'id', 'parentId', "children");
}
}; this.confirmClick = function () {
var post = {menus:[],buttons:[]};
utils.eachTreeRow(self.grid.treegrid('getData'),function(node){
if (node.checked) {
//1 取得菜单权限数据
post.menus.push({ menuId: node.id }); //2 取得按钮权限数据
for (var btn in node)
if (btn.substr(0, 4) == 'btn_' && node[btn] == '1' && btn != 'btn__checkall')
post.buttons.push({ menuId: node.id, buttonId: btn.split('_')[1]}); }
}); com.ajax({
url: rootPath+'/sys/role!editPermission.do?roleId=' + row.id,
data: ko.toJSON(post),
success: function (d) {
self.cancelClick();
com.message('success', '保存成功!');
}
}); }; this.cancelClick = function () {
win.dialog('close');
};
}
})
} var memberDialog = function (row) {
var users = data.users;
var organizes = data.organizes; com.dialog({
title: "管理成员",
width: 500,
height: 400,
html: "#members-template",
viewModel: function (win) {
var self = this;
this.members = ko.observableArray([]);
this.memberText = function (item) {
return utils.formatString('[{0}] {1}', item.memberType == 'user' ? '用户' : '机构', item.memberName);
};
com.ajax({
type: 'GET',
url: rootPath+'/sys/role!getRoleMembers.do?roleId=' + row.id,
success: function (d) {
self.members(d);
}
});
this.roleName = utils.formatString("{0}", row.roleName);
this.description = row.description || " ";
this.addClick = function () {
com.dialog({
title: "选择成员",
width: 600,
height: 500,
html: "#choose-members-template",
viewModel: function (w) {
var that = this;
for (var i in users) users[i].checked = false;
for (var i in organizes) organizes[i].checked = false;
this.users = ko.mapping.fromJS(users);
this.organizes = ko.mapping.fromJS(organizes);
this.checkAllUser = ko.observable(false);
this.checkAllUser.subscribe(function (b) {
var list = that.users();
for (var i in list)
list[i].checked(b);
});
this.checkAllOrganize = ko.observable(false);
this.checkAllOrganize.subscribe(function (b) {
var list = that.organizes();
for (var i in list)
list[i].checked(b);
});
this.confirmClick = function () {
var userlist = this.users(),organizelist=this.organizes(),memberMap = {},members = ko.toJS(self.members);
for (var j in members)
memberMap[members[j].memberType + '|' + members[j].memberId] = true; for (var i in userlist)
if (userlist[i].checked()) {
var item = { memberName: userlist[i].userName(), memberId: userlist[i].id(), memberType: 'user' };
if (!memberMap[item.memberType + '|' +item.memberId]) self.members.push(item);
} for (var i in organizelist)
if (organizelist[i].checked()) {
var item = { memberName: organizelist[i].organizeName(), memberId: organizelist[i].id(), memberType: 'organize' };
if (!memberMap[item.memberType + '|' +item.memberId]) self.members.push(item);
}
this.cancelClick();
};
this.cancelClick = function () { w.dialog('close'); };
}
});
}; this.selectValue = ko.observable();
this.deleteClick = function () {
if (this.selectValue()) {
self.members.remove(this.selectValue());
}
};
this.clearClick = function () {
self.members([]);
};
this.confirmClick = function () {
com.ajax({
url: rootPath+'/sys/role!editRoleMembers.do?roleId=' + row.id,
data: ko.toJSON(self.members),
success: function (d) {
com.message('success', '保存成功!');
self.cancelClick();
}
});
};
this.cancelClick = function () { win.dialog('close'); };
}
}); };

  

二. 效果图

  1. 访问:http://localhost:8080/ims/sys/role.do,角色管理界面

基于easyUI实现权限管理系统(三)——角色管理-LMLPHP

  2. 点击 编辑权限,菜单权限

基于easyUI实现权限管理系统(三)——角色管理-LMLPHP

  3. 按钮权限

基于easyUI实现权限管理系统(三)——角色管理-LMLPHP

  4. 点击 管理成员

基于easyUI实现权限管理系统(三)——角色管理-LMLPHP

04-26 16:14
查看更多