如果要实现上面的grid,使用原生的jqgrid如下:
function queryUser(){
$("#testJqgrid").trigger("reloadGrid",[{page:1}]);
}
$(function(){
initGrid();
});
function initGrid(){
$("#testJqgrid").jqGrid({
datatype: "json",
mtype:'POST',
url:"<%=request.getContextPath()%>/gridServer!server.do",
colNames:['编号','用户名', '密码'],
colModel:[
{name:'id',index:'id', width:100,editable:true,edittype:'text'},
{name:'userName',index:'userName', width:100,editable:true,sorttype:'date'},
{name:'password',index:'password', width:100,editable:true,edittype:'text'}
],
viewrecords:true,
rowNum:10,
rowList:[10,20,30],
sortname: 'id',
sortorder: "asc",
viewrecords: true,
autowidth:true,
height:'auto',
caption:"用户信息",
multiselect: true,
pager:'pageDiv',
altRows:true,
altclass:'gridAltclass',
prmNames:{
page:"pageNum",
rows:"pageSize",
sort: "sordCol",
order: "orderRule",
search:"_search"
}
,jsonReader:{
total:'pageTotal',
page:'pageNum',
records:'totalSize',
rows:'rows'
},
beforeRequest:function(){
$("#testJqgrid").jqGrid('setGridParam',{
postData:{
gridSql:'com.myproject.user.dao.UserDao.queryByCondition',
userName:$("#userName").val()
}
});
}
});
}
如果要实现多个这样的grid,其实很多类似datatype、mtype、viewrecords、autowidth、height等等这样的配置信息是重复的,而且每次修改配置文件的时候必须要保证colNames、colModel的长度必须一致,为了让datatype等公共配置信息不分布在各个地方,我在jqgrid上做了简单的包装。虽有很多配置信息修改jqgrid源代码会更佳快捷,但我不建议这样做。如果修改了源代码,以后想通过升级jqgrid版本来引进新功能的时候我们不得不重修对新版本的源码做一次同样的修改,稍有不慎漏改或者改错了某个地方可能会导致不可预知的错误。
jquery.jqGrid.extend.js
if( Array.prototype.indexOf==undefined ){
Array.prototype.indexOf = function(el){
return $.inArray(el,this);
};
}
function isEmptyString( str ){
return str==undefined || $.trim(str)=='';
}
function queryGridData(gridId){
$("#"+gridId).trigger("reloadGrid",[{page:1}]);
}
function exportGridExcel(gridId){
extJqGrid.exportGridExcel(gridId);
}
var extJqGridObjects = {};
var extJqGrid ={
defaultConfig:{
datatype:'json',
mtype:'POST',
url:contextPath+"/gridServer!server.do",
rowNum:10,
rowList:[10,15,20],
altRows:true,
altclass:'gridAltclass',
autowidth:true,
height:'auto',
scrollOffset:0,
forceFit:true,
viewrecords:true,
toolbar:[true,'top'],
//pgbuttons:true,
selectLocalAllRow:false,
rownumbers:true,
showPager:true,
loadDataFlag:true,
useColSpanStyle:false,
excelDataFrom:'server',
'emptyrecords':'没有符合条件的记录',
prmNames:{
page:"pageNum",
rows:"pageSize",
sort: "sordCol",
order: "orderRule",
search:"_search"
}
,jsonReader:{
total:'pageTotal',
page:'pageNum',
records:'totalSize',
rows:'rows'
}
},
GridHeader:function(colModel){
if( colModel.colspan!=undefined&&colModel.colspan>1 ){
this.colName = isEmptyString(colModel.colspanTitle)?colModel.colName : colModel.colspanTitle;
if( isEmptyString(this.colName) ){
this.colName = '';
}
}else{
this.colName = colModel.colName;
}
this.name = colModel.name;
this.isParent = false;
this.countFlag=colModel.countFlag;
},
/**
* MergeHeader extends GridHeader
*/
MergeHeader:function(colModels,colIndex){
var colModel = colModels[colIndex];
extJqGrid.GridHeader.call(this,colModel);
if( colModel.colspan!=undefined&&colModel.colspan>1 ){
var subHeaders = [];
for( var i=colIndex;i<(colIndex+colModel.colspan);i++ ){
subHeaders.push( new extJqGrid.GridHeader(colModels[i]));
}
this.subHeaders = subHeaders;
this.isParent = true;
}
},
/**
* 初始化grid表头信息,如果isParent为true,则表示该表头为合并单元格
*/
initGridHeaders:function(config){
var colModels =config.colModel;
var gridHeaders = [];
for( var i=0;i<colModels.length;i++ ){
if(colModels[i].hidden||isEmptyString(colModels[i].name)) continue;
gridHeaders.push(new extJqGrid.MergeHeader(colModels,i));
i+= colModels[i].colspan==undefined ? 0 : (colModels[i].colspan-1);
}
config.gridHeaders = gridHeaders;
},
/**
* 合并表头信息
*/
GroupHeader:function(gridHeader){
this.startColumnName = gridHeader.name;
this.numberOfColumns = gridHeader.subHeaders.length;
this.titleText = gridHeader.colName;
},
/**
*合并表头
*/
setGroupHeaders:function(config){
if(!config.useColSpanStyle)
return;
var groupHeaders = [];
$(config.gridHeaders).each(function(index,gridHeader){
if( gridHeader.isParent ){
groupHeaders.push(new extJqGrid.GroupHeader(gridHeader));
}
});
$("#"+config.gridId).jqGrid('setGroupHeaders', {
useColSpanStyle: true,
groupHeaders:groupHeaders
});
},
initColModel:function(config){
var undefinedColNames = false;
if( config.colNames==undefined ){
undefinedColNames = true;
config.colNames=[];
}
var colModels = config.colModel;
$.each(colModels,function(index,colModel){
if( colModel.key===true&&config.keyName==undefined ){
config.keyName = colModel.name;
}
if( !config.useColSpanStyle&&colModel.colspan!=undefined&&colModel.colspan>1 ){
config.useColSpanStyle = true;
}
if( colModel.index==undefined&&colModel.name!=undefined ){
colModel.index = colModel.name;
}
if(undefinedColNames){
if(colModel.colName==undefined){
colModel.colName = colModel.name==undefined ? "" : colModel.name;
}
config.colNames.push(colModel.colName);
}
});
extJqGrid.initGridHeaders(config);
}
,init:function(gridId,userConfig){
userConfig.gridId = gridId;
var config = extJqGrid.initGridConfig(userConfig);
extJqGrid.initGridEvent(config);
return config;
}
,initGridConfig:function(userConfig){
var config = {};
$.extend(true,config,extJqGrid.defaultConfig,userConfig);
extJqGrid.initColModel(config);
if(config.rowNum==undefined){
config.rowNum = rowList[0];
}
if(config.loadAll==true){
config.rowNum = -1;
}
if(config.showPager==true&&config.pager==undefined){
if( $("#extJqGrid_page_"+config.gridId).length==0 ){
$("#"+config.gridId).after('<div id="extJqGrid_page_'+config.gridId+'"></div>');
}
config.pager = 'extJqGrid_page_'+config.gridId;
}
config.pagerId = config.pager;
if( config.cellEdit&&config.cellsubmit==undefined ){
config.cellsubmit='clientArray';
}
if( config.exportExcel==true ){
if(isEmptyString(config.exportExcelName)){
config.exportExcelName = isEmptyString(config.caption) ? 'gridExportExcel.xls' : config.caption;
}
if( $("#_gridExportExcelForm").length==0 ){
$("body").prepend('<form action="'+contextPath+'/gridServer!export.do" id="_gridExportExcelForm" style="display: none;" method="post">'+
"<input type='hidden' id='_exportExcelName' name='exportGridParam.exportExcelName' >"+
"<input type='hidden' id='_gridHeadStr' name='exportGridParam.gridHeadStr' >"+
"<input type='hidden' id='_gridSql' name='exportGridParam.gridSql' >"+
"<input type='hidden' id='_excelDataSql' name='exportGridParam.excelDataSql' >"+
"<input type='hidden' id='_datasourceClass' name='exportGridParam.datasourceClass' >"+
"<input type='hidden' id='_queryParamStr' name='exportGridParam.queryParamStr' >"+
"<input type='hidden' id='_gridLocalDatas' name='gridLocalDatas' >"+
'</form>');
}
}
return config;
}
,exportGridExcel:function(gridId){
var config = extJqGridObjects[gridId];
if(config==undefined){
return;
}
var gridExportExcelForm = $("#_gridExportExcelForm");
$(gridExportExcelForm).find("input").val('');
$("#_exportExcelName").val(config.exportExcelName);
$("#_gridHeadStr").val(JSON.stringify(config.gridHeaders));
if(config.excelDataFrom==='server'){
extJqGrid.exportGridExcelFromServer(config,gridExportExcelForm);
}else if(config.excelDataFrom==='local'){
extJqGrid.exportGridExcelFromLocal(config,gridExportExcelForm);
}
$("#_gridExportExcelForm").submit();
}
,exportGridExcelFromServer:function(config,gridExportExcelForm){
queryGridData(config.gridId);
$(gridExportExcelForm).attr('action',(contextPath+'/gridServer!export.do?timeStap='+new Date().getTime()));
if(!isEmptyString(config.gridSql)){
$("#_gridSql").val(config.gridSql);
}
if(!isEmptyString(config.excelDataSql)){
$("#_excelDataSql").val(config.excelDataSql);
}
if(!isEmptyString(config.datasourceClass)){
$("#_datasourceClass").val(config.datasourceClass);
}
var postData = $("#"+config.gridId).jqGrid('getGridParam','postData');
if(postData!=undefined){
$("#_queryParamStr").val(JSON.stringify(postData));
}
}
,exportGridExcelFromLocal:function(config,gridExportExcelForm){
$(gridExportExcelForm).attr('action',(contextPath+'/gridServer!exportFromLocal.do?timeStap='+new Date().getTime()));
var datas = extJqGrid.getAllLocalDatas(config.gridId);
$("#_gridLocalDatas").val(JSON.stringify(datas));
}
,getAllLocalDatas:function(gridId){
var config = extJqGridObjects[gridId];
var rowDatas = [];
if(config.multiselect){
if(config.loadonce){ //一次性加载:所有的数据 在页面保存
$(config.selectIds).each(function( index,rowId ){
rowDatas.push( $("#"+gridId).getLocalRow(rowId));
});
}else{ //非一次性加载:在服务器端分页的
$($("#"+gridId).jqGrid('getGridParam','selarrrow')).each(function( index,rowId ){
rowDatas.push( $("#"+gridId).getRowData(rowId));
});
}
}else{
if(config.loadonce){ // 一次性加载:所有的数据 在页面保存
rowDatas = $("#"+gridId).getGridParam('data');
}else{ // 非一次性加载:在服务器端分页的
rowDatas = $("#"+gridId).getRowData();
}
}
return rowDatas;
}
,initGridEvent:function(config){
extJqGrid.initBeforeRequestEvent(config);
extJqGrid.initGridCompleteEvent(config);
if( config.cellEdit==true ){
extJqGrid.initEditEvent(config);
}
extJqGrid.initSelectEvent(config);
}
,initEditEvent:function(config){
extJqGrid.initAfterEditCell(config);
extJqGrid.initBeforeSaveCell(config);
extJqGrid.initAfterSaveCell(config);
}
,initSelectEvent:function(config){
//extJqGrid.initBeforeSelectRow(config);//解决最新版本cellEdit和mutilselect同时为true不能选择的问题
extJqGrid.initSelectLocalAllRow(config);
extJqGrid.initOnSelectRow(config);
extJqGrid.initOnSelectAll(config);
}
,initOnSelectRow:function(config){
if(typeof config.onSelectRow ==='function'){
config.customOnSelectRow = config.onSelectRow;
}
config.onSelectRow = function(rowid,status,e){
if(config.customOnSelectRow!=undefined){
config.customOnSelectRow.apply(this,arguments);
}
if( config.selectIds!=undefined ){
extJqGrid.modifySelectIds(config,rowid,status);
}
};
}
,initSelectLocalAllRow:function(config){//初始化一次性加载时选择本地所有文件的事件
if(config.multiselect===true&&config.selectLocalAllRow===true&&config.loadonce===true){
config.selectIds=[];
}
}
,initOnSelectAll:function(config){
if( typeof config.onSelectAll ==='function' ){
config.customOnSelectAll = config.onSelectAll;
}
config.onSelectAll = function(rowids,status){
if(config.customOnSelectAll!=undefined){
config.customOnSelectAll.apply(this,arguments);
}
if(config.selectIds!=undefined){
$(rowids).each(function(index,rowid){
extJqGrid.modifySelectIds(config,rowid,status);
});
}
};
}
,modifySelectIds:function( config,rowid,status ){
if( status ){
if($.inArray(rowid,config.selectIds)==-1 ){
config.selectIds.push(rowid);
}
}else{
config.selectIds = $.grep(config.selectIds,function(_rowid,index){
return _rowid!=rowid;
});
/*
if(config.selectAllLocalRows){
$('#'+config.gridId+"SelectAllLocalRows").attr('checked', false);
}
*/
}
}
,initBeforeSelectRow:function(config){
if( typeof config.beforeSelectRow !='function'&&config.cellEdit==true&&config.multiselect==true ){
config.beforeSelectRow = function(rowid, e){
$(this).restoreRow(rowid);
return false;
};
}
}
,initAfterEditCell:function(config){
if(typeof config.afterEditCell =='function'){
config.customAfterEditCell = config.afterEditCell;
}
config.afterEditCell = function(rowid, cellname, value, iRow, iCol){//注册焦点离开保存单元格事件
if(config.customAfterEditCell!=undefined){
config.customAfterEditCell.apply(this,arguments);
}
if( !(config.customAfterEditCell!=undefined&&config.customAfterEditCell.toString().indexOf("saveCell")!=-1)){
$("#"+iRow+"_"+cellname,"#"+config.gridId).blur(function(){
$('#'+config.gridId).jqGrid('saveCell',iRow, iCol);
});
}
extJqGridObjects[config.gridId].editCellOldValue =value;
};
}
,initBeforeSaveCell:function(config){
if(typeof config.beforeSaveCell =='function'){
config.customBeforeSaveCell = config.beforeSaveCell;
}
config.beforeSaveCell = function(rowid, cellname, value, iRow, iCol){
if( config.customBeforeSaveCell!=undefined ){
var returnValue = config.customBeforeSaveCell.apply(this,arguments);
if( returnValue==false ){
return extJqGridObjects[config.gridId].editCellOldValue;
}
}
};
}
,initAfterSaveCell:function(config){
if( typeof config.afterSaveCell =='function' ){
config.customAfterSaveCell=config.afterSaveCell;
}
config.afterSaveCell=function(rowid, cellname, value, iRow, iCol){
if(config.customAfterSaveCell!=undefined){
config.customAfterSaveCell.apply(this, arguments);
}
if( value!=extJqGridObjects[config.gridId].editCellOldValue ){
$("#"+config.gridId+" tr td.edit-cell").css({background:'#55C8FC',color:'red'});
}
};
}
,initBeforeRequestEvent:function(config){
if(typeof config.beforeRequest =='function'){
config.customBeforeRequest = config.beforeRequest;
}
config.beforeRequest = function(){
if(config.loadDataFlag==false){
config.loadDataFlag=true;
return false;
}
config.loadDataFlag = false;
if( config.customBeforeRequest!=undefined ){
var requestFlag = config.customBeforeRequest.apply(this,arguments);
if( requestFlag==false ){
return false;
}
}
if(config.defaultRequestParamNames==undefined){//初始化默认的参数名称
config.defaultRequestParamNames = [];
for( var i in config.prmNames ){
config.defaultRequestParamNames.push(config.prmNames[i]);
}
}
var postData = $("#"+config.gridId).jqGrid('getGridParam','postData');
if(postData==undefined){
postData = {};
}else{
for(var item in postData){
if($.inArray(item,config.defaultRequestParamNames)==-1){
postData[item]= undefined;
}
}
}
if( config.postData!=undefined ){
$.extend(postData,config.postData);
}
postData['loadonce'] = config.loadonce;
postData['gridSql'] = config.gridSql;
postData['countSql'] = config.countSql;
postData['datasourceClass'] = config.datasourceClass;
if( !config.loadDataFlag ){
config.loadDataFlag = true;
}
if( config.loadAll||config.loadonce ){
jQuery.extend(postData, {loadAll:true});
}
if( config.postParamFields!=undefined ) {
$.each(config.postParamFields,function(index, _paramName){
var _paramValue = $("#"+_paramName).val();
if(_paramValue!=null&& $.trim(_paramValue)!=''){
postData[_paramName] = $.trim(_paramValue);
}else{
postData[_paramName] = '';
}
});
}
if( $.isFunction(config.preparePostData) ){
var _postData = config.preparePostData.apply(this,arguments);
if( _postData!=undefined&&_postData!=null ){
jQuery.extend(postData, _postData);
}
}
$("#"+config.gridId).jqGrid('setGridParam',{
postData:postData,
url:(contextPath+"/gridServer!server.do?timeStamp="+new Date().getTime())
});
};
}
,initGridCompleteEvent:function(config){
if( typeof config.gridComplete == 'function' ){
config.customGridComplete = config.gridComplete;
}
config.gridComplete = function(){//如果beforeRequest返回false,则不会触发该事件
var gridObject = extJqGridObjects[config.gridId];
gridObject.loadDataFlag = true;
if( config.customGridComplete!=undefined ){
config.customGridComplete.apply(this,arguments);
}
//本地分页且多选的时候使用
if(config.multiselect===true&&config.selectLocalAllRow===true
&&config.loadonce===true&&config.keyName!=undefined){
$("#"+config.gridId).resetSelection();
var currentPageDatas = $("#"+config.gridId).jqGrid("getRowData");
$(currentPageDatas).each(function(index,data){
if($.inArray(data[config.keyName],config.selectIds)!=-1){
$("#"+config.gridId).setSelection(data[config.keyName],false);
}
});
}
};
}
,selectLocalAllRow:function(gridId){
extJqGridObjects[gridId].selectIds = extJqGrid.getAllLocalRowIds(gridId);
extJqGrid.selectAllRow(gridId);
}
,deSelectLocalAllRow:function(gridId){
extJqGridObjects[gridId].selectIds = [];
extJqGrid.selectAllRow(gridId, false);
}
,selectAllRow:function(gridId,checked){
$("#"+gridId).trigger("jqGridSelectAll",!(checked===false));
/*
$('#cb_'+gridId).attr('checked', (checked===false));
$("#cb_"+gridId).trigger("click");
$('#cb_'+gridId).attr('checked', !(checked===false));
*/
}
,deselectAllRow:function(gridId){
extJqGrid.selectAllRow(gridId, false);
}
,getAllLocalRowIds:function( gridId ){
var config = extJqGridObjects[gridId];
if( config.allLocalRowIds==undefined||config.allLocalRowIds==null||config.allLocalRowIds.length==0 ){
var allLocalRowIds = [];
var allLocalRowDatas = $("#"+config.gridId).getGridParam('data');
$(allLocalRowDatas).each(function( index,rowData ){
allLocalRowIds.push(rowData._id_);
});
config.allLocalRowIds = allLocalRowIds;
}
return config.allLocalRowIds;
}
};
$.fn.extJqGrid = function(userConfig){
var gridId = $(this).attr('id');
var config = extJqGrid.init(gridId, userConfig);
extJqGridObjects[config.gridId] = config;
$("#"+gridId).jqGrid(config);
extJqGrid.setGroupHeaders(config);
$(this).bind('jqGridSelectAll',function(e,checkFlag){
if(e.isTrigger===2){
return;
}
$('#cb_'+gridId).attr('checked', (checkFlag===false));
$("#cb_"+gridId).trigger("click");
$('#cb_'+gridId).attr('checked', !(checkFlag===false));
});
};
引入jquery.jqGrid.extend.js,还实现相同的表格,代码如下:
<pre name="code" class="javascript">$("#testJqgrid").extJqGrid({
colModel:[
{name:'id',colName:'编号',key:true,width:100},
{name:'userName',colName:'用户名',width:100},
{name:'password',colName:'密码', width:100}
],
gridSql:'com.myproject.user.dao.UserDao.queryByCondition',
postParamFields:["userName"],
caption:"用户信息",
multiselect:true
});
相对于使用原生的jqgrid,这里只需要简单的配置一下colModel、gridSql(查询sql)、postParamFields(查询参数input id),以后要实现其他的表格同样也是只需要定义着几个参数即可。
其实对于大部分的表格来说,数据都来源于数据库,基本上一个sql语句就可以把表格的数据查询出来,所以这里提供了gridSql配置,对于那些不能简简单单使用一个sql来查询的表格,则可以使用datasourceClass配置来实现,datasourceClass是后台的一个java类全名。
合并表头,只要在colModel的元素中添加colspan属性即可
修改单元格内容后,自动标识(背景颜色不是很好看,读者可以自己调整)
导出excel,只要配置exportExcel:true,即可,然后调用exportGridExcel(gridId)即可实现导出excel功能,导出的excel表头合并信息跟页面的grid一致
也可以通过配置excelDataFrom:"local"来设定只导出页面中的本地数据,当excelDataFrom为local,且grid为多选时,则只导出选中的记录
如果excelDataFrom为local,且不多选为false时,则只导出当前页面的数据。
如果loadone为true,且多选为false时,则导出页面表格中所有的本地数据。
如果loadone为true,且多选为true时,则导出所有选中的本地数据(包括分页选中的数据,jqgrid不支持分页选中,但我封装的这个支持,后面会介绍)
分页多选:
假设有这样的需求,我们在第一页选择几条记录,然后翻到第二页再选择几条记录,最后翻回第一页,要求原来选中的记录状态任然为选中。jqgrid是不支持这样的特性的,所以我添加了pageMultiselect选项来完成类似这样的功能。当且仅当loadonce、multiselect和pageMultiselect都为true时可实现翻页多选(大家可以根据自己的需求做相关修改)
第一页选中3条
第二页选中两条
本地全选:
跟分页多选的条件一样,当且仅当loadonce、multiselect和pageMultiselect都为true时,可以使用extJqGrid.selectLocalAllRow()方法选择本地所有记录,调用extJqGrid.selectLocalAllRow()方法取消全选本地记录
extJqGrid.selectLocalAllRow('testJqgrid');
extJgGrid.deSelectLocalAllRow('testJqgrid'<span style="font-family: Arial, Helvetica, sans-serif;">);</span>
触发全选事件:
如果使用原生的jqgrid,想要使用程序触发jqGridSelectAll事件进行全选是无效的,虽然jqgrid官方文档提供了jqGridSelectAll事件的说明,但源码中根本没有定义这样的事件。我在封装的js中添加了jqGridSelectAll事件,通过以下代码可以触发grid的全选和取消全选事件
$("#testJqgrid").trigger("jqGridSelectAll",true);
$("#testJqgrid").trigger("jqGridSelectAll",false);
因为后台东西过多,所以这里只提供了页面的js实现,有问题的同学可以留言或者直接把问题发送到blackbeauty1024@163.com,如果程序中存在什么问题,也希望大家能帮忙指正,谢谢!