jqGrid 实例中文版网址:http://blog.mn886.net/jqGrid/
国外官网:http://www.trirand.com/blog/jqgrid/jqgrid.html
http://free-jqgrid.github.io/
http://www.guriddo.net/demo/guriddojs/
http://www.trirand.com/jqgridwiki/doku.php?id=wiki:jqgriddocs
http://www.guriddo.net/documentation/guriddo/javascript/
jqGrid是Trirand软件开发公司的Tony Tomov开发的一个方便人们开发使用的web组件,它包含了许多免费和开源的库如:jQuery, ThemeRoller, & jQuery UI等 ,同时最新的版本已经支持bootstrapUI,Tony最初的时候是因为他需要一种方式来表示数据库信息,这种方式有速度上的要求同时还要独立于服务器端技术和后台数据库,于是jqGrid诞生了,从最初的版本到现在已经升级到了Guriddo jqGrid 5.4 ,之前的各个版本都是在不断的修复bug以及添加符合需求的新功能。jqGrid越来越趋于完善。
————————————————
jqGrid 是一个用来显示网格数据的jQuery插件,通过使用jqGrid可以轻松实现前端页面与后台数据的ajax异步通信。
一、jqGrid特性
- 基于jquery UI主题,开发者可以根据客户要求更换不同的主题。
- 兼容目前所有流行的web浏览器。
- Ajax分页,可以控制每页显示的记录数。
- 支持XML,JSON,数组形式的数据源。
- 提供丰富的选项配置及方法事件接口。
- 支持表格排序,支持拖动列、隐藏列。
- 支持滚动加载数据。
- 支持实时编辑保存数据内容。
- 支持子表格及树形表格。
- 支持多语言。
- 目前是免费的。
二、调用ajax的事件顺序如下:
- beforeRequest
- loadBeforeSend
- serializeGridData--从第4项开始为返回数据过程的事件
- loadError (if a error from the request occur - the event from steps 5 till 7 do not execute. If there is no error the event 4. does not execute and we continue to with the step 5.)
- beforeProcessing
- gridComplete
- loadComplete
三、JQgrid处理json数据
1、定义Jqgrid
$("#tableOEE").jqGrid({ data: [], datatype: "json", rownumbers: true, //显示行号 loadonce:true,//在加载完成后,datatype自动变成local autowidth: true, pager: "#pager", viewrecords: true,//是否显示总记录数 rowNum: 300,//表格中显示的记录数 rowList: [10, 20, 30], height: '100%', gridview: true,//整个表格都构造完成后再添加到grid中。 jsonReader:{repeatitems:false,id:"2"},//2表示id为rowData的第三个元素。 beforeProcessing:function(res,status,errror){ $.each(res.rows,function(i,n){//在来自Sever的数据Grid处理之前,格式化返回的JSON数据 n.time=Number(n.time).toExponential(3); n.shift=["早","中","晚"][n.shift]; }); }, loadComplete:function(xhr){//Grid加载完成后,可对Grid中的元素绑定事件了。分组完成。 $("td.tdQty").bind("click", {}, getDcData); var rowCount=$(this).getGridParam("records"); }, colModel: [{ name: 'line', index: 'line', width: 80, align: 'center', label: '产线', key:true,editable:true },//排序sidx { name: 'shift', index: 'shift', width: 80, align: 'center', label: '班次' }, { name: 'remark_avai', index: 'remark_avai', label: '备注', hidden: true }, { name: 'qty_dot', index: 'qty_dot', align: 'right', classes: 'linkbyPop tdQty', label: '总点数', formatter: NumFmatter }, //formatter 格式化字段,unformat:反格式化。 ] }); jQuery("#tableOEE").jqGrid('navGrid', '#pager', { edit: false, add: false, del: false, search: true, refresh: true }, {}, //编辑edit参数 {}, //添加add参数 {}, //删除del参数 { multipleSearch: true },//搜索search参数 {closOnEscape:true}//查看view参数 ); jQuery("#tableOEE").jqGrid('setGroupHeaders', {//表头分组 useColSpanStyle: true, groupHeaders: [ { startColumnName: 'time_avai', numberOfColumns: 1, titleText: 'A' }, { startColumnName: 'qty_dot', numberOfColumns: 3, titleText: 'F' }] });
2、重新加载数据
$("#tableOEE").jqGrid("clearGridData", true); $("#tableOEE").jqGrid("setGridParam", { data: {...} }); //或者 $("#tableOEE").setGridParam({ datatype: "json",url: "ajax/Punch.ashx",postData:"line=aa&lot=''"}); $("#tableOEE").trigger("reloadGrid");
3、后台处理
var GridJson=new { total="10",page="1",rows=oeeList,records=oeeList.Count.ToString()}; returnStr=new JavascriptSerialzer().Serilize(gridJson);
4、返回JSON格式:
1、当repeatitems:false时,名称要与colModel中的名字一致 。
{"total":"10","page":"1","rows"=[{"line":"A1","Shift":3,"qty":123,"time":0.02}],"records":"4"} //records为查询出的总记录数,并非本页记录数。
2、如果repeatitems:true(默认)
{"total":"10","page":"1","rows":[{id:"1",cell:["cell1","cell2"]},{id:"2",cell:["cell3","cell4"]}],"records":"4"}
对数字进行千分符分割:
function getNumberSpliter(num) { if (num != '' && !isNaN(num)) { re = /(\d{1,3})(?=(\d{3})+(?:$|\.))/g; n = String(num).replace(re, "$1,"); return n; } else return num; }
四、JQgrid处理Local数据
$("#tableOEE").jqGrid({ data: [], datatype: "local", ... }); //获得服务器数据 $.ajax({ type: "GET", cache: false, url: "ajax/Punch.ashx", data: i, success: function (res) { if (res.indexOf("SERVER_ERROR") == -1) { res = $.parseJSON(res); $.each(res, function (i, n) { this.shift = Shift[this.shift]; this.time_perdot = Number(this.time_perdot).toExponential(3); }); $("#tableOEE").jqGrid("clearGridData", true); $("#tableOEE").jqGrid("setGridParam", { data: res }); $("#tableOEE").trigger("reloadGrid"); $("td.tdQty").bind("click", {}, getDcData);//绑定grid中元素事件 } else { alert(res.replace("SERVER_ERROR", "错误")); } $.unblockUI(); }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert(textStatus + errorThrown); } });
五、JQgrid分组与行选择
$("#tableOEE").jqGrid({ grouping: true, groupingView: { groupField: ['BoxId'] },//分组 multiselect: true, autowidth: true, //... colModel: [ { name: 'Serial', index: 'Serial', align: 'center', label: '序列号' }, { name: 'BoxId', index: 'BoxId', align: 'center', label: '箱号' }, { name: 'progress_recid', key: true, index: 'progress_recid', width: 80, align: 'center', label: '内部号' }/ //key: true主键,服务器返回的数据没有ID时,将此作为rowid使用。 ], onSelectRow: selectRow }); var parentWidth = $("#DIV_Body").css("width").replace("px", ""); $("#tableOEE").jqGrid("setGridWidth", parentWidth); function selectRow(rowid, status, e) { if (status) { if ($("#tableOEE").getRowData(rowid).PalLocation != "在货仓") { $("#tableOEE").setSelection(rowid, false);//取消选择 alert("在货仓状态的卡板,只能由SIS人员操作"); } var selRows = $("#tableOEE").getGridParam('selarrrow');//'selrow'最后选择行的主键 if (selRows.length > 2) { $("#tableOEE").setSelection(rowid, false); alert("只能选择两个序列号更换"); } } }
六、 JQgrid构建查询
1、定义Jqgrid
ajax远端请求分页,排序,手工构建搜索参数,进行服务端查询,以及CURD操作。
$(function () { $("#grid").jqGrid({ url: "/PushPDA/GetTodoLists", datatype: 'json', mtype: 'Get', colNames: ['操作', 'ID', 'IP', '所属人', '生产线', '状态', '类型', '更新日期', '更新时间'], colModel: [ { name: 'act', index: 'act', align: 'center', width: 80, search: false, sortable: false, editable: false }, { hidden: true, align: 'center', name: 'ID', index: 'ID', editable: true, key: true }, { name: 'IP', align: 'center', index: 'IP', editable: true }, { name: 'Owner', align: 'center', index: 'Owner', editable: true }, { name: 'Line', align: 'center', index: 'Line', editable: true }, { name: 'Status', align: 'center', index: 'Status', editable: true, }, { name: 'Type', align: 'center', index: 'Type', editable: true, edittype: 'select', formatter: 'select', editoptions: { value: { 'CASE': '套料', 'BIG': '中大件料' } } }, { name: 'UpdateDate', align: 'center', index: 'UpdateDate', editable: false }, { name: 'UpdateTime', align: 'center', index: 'UpdateTime', editable: false } ], pager: jQuery('#pager'), rowNum: 100, rowList: [10, 20, 30, 40], height: '100%', viewrecords: true, emptyrecords: 'No records to display', jsonReader: { root: "rows", page: "page", total: "total", records: "records", repeatitems: false, Id: "0" }, autowidth: true, multiselect: false, beforeProcessing: function (res) {//格式化返回数据 if (!res) return; //$.each(res.rows, function (i, n) { // n.UpdateDate = DatefromJSON(n.UpdateDate); // n.UpdateTime = secondToTimeString(n.UpdateTime); //}); }, gridComplete: function () { var ids = $("#grid").getDataIDs();//jqGrid('getDataIDs'); for (var i = 0; i < ids.length; i++) { var cl = ids[i]; be = ""; de = ""; jQuery("#grid").jqGrid('setRowData', ids[i], { act: be + de }); } }, }).navGrid('#pager', { edit: true, add: true, del: true, search: false, refresh: true }, { // edit options zIndex: 100, url: '/PushPDA/Edit', closeOnEscape: true, closeAfterEdit: true, recreateForm: true, afterComplete: function (response) { if (response.responseText) { alert(response.responseText); } } }, { // add options zIndex: 100, url: "/PushPDA/Create", closeOnEscape: true, closeAfterAdd: true, afterComplete: function (response) { if (response.responseText) { alert(response.responseText); } } }, { // delete options zIndex: 100, url: "/PushPDA/Delete", closeOnEscape: true, closeAfterDelete: true, recreateForm: true, msg: "Are you sure you want to delete this task?", afterComplete: function (response) { if (response.responseText) { alert(response.responseText); } } }); new_search(); }); //将整数秒格式转成时间格式。 function secondToTimeString(seconds) { if (seconds == null) return ""; var hh = parseInt(seconds / 3600).toString(); seconds -= hh * 3600; var mm = Math.round(seconds / 60).toString(); if (hh.length == 1) { hh = "0" + hh; } if (mm.length == 1) { mm = "0" + mm; } return hh + ":" + mm; } //解析JOSN返回的日期字符串格式。 function DatefromJSON(jsonstr) { // return eval (jsonstr.replace(new RegExp('/Date\\((-?[0-9]+)\\)/','g'),'new Date($1)')).toLocalDateString(); if (jsonstr == null) return ""; d = eval('new ' + (jsonstr.replace(/\//g, ''))); var month = (d.getMonth() + 1); month = ("00" + month).substr(("" + month).length); var day = d.getDate() day = ("00" + day).substr(("" + day).length); return d.getFullYear() + "-" + month + "-" + day; }
2、手工构建查询参数
(1)单字段搜索:
主要构建的查询参数为searchField,searchString,searchOper
var searchPara = { // 构建查询需要的参数 searchField: "Line", searchString: strLines, searchOper: "in" }; // 获得当前postData选项的值 var postData = $("#grid").jqGrid("getGridParam", "postData"); // 将查询参数融入postData选项对象 $.extend(postData, searchPara); $("#grid").jqGrid("setGridParam", { url: "/PushPDA/GetTodoLists", search: true //将jqGrid的search选项设为true }).trigger("reloadGrid", [{ page: 1 }]); // 重新载入Grid表格,以使上述设置生效
(2)多字段搜索
主要构建的查询参数为groupOp,rules,filed,op,data.
var rules = ""; // 构建查询需要的参数 var searchField = "Line"; var searchString = strLines; var searchOper = "in"; if (searchField && searchOper && searchString) { //如果三者皆有值且长度大于0,则将查询条件加入rules字符串 rules += ',{"field":"' + searchField + '","op":"' + searchOper + '","data":"' + searchString + '"}'; } if (strDate1) { rules += ',{"field":" IP","op":"eq","data":"' + strDate1 + '"}'; } if (rules) { //如果rules不为空,且长度大于0,则去掉开头的逗号 rules = rules.substring(1); } //串联好filtersStr字符串 var filtersStr = '{"groupOp":"AND","rules":[' + rules + ']}'; // 获得当前postData选项的值 var postData = $("#grid").jqGrid("getGridParam", "postData"); // 将查询参数融入postData选项对象 $.extend(postData, { filters: filtersStr }); $("#grid").jqGrid("setGridParam", { url: "/PushPDA/GetTodoLists", search: true // 将jqGrid的search选项设为true }).trigger("reloadGrid", [{ page: 1 }]); // (7)重新载入Grid表格,以使上述设置生效
3、后台根据查询条件返回查询结果
注意使用Linq语句,以及动态Linq查询。
public JsonResult GetTodoLists(string sidx, string sord, int page, int rows, bool _search, string searchField, string searchString, string searchOper, string filters) //Gets the todo Lists. { IQueryablepdas = db.PushPDAs; IQueryable todoListsResults = null; //搜索 if (_search) { if (!string.IsNullOrEmpty(searchField))//单字段搜索 { todoListsResults = pdas.Where(p => searchString.IndexOf(p.Line) > -1); } else if (!string.IsNullOrEmpty(filters))//多字段搜索 { JObject ofilters = JObject.Parse(filters); string searchField1; string searchString1; string sql; for (int i = 0; i < ofilters["rules"].Count(); i++) { searchField1 = ofilters["rules"][i]["field"].ToString(); searchString1 = ofilters["rules"][i]["data"].ToString(); sql = "\"" + searchString1 + "\".Contains(" + searchField1 + ")"; todoListsResults = pdas.Where(sql); } } } else { return Json(new { }, JsonRequestBehavior.AllowGet); } //排序 if (string.IsNullOrEmpty(sidx)) sidx = "IP"; todoListsResults = todoListsResults.OrderBy(sidx + " " + sord); //分页 int pageIndex = Convert.ToInt32(page) - 1; int pageSize = rows; int totalRecords = pdas.Count(); var totalPages = (int)Math.Ceiling((float)totalRecords / (float)rows); todoListsResults = todoListsResults.Skip(pageIndex * pageSize).Take(pageSize); var todoListsResults1 = from p in todoListsResults.ToList() select new { p.ID, p.IP, p.Owner, p.Line, p.Status, p.Type, UpdateDate = p.UpdateDate.HasValue ? p.UpdateDate.GetValueOrDefault().ToShortDateString() : "", UpdateTime = p.UpdateTime.HasValue ? IntTimeToStringTime(p.UpdateTime.GetValueOrDefault()) : "" }; var jsonData = new { total = totalPages, page, records = totalRecords, rows = todoListsResults1 }; return Json(jsonData, JsonRequestBehavior.AllowGet); }
4、定义HTML
<div id="search_container" title="Search Options"> <div id="boxbody"> <fieldset> <legend>Query IP<span id="spanClearDates">[Clear]span>legend> <table> <tr> <td><strong>扫描枪IP: strong> <input id="Text_Date1" type="text" /> td> tr> table> fieldset> div> div> <div> <table id="grid">table> <div id="pager">div> div>