之前有提及过jqgrid这个很不错的jquery grid, 非常适合企业MIS系统使用. 本文以一个显示学生成绩结果的页面, 来说明它的一些用法, 手写代码, 运行可能会报错, 不过思路是经过验证的.
=================================
加载theme
=================================
默认的jqgrid样式很难看, jqgrid 完全支持jquery ui的 theme, 我们选择一个好看的theme, 将 ui.theme.css 加到html中即可
theme 下载: http://jqueryui.com/themeroller/
=================================
不想在init和reload时都设置jqgrid的所有属性
=================================
我们自然不推荐一个页面多次设置同一个jqgrid的属性, 尤其jqgrid的colModel属性.
好的作法是, 在init grid的时候, 设置全部的属性, 而在reload时仅仅发出新数据请求.
=================================
鱼和熊掌皆得: 启用排序和允许reload
=================================
jqgrid 当然支持reload 操作, 重点代码是:
jQuery('#grid_resultset').jqGrid('setGridParam', {url: target_url});
jQuery('#grid_resultset').trigger('reloadGrid');
但需要特别注意: jqgrid 只有在设置 loadonce 为 true 后, 才允许客户端排序. 但如果 init jqgrid 时设置了loadonce=true 后, jqgrid将会在第一次加载后, 自动修改datatype属性值为 local , 这之后简单触发 reloadGrid trigger, jqgrid并不会真的做reload动作. 解决方法是, 在 reload之前, 先将 datatype 属性修改为 json.
总结为:
1. 在init时候, 设置属性 loadonce 为 true
2. reload 代码为:
jQuery('#grid_resultset').jqGrid('setGridParam', {datatype:'json'});
jQuery('#grid_resultset').jqGrid('setGridParam', {url: target_url});
jQuery('#grid_resultset').trigger('reloadGrid');
//enable jqgrid sortable again
jQuery('#grid_resultset').jqGrid('setGridParam', {loadonce: true, forceClientSorting: true});
看起来还挺复杂的, 所以我这边封装成一个 realoadJqGrid() 函数.
=================================
cell 内容的 formatter
=================================
1. 简单formatter
参考 formatPercentage()和unformatPercentage(), 以及 formatProfileLink()和 unformatProfileLink(), formatter函数应该是成对的, 当然一般情况下没有unformat函数也是可以的.
2. 复杂formatter, 比如ratio值的小计和总计
上例中, 我们要显示每个学生的课程优良率, 另外也要显示班级的优良率, 最后还有一个grand total行, 要显示全校的课程优良率.
小计: 统计一个班级的优良率,
总计: 统计一个学校的优良率,
要统计课程优良率, 针对每个学生, 优良率是: good_course_count/total_course_count, 但最后需要统计每个class的优良率, 是通过 jqgrid 的 grouping的, 优良率是放在grouping 行中的. 要统计全校的优良率, 会在最后的 grand total.
仅仅为column指定 formatterGoodScorePercentage() 是不够的, 还是为该column指定 summaryType 函数, 比如 summaryTypeGoodScore()
=================================
自动换行 Jqgrid 的 Header
=================================
将下面的css style加到html 的head节即可.
<style type="text/css">
/* enable word wrap in jqgrid header */
th.ui-th-column div {
white-space: normal ;
height: auto ;
padding: 2px;
}
</style>
<html> <body> <table id="grid_resultset"></table> <div id="pgrid_resultset"></div> </body> </html>
<script> function formatPercentage(cellval, options, rowObject, act) { //http://www.guriddo.net/demo/guriddojs/functionality/formatters_custom/index.html var cellHtml= "<span originalValue='" + cellval + "'>" + Math.round(cellval*100)+"%" + "</span>"; return cellHtml; //上面拼字符串太复杂了, 推荐使用 sprintf.min.js, 比如下面示例 //var url_fmt="/module/download?file_type=%s&year=%s&month=%s&areas=%s"; //var target_url=vsprintf(url_fmt, ['ytm', '2016','01' ]); } function unformatPercentage(cellval, options, cellObject){ return $(cellObject.html()).attr("originalValue"); } function formatProfileLink(cellval, options, rowObject, act) { if (options.rowId === "") //grouping row { var cellHtml= cellval; return cellHtml; } else { var cellHtml= '<a href="/profile/cellval">cellval </a>'; return cellHtml; } } function unformatProfileLink(cellval, options, cellObject) { return $(cellObject.html()).val(); } function formatterGoodScorePercentage(cellval, options, rowObject, act) { if (options.rowId === "") { if (rowObject['name']!='Grand total') //grand total row { if (cellval.total_course_count_sum==0) cellval=0; else cellval=cellval.good_course_count_sum/cellval.total_course_count_sum; var cellHtml= "<span originalValue='" + cellval + "'>" + Math.round(cellval*100)+"%" + "</span>"; return cellHtml; } else //grouping row { cellval=rowObject['total_course_count']/rowObject['good_course_count'] ; var cellHtml= "<span originalValue='" + cellval + "'>" + Math.round(cellval*100)+"%" + "</span>"; return cellHtml; } } else //ordinary row { var cellHtml= "<span originalValue='" + cellval + "'>" + Math.round(cellval*100)+"%" + "</span>"; return cellHtml; } } function summaryTypeGoodScore(val, name, record) { if (typeof (val) === "string") { val = {max: false, total_course_count_sum: 0, good_course_count_sum: 0}; } val.total_course_count_sum += record['total_course_count']; val.good_course_count_sum += record['good_course_count']; val.max = true; return val; } function exportJqGrid(fab_line) { // Export the data to csv file var url = '/download' window.location.assign(url) ; } function initJqGrid() { var target_url='/scorecard_api' // alert(target_url); var myUserData ={ id:0, name:"Grand total", student_name:"", age:"", good_course_count:"", total_course_count:"", good_rate:"" } ; jQuery("#grid_resultset").jqGrid({ colModel: [ { name: "class" ,index:'class',label: 'Class No', search: true, 60, sortable: true,sorttype: 'text',align:"left",formatter: formatProfileLink}, { name: "student_name" ,index:'student_name',label: 'Student Name',key:true, search: true, 60, sortable: true,sorttype: 'text',align:"left",formatter: formatProfileLink}, { name: "age" , index:'age', label: 'Student Age', search: false,100, sortable: true, sorttype: 'number', align:"left"}, { name: "good_course_count" , index:'good_course_count', label: 'Good course count', search: false,100, sortable: true, sorttype: 'number', align:"left"}, { name: "total_course_count" , index:'total_course_count', label: 'Total course count', search: false,100, sortable: true, sorttype: 'number', align:"left"}, { name: "good_rate" , index:'good_rate', label: 'Good rate', search: false,100, sortable: true, sorttype: 'number', align:"left",formatter: formatterGoodScorePercentage, summaryType:summaryTypeGoodScore } ], url:target_url, datatype: "json", userData: myUserData, shrinkToFit: false, rownumbers: false, height: 350 , 1250, rowNum:10000, rowList: [], // if [] given, hide the page count indicator. if [10000] given, one page will show at most 10000 records, and the 10000 number will show in pager bar viewrecords: true, //定义是否要显示总记录数 loadonce: true, //allow sort when loadonce=true hoverrows: false, //禁用 mouse hovering sortable: true, forceClientSorting: true, gridview: true, ignoreCase: true, // Make the "Search" popup search case-insensitive multiselect:false, pager: '#pgrid_resultset', caption: "Student scorecard", // sortname : "name", //默认的排序列,这个参数会被提交到后台 // sortorder: "asc", grouping:true, groupingView : { groupField : ['class'], groupSummary : [true], groupColumnShow : [true], groupText : ['<b>{0}</b>'], groupCollapse : true, showSummaryOnHide: true, groupOrder: ['asc'] }, footerrow: true, userDataOnFooter: true }); jQuery('#grid_resultset').jqGrid('navGrid', '#pgrid_resultset', { search: true, searchtext: "Search", // Make the Search icon have a "Search" label next to it edit: false, add: false, del: false, refresh: false }, {}, // default settings for edit {}, // default settings for add {}, // delete { closeOnEscape: true, closeAfterSearch: true, ignoreCase: true, multipleSearch: false, multipleGroup: false, showQuery: false, sopt: ['cn', 'eq', 'ne'], defaultSearch: 'cn' }).navButtonAdd('#pgrid_resultset', { caption: "Export", buttonicon: "ui-icon-disk", onClickButton: function () { exportJqGrid(); }, position: "last" }); } function realoadJqGrid() { target_url='/scorecard_api?'+some_new_query_conditions; //reload jqgrid jQuery('#grid_resultset').jqGrid('setGridParam', {datatype:'json'}); jQuery('#grid_resultset').jqGrid('setGridParam', {url: target_url}); jQuery('#grid_resultset').trigger('reloadGrid'); //enable jqgrid sortable again jQuery('#grid_resultset').jqGrid('setGridParam', {loadonce: true, forceClientSorting: true}); } </script>