基本思路:
2. JavaScript业务代码负责调用REST API获得数据,然后操纵flexigrid显示数据。
特别是负责操控page bar,也就是flexigrid表格下方的哪个页面导航条进行中/英文支持,每个按钮的点击事件等。
3. REST API无状态,因此通过接收一些参数来计算返回的数据:
a. 查询条件 //根据不同的业务有所变化
b. pageSize //每页记录数目
c. pageIndex //期望返回的页面编号
返回的结果包括了:
a. 某页数据的JSON格式表示
b. 查询条件
c. 最大记录数
d. 最大页面数
先看个最后完成的效果图:
下面分步骤简述:
1. REST API的实现
REST API由于不记录状态,每次都是通过参数来得知要获取什么页面的数据。这个算法很多,有基于数据库自己提供的功能的,有纯粹在内存中计算的,我用的是先查询符合条件的记录总数,再分页,然后读取指定页的记录。
这到不是重点,关键是返回的数据格式JSON不按照flexigrid的要求,而是根据业务要求生成。之后页面端会有JavaScript代码将其转换成flexigrid格式。REST API返回的格式举例如下面的结果:
{ "sign_page":{ "max_sign_count":50,"page_index":1,"group_id":"","max_page_count":4,"signs":{ "displays":[ { "index":"0","value":{ "id":"51fe01dbe4b0f241088d3b4e","userId":"4ee175ff82bc6273d0d4672f","address":"000000000001","groupName":"ok67","location":"function test","description":"","status":"offline" } },{ "index":"1","value":{ "id":"51fe01dbe4b0f241088d3b4f","address":"000000000002",{ "index":"2","value":{ "id":"51fe01dbe4b0f241088d3b50","address":"000000000003",{ "index":"3","value":{ "id":"51fe01dbe4b0f241088d3b51","address":"000000000004",{ "index":"4","value":{ "id":"51fe01dbe4b0f241088d3b52","address":"000000000005",{ "index":"5","value":{ "id":"51fe01dbe4b0f241088d3b53","address":"000000000006",{ "index":"6","value":{ "id":"51fe01dbe4b0f241088d3b54","address":"000000000007",{ "index":"7","value":{ "id":"51fe01dbe4b0f241088d3b55","address":"000000000008",{ "index":"8","value":{ "id":"51fe01dbe4b0f241088d3b56","address":"000000000009",{ "index":"9","value":{ "id":"51fe01dbe4b0f241088d3b57","address":"000000000010",{ "index":"10","value":{ "id":"51fe01dbe4b0f241088d3b58","address":"000000000011",{ "index":"11","value":{ "id":"51fe01dbe4b0f241088d3b59","address":"000000000012",{ "index":"12","value":{ "id":"51fe01dbe4b0f241088d3b5a","address":"000000000013",{ "index":"13","value":{ "id":"51fe01dbe4b0f241088d3b5b","address":"000000000014",{ "index":"14","value":{ "id":"51fe01dbe4b0f241088d3b5c","address":"000000000015","status":"offline" } } ] } } }
2. JavaScript的实现
这是最重要的部分,必须完成JSON格式转换和page bar的操纵,比如事件绑定和处理等。为此,我实现了一个signTable.js,这是一个AMD模块。有了它,JavaScript就可以配置flexigrid,添加数据,并且支持分页。先看如何使用它。
this.table.configSigns("mydisplays",this.locale,"multiple",this.ajaxUtility,this.artDialog); ... this.table.fillInSigns("mydisplays",window.userdisplays.sign_page,this.onSelectdisplay,this);this.table就是signTable对象。就提供了两个方法,configSigns方法配置了flexigrid的列等基本信息,并且支持多选或者单选模式。后面两个参数ajaxUtility和artDialog是另外的模块用来实现ajax调用和对话框的显示。下面是该函数的实现:
// config grid's basic structures,columents and events // tableId is the id of HTML table tag // locale is en or cn // selectMod single,multiple configSigns: function(tableId,locale,selectMod,ajaxUtility,artDialog) { var id,description,location,status,page,innerHtml; this.ajaxUtility = ajaxUtility; this.artDialog = artDialog; this.locale = locale; if (locale === "en") { id = "ID"; description = "Description"; location = "Location"; status = "Status"; } else if (locale === "cn") { id = "ID"; description = "描述"; location = "位置"; status = "状态"; } this.selectMod = selectMod; $("#" + tableId).flexigrid({ dataType: 'json',width: 630,height: 260,colModel : [ {display: '',name: 'id',width: 20,sortable: true,align: 'left'},{display: id,name: 'address',width: 150,{display: description,name: 'description',width: 190,{display: location,name: 'location',width: 130,{display: status,name: 'status',width: 60,align: 'left'} ],usepager: true }); },
下面是fillInSigns函数的实现,主要负责填充数据。
// tableId the id of HTML table tag // locale en or cn // value the data for filling in table // onSelect the event function for hanlding row selection // ob this for callback function fillInSigns: function(tableId,signPage,onSelect,ob) { this.signPage = signPage; $("#" + tableId).flexAddData(this.convert(locale,signPage)); $("#" + tableId +" tbody tr td div input").on("click",ob,onSelect); this.updatePagebar(); }
由于我的代码是从以前做的系统演化而来,所以signTable不是个通用的分页功能解决方案。仅在这里提供一个解决思路和完整的可参考代码,读者请自己根据情况修改吧。或许什么时候有时间,做成一个通用的flexigrid扩展也不一定。下面是signTable.js的全部内容:
// provides some common functions on top of flexigrid for simplifying web front-end development // If some web page use one same grid,add it here,they can resuse these codes define("signTable",["jquery","flexigrid","flexigrid.pack"],function ($) { 'use strict'; return { // config grid's basic structures,getStatus: function (status) { if (status === "online") { if (this.locale === "cn") { return "在线"; } else { return "Online"; } } if (status === "offline") { if (this.locale === "cn") { return "离线"; } else { return "Offline"; } } return status; },buildCell: function (line) { var template; if (this.selectMod == "multiple") { template = "{\"cell\":[\"<input id='{0}' class='row_class' type='checkBox' value='{0}'/>\",\"{1}\",\"{2}\",\"{3}\",\"{4}\"]}"; return jQuery.validator.format(template,line.id,line.address,line.description,line.location,this.getStatus(line.status)); } else { template = "{\"cell\":[\"<input id='{0}' class='row_class' name='single' type='radio' value='{0}'/>\",this.getStatus(line.status)); } },convert : function (locale,signPage) { var ds,d,i,str,s1,s2; ds = signPage.signs.displays; this.length = ds.length; d = "{\"page\": 1,\"total\": 40,\"rows\":["; for (i = 0; i < this.length; (i += 1)) { str = this.buildCell(ds[i].value); d += str; if (i !== (this.length - 1)) { d += ","; } } d += "]}"; return jQuery.parseJSON(d); },afterLoadPageSigns: function (ob,data) { if (data.status === 0) { ob.fillInSigns("mydisplays",ob.locale,JSON.parse(data.value).sign_page,ob.onSelectdisplay,ob); } else { if (ob.locale === "cn") { ob.artDialog.error('设备查询失败'); } else { ob.artDialog.error('Load signs Failed.'); } } },// for inner reuse search: function(pageIndex) { var pageSize = $("select[name=rp]").val(),data; data = { 'groupId': this.signPage.group_id,'pageSize': pageSize,'pageIndex': pageIndex,'column': "address",'ascending': 1 }; this.ajaxUtility.post('pageSigns',false,data,this.afterLoadPageSigns,null,this); },onNext: function (event) { var ob = event.data; ob.search(ob.signPage.page_index + 1); },onPrev: function (event) { var ob = event.data; ob.search(ob.signPage.page_index - 1); },onLast: function (event) { var ob = event.data; ob.search(ob.signPage.max_page_count); },onFirst: function (event) { var ob = event.data; ob.search(1); },onReload: function (event) { var pageIndex,ob = event.data; pageIndex = $("#pageIndexInput").val(); if (pageIndex !== "") { ob.search(parseInt(pageIndex,10)); } },onChangePageSize: function (event) { var ob = event.data; ob.search(ob.signPage.page_index); },/* onChangePageIndex: function (event) { var ob,pageIndex; ob = event.data; pageIndex = $(this).val(); if (pageIndex !== "") { ob.search(parseInt(pageIndex,*/ // fill in Chinese or English words according to this.locale // fill in page number according to the total pages and current page index // enable/disable buttons in page bar updatePagebar: function() { var innerHtml,t1,j,pageSize = 15; if (this.locale === "cn") { t1 = "显示 {0} 到 {1},总数: {2} 设备"; } else { t1 = "from {0} to {1},total: {2} signs"; } i = pageSize * (this.signPage.page_index - 1) + 1; j = i + pageSize - 1; innerHtml = jQuery.validator.format(t1,this.signPage.max_sign_count); $($(".pDiv2").children()[10]).children(0).html(innerHtml); if (this.locale === "cn") { t1 = "页面 <input id=\"pageIndexInput\" type=\"number\" min=\"1\" style=\"width:30px;\" value=\"{0}\"> 到 <span>{1}</span>"; } else { t1 = "Page <input id=\"pageIndexInput\" type=\"number\" min=\"1\" style=\"width:30px;\" value=\"{0}\"> to <span>{1}</span>"; } innerHtml = jQuery.validator.format(t1,this.signPage.page_index,this.signPage.max_page_count); $(".pcontrol").html(innerHtml); if (this.signPage.page_index === 1) { if (this.signPage.max_page_count === 1) { $(".pPrev").removeClass("pButton"); $(".pFirst").removeClass("pButton"); $(".pNext").removeClass("pButton"); $(".pLast").removeClass("pButton"); } else { $(".pPrev").removeClass("pButton"); $(".pFirst").removeClass("pButton"); $(".pNext").addClass("pButton"); $(".pLast").addClass("pButton"); } } else { if (this.signPage.page_index === this.signPage.max_page_count) { $(".pNext").removeClass("pButton"); $(".pLast").removeClass("pButton"); $(".pPrev").addClass("pButton"); $(".pFirst").addClass("pButton"); } else { $(".pNext").addClass("pButton"); $(".pLast").addClass("pButton"); $(".pPrev").addClass("pButton"); $(".pFirst").addClass("pButton"); } } if (!this.hasPageBarEvents) { $(".pNext").on("click",this,this.onNext); $(".pFirst").on("click",this.onFirst); $(".pPrev").on("click",this.onPrev); $(".pLast").on("click",this.onLast); $(".pReload").on("click",this.onReload); $("select[name=rp]").on("change",this.onChangePageSize); // $("#pageIndexInput").on("change",this.onChangePageIndex); this.hasPageBarEvents = true; } },getSelectednum: function() { var n = 0; $('.row_class').each( function () { if ($(this).is(':checked')) { n += 1; } } ); return n; },// tableId the id of HTML table tag // locale en or cn // value the data for filling in table // onSelect the event function for hanlding row selection // ob this for callback function fillInSigns: function(tableId,onSelect); this.updatePagebar(); } }; });
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。