最近在開發系統權限管理相關的功能,主要包含用戶管理,資源管理,角色管理,組類別管理等小的模塊。以前的Web開發中也用過jQueryEasyUI插件,感受這款插件簡單易用,上手很快。之前用到的主要是Datagrid組件,此次爲了區分資源的父子關係,打造更好的用戶體驗,遂探索一下Treegrid組件。javascript
jQuery EasyUI是一組基於jQuery的UI插件集合體,而jQuery EasyUI的目標就是幫助web開發者更輕鬆的打造出功能豐富而且美觀的UI界面。開發者不須要編寫複雜的javascript,也不須要對css樣式有深刻的瞭解,開發者須要瞭解的只有一些簡單的html標籤。css
EasyUI Treegrid樹形網格:擴展自 $.fn.datagrid.defaults。經過 $.fn.treegrid.defaults 重寫默認的 defaults。樹形網格(treegrid)用於以網格形式顯示分層數據。它是基於數據網格(datagrid)的,並結合了樹視圖(treeview)和可編輯網格。樹形網格(treegrid)容許您建立可定製的、可異步展開的行,並以多列形式顯示分層數據。html
jQuery EasyUI官網:http://www.jeasyui.com/java
jQuery EasyUI中文網:Treegrid:http://www.jeasyui.net/plugins/186.htmljquery
⑴ 引入EasyUI相關的js和css文件:web
<script type="text/javascript" src="/assets/scripts/jquery-1.8.2.min.js"></script> <script type="text/javascript" src="/assets/scripts/jquery-easyui-1.4.5/jquery.min.js"></script> <script type="text/javascript" src="/assets/scripts/jquery-easyui-1.4.5/jquery.easyui.min.js"></script> <link rel="stylesheet" type="text/css" href="/assets/scripts/jquery-easyui-1.4.5/themes/default/easyui.css"> <link rel="stylesheet" type="text/css" href="/assets/scripts/jquery-easyui-1.4.5/themes/icon.css">
⑵ 在HTML標籤中建立樹形網格(treegrid):json
<table id="tgTab" title="查詢結果" class="easyui-treegrid" style="width:1080px;height:450px"> <thead> <tr> <th data-options="field:'name',width:160">資源名稱</th> <th data-options="field:'description',width:100">資源描述</th> <th data-options="field:'code',width:100, align:'center' ">標識碼</th> <th data-options="field:'type',width:50, align:'center' ">類型</th> <th data-options="field:'status',width:40, align:'center' ">狀態</th> <th data-options="field:'gmtCreate',width:80,align:'center' ">建立時間</th> <th data-options="field:'gmtModified',width:80, align:'center'">最後修改時間</th> <th data-options="field:'id',width:60,formatter:rowFormatter, align:'center' ">操做</th> </tr> </thead> </table>
⑶ Js初始化Treegrid資源列表:api
(function($){ function pagerFilter(data){ if ($.isArray(data)){ data = { total: data.length, rows: data } } var dg = $(this); var state = dg.data('treegrid'); var opts = dg.treegrid('options'); var pager = dg.treegrid('getPager'); pager.pagination({ onSelectPage:function(pageNum, pageSize){ opts.pageNumber = pageNum; opts.pageSize = pageSize; pager.pagination('refresh',{ pageNumber: pageNum, pageSize: pageSize, beforePageText: '第', //頁數文本框前顯示的漢字 afterPageText: '頁 共 {pages} 頁', displayMsg: '當前顯示 {from} - {to} 條記錄 共 {total} 條記錄' }); dg.treegrid('loadData',state.originalRows); }, beforePageText: '第', //頁數文本框前顯示的漢字 afterPageText: '頁 共 {pages} 頁', displayMsg: '當前顯示 {from} - {to} 條記錄 共 {total} 條記錄' }); if (!state.originalRows){ state.originalRows = data.rows; } var topRows = []; var childRows = []; $.map(state.originalRows, function(row){ row._parentId ? childRows.push(row) : topRows.push(row); }); data.total = topRows.length; var start = (opts.pageNumber-1)*parseInt(opts.pageSize); var end = start + parseInt(opts.pageSize); data.rows = $.extend(true,[],topRows.slice(start, end).concat(childRows)); return data; } var appendMethod = $.fn.treegrid.methods.append; var loadDataMethod = $.fn.treegrid.methods.loadData; $.extend($.fn.treegrid.methods, { clientPaging: function(jq){ return jq.each(function(){ var state = $(this).data('treegrid'); var opts = state.options; opts.loadFilter = pagerFilter; var onBeforeLoad = opts.onBeforeLoad; opts.onBeforeLoad = function(row,param){ state.originalRows = null; onBeforeLoad.call(this, row, param); }; $(this).treegrid('loadData', state.data); $(this).treegrid('reload'); }); }, loadData: function(jq, data){ jq.each(function(){ $(this).data('treegrid').originalRows = null; }); return loadDataMethod.call($.fn.treegrid.methods, jq, data); }, append: function(jq, param){ return jq.each(function(){ var state = $(this).data('treegrid'); if (state.options.loadFilter == pagerFilter){ $.map(param.data, function(row){ row._parentId = row._parentId || param.parent; state.originalRows.push(row); }); $(this).treegrid('loadData', state.originalRows); } else { appendMethod.call($.fn.treegrid.methods, jq, param); } }) } }); })(jQuery); $(function(){ $('#tgTab').treegrid({ iconCls: 'icon-ok', rownumbers: true, animate: true, collapsible: true, fitColumns: true, url: '../api/initResourcesList?type=-1', method: 'get', idField: 'id', treeField: 'name', pagination: true, pageSize: 80, pageList: [80,120,160] }).treegrid('clientPaging'); }); function rowFormatter(value, row, index){ //value爲該條數據的field字段的值,row爲該行(顯示在頁面)數據的全部信息,index當前行,單引號裏面必須雙引號,雙引號裏面必須單引號,裏面再有就需轉義 return '<img id="update" src="/assets/images/layout/update.png" onclick="updateRes('+value+')"/> ' + ' <img id="delete" src="/assets/images/layout/delete.png" onclick="deleteRes('+value+')"/>'; }
⑷ Java後臺生成資源列表JSON數據:app
/** * 將資源封裝成資源樹 * @param list * @param parentId */ @SuppressWarnings("deprecation") private List<Map<String,Object>> createTreeGridTree(List<UsersResource> list) { //存放轉換後的資源樹 List<Map<String,Object>> treeGridList =new ArrayList<Map<String,Object>>(); for (int i = 0; i < list.size(); i++) { Map<String, Object> map = null; UsersResource res = list.get(i); if (res.getParentId().equals(0)) { map = new HashMap<String, Object>(); map.put("id", res.getId()); map.put("name", res.getName()); map.put("description", res.getDescription()); map.put("code", res.getCode()); if (res.getType() == 0) { map.put("type", "URL資源"); } else if (res.getType() == 1) { map.put("type", "組件資源"); } else { map.put("type", "虛擬根資源"); } if (res.getStatus() == 0) { map.put("status", "隱藏"); } else { map.put("status", "顯示"); } map.put("gmtCreate", res.getGmtCreate().toLocaleString()); map.put("gmtModified", res.getGmtModified().toLocaleString()); map.put("children", createTreeGridChildren(list, res.getId())); } if (map != null) { treeGridList.add(map); } } return treeGridList; } /** * 遞歸設置資源樹 * @param list * @param parentId * @return childList */ @SuppressWarnings("deprecation") private List<Map<String, Object>> createTreeGridChildren(List<UsersResource> list, int parentId) { List<Map<String, Object>> childList = new ArrayList<Map<String, Object>>(); for (int j = 0; j < list.size(); j++) { Map<String, Object> map = null; UsersResource treeChild = list.get(j); if (treeChild.getParentId().equals(parentId)) { map = new HashMap<String, Object>(); map.put("id", treeChild.getId()); map.put("name", treeChild.getName()); map.put("description", treeChild.getDescription()); map.put("code", treeChild.getCode()); if (treeChild.getType() == 0) { map.put("type", "URL資源"); } else if (treeChild.getType() == 1) { map.put("type", "組件資源"); } else { map.put("type", "虛擬根資源"); } if (treeChild.getStatus() == 0) { map.put("status", "隱藏"); } else { map.put("status", "顯示"); } map.put("gmtCreate", treeChild.getGmtCreate().toLocaleString()); map.put("gmtModified", treeChild.getGmtModified().toLocaleString()); map.put("children", createTreeGridChildren(list, treeChild.getId())); } if (map != null) { childList.add(map); } } return childList; } @GET @Path("initResourcesList") @Override public Object initResourcesList(String page, String rows, String name, String code, int type) { System.out.println("資源傳參:page:"+ page +",rows:"+ rows + ",name:"+ name +",code:"+ code + ",type:"+ type); UsersResource usersRes = new UsersResource(); usersRes.setName(name); usersRes.setCode(code); usersRes.setType(type); int recordNum = 0; // 總記錄數 recordNum = usersResourceService.getUsersResourceTotalNumBySQL(usersRes); //System.out.println("資源總條數:" + recordNum); // *******分頁****************** int pageSize = 80; pageSize = Integer.parseInt(rows); int curPageNo = 1; curPageNo = Integer.parseInt(page); // 當前頁號 int startIndex = 0; // 開始索引 if (recordNum > 0) { if (curPageNo == 1) { startIndex = 0; // 開始索引 } else { startIndex = curPageNo * pageSize - pageSize; // 開始索引 } } Map<String, Object> paramMap = new HashMap<String, Object>(); paramMap.put("startIndex", startIndex); paramMap.put("pageSize", pageSize); paramMap.put("name", name); paramMap.put("code", code); paramMap.put("type", type); List<UsersResource> resourceList = new ArrayList<UsersResource>(); resourceList = usersResourceService.searchUsersResourceBySQL(paramMap); Map<String, Object> result = new HashMap<String, Object>(2); JSONArray jsonArray = new JSONArray(); List<Map<String,Object>> treeGridList =new ArrayList<Map<String,Object>>(); //調用方法實現樹 treeGridList = createTreeGridTree(resourceList); jsonArray = JSONArray.fromObject(treeGridList); result.put("total", recordNum); result.put("rows", jsonArray); //System.out.println("json:" + JSONObject.fromObject(result).toString()); return JSONObject.fromObject(result); }
Model類:UsersResource異步
package com.ouc.mkhl.platform.authority.model; import java.io.Serializable; import java.util.Date; //RBAC權限管理用戶資源信息 public class UsersResource implements Serializable { private static final long serialVersionUID = 10002121L; private Integer id; //用戶資源Id private Integer authId; //權限中心資源Id private String name; //資源名稱 private String description; //資源描述 private String url; //連接地址 private Integer type; //資源類型:0-URL資源,1-組件資源 private Integer status; //狀態:0-隱藏,1-展現 private String code; //標識碼 private String configuration; //配置項 private String moduleName; //模塊名稱 private Date gmtCreate; //建立時間 private Date gmtModified; //最後修改時間 private String createBy; //建立人 private String lastModifedBy; //最後修改人 private Integer orderIndex; //排序號 private Integer parentId; //父資源 public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getAuthId() { return authId; } public void setAuthId(Integer authId) { this.authId = authId; } public String getName() { return name; } public void setName(String name) { this.name = name == null ? null : name.trim(); } public String getDescription() { return description; } public void setDescription(String description) { this.description = description == null ? null : description.trim(); } public String getUrl() { return url; } public void setUrl(String url) { this.url = url == null ? null : url.trim(); } public Integer getType() { return type; } public void setType(Integer type) { this.type = type; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } public String getCode() { return code; } public void setCode(String code) { this.code = code == null ? null : code.trim(); } public String getConfiguration() { return configuration; } public void setConfiguration(String configuration) { this.configuration = configuration == null ? null : configuration .trim(); } public String getModuleName() { return moduleName; } public void setModuleName(String moduleName) { this.moduleName = moduleName == null ? null : moduleName.trim(); } public Date getGmtCreate() { return gmtCreate; } public void setGmtCreate(Date gmtCreate) { this.gmtCreate = gmtCreate; } public Date getGmtModified() { return gmtModified; } public void setGmtModified(Date gmtModified) { this.gmtModified = gmtModified; } public String getCreateBy() { return createBy; } public void setCreateBy(String createBy) { this.createBy = createBy == null ? null : createBy.trim(); } public String getLastModifedBy() { return lastModifedBy; } public void setLastModifedBy(String lastModifedBy) { this.lastModifedBy = lastModifedBy == null ? null : lastModifedBy .trim(); } public Integer getOrderIndex() { return orderIndex; } public void setOrderIndex(Integer orderIndex) { this.orderIndex = orderIndex; } public Integer getParentId() { return parentId; } public void setParentId(Integer parentId) { this.parentId = parentId; } }
最終效果醜了點,須要請美工美化一下,還有分頁的地方有個Bug須要改一改。分頁Bug以下圖:
Treegrid擴展自Datagrid,用過Datagrid的這個學起來也不是很難。