我找到了一种似乎可行的方法。
我的解决方案的想法如下。您使用colModel 有许多隐藏列,其中包含虚拟名称,例如“cm0”、“cm1”、“cm2”……所有列都具有与您的情况相同的数据。为了更轻松地填充数据,我使用自 jqGrid 3.8.2 以来存在的列模板:
var mygrid=jQuery("#list"),
cmIntTemplate = {
width:50,
sorttype:"int",
formatter:"integer",
align:"right",
hidden:true
},
cm = [
// here we define the first columns which we always has
// the list can be empty or has some columns with
// the properties other as the rest (without cmIntTemplate)
{name:"date",label:"Date",key:true,width:100, fixed:true,
formatter:'date',formatoptions:{srcformat:"m-d",newformat:"m/d"}}
], maxCol = 30, dummyColumnNamePrefix = "cm";
// Add dummy hidden columns. All the columns has the same template
for (i=0;i<maxCol;i++) {
cm.push({name:dummyColumnNamePrefix+i,template:cmIntTemplate});
}
之后我以标准方式创建 jqGrid,但使用 jsonReader 使用 page as function:
jsonReader: {
repeatitems: false,
page: function (obj) {
// ------------------------
// here I add the main code
// ------------------------
return obj.page;
}
}
jsonReader.page 中的函数返回与默认jsonReader 相同的值,但我使用带函数的方式,因为该函数将在读取 JSON 数据的主要内容之前直接调用。在代码内部,我获取第一行数据并使用它的属性名称来填充相应列的jsonmap 属性并设置列名称。此外,我制作了一些显示所有 JSON 数据可见所需的虚拟列,并隐藏了其余的虚拟列。应该做的最后一件事是校正先前计算的网格宽度。所以网格看起来像这样:
或者像这样
取决于 JSON 输入数据。
page函数的代码如下:
page: function (obj) {
var rows = obj.rows, colModel = mygrid[0].p.colModel,
cmi, iFirstDummy, firstRow, prop,
orgShrinkToFit, isFound,
showColNames = [], hideColNames = [];
if (typeof(rows) === "undefined" || !$.isArray(rows) || rows.length === 0) {
// something wrong need return
return obj.page;
}
// find the index of the first dummy column
// in the colModel. If we use rownumbers:true,
// multiselect:true or subGrid:true additional
// columns will be inserted at the begining
// of the colModel
iFirstDummy = -1;
for(i=0;i<colModel.length;i++) {
cmi = colModel[i];
if (dummyTestRegex.test(cmi.name)) {
iFirstDummy = i;
break;
}
}
if (iFirstDummy === -1) {
// something wrong need return
return obj.page;
}
orgShrinkToFit = clearShrinkToFit();
// we get the first row of the JSON data
firstRow = rows[0];
for (prop in firstRow) {
if (firstRow.hasOwnProperty(prop)) {
// we will use the properties name of the first row
// as the names of the column headers of the grid
// find column index having prop as the name
isFound = false;
for(i=0;i<colModel.length;i++) {
cmi = colModel[i];
if (cmi.name === prop) {
isFound = true;
showColNames.push(prop);
break;
}
}
if(!isFound) {
// labels defines the column names
cmi = colModel[iFirstDummy];
showColNames.push(cmi.name);
mygrid.jqGrid('setLabel',cmi.name,prop);
// because of bug in jqGrid with calculation of width
// we have to reset the width
cmi.width = cmIntTemplate.width;
// we set jsonmap which jqGrid will use instead
// of dummy column names to read all row data
cmi.jsonmap = prop;
iFirstDummy++;
}
}
}
// fill the list of unused columns
for(i=0;i<colModel.length;i++) {
cmi = colModel[i];
if ($.inArray(cmi.name, showColNames) === -1 && dummyTestRegex.test(cmi.name)) {
hideColNames.push(cmi.name);
}
}
mygrid.jqGrid('showCol',showColNames);
mygrid.jqGrid('hideCol',hideColNames);
setGridWidthAndRestoreShrinkToFit(orgShrinkToFit);
return obj.page;
}
在page 函数内部,我使用了小的辅助函数
var clearShrinkToFit = function() {
// save the original value of shrinkToFit
var orgShrinkToFit = mygrid.jqGrid('getGridParam','shrinkToFit');
// set shrinkToFit:false to prevent shrinking
// the grid columns after its showing or hiding
mygrid.jqGrid('setGridParam',{shrinkToFit:false});
return orgShrinkToFit;
},
setGridWidthAndRestoreShrinkToFit = function(orgShrinkToFit) {
// calculate the new grid width
var width=0, i=0, headers=mygrid[0].grid.headers, l=headers.length;
for (;i<l; i++) {
var th = headers[i].el;
if (th.style.display !== "none") {
width += $(th).outerWidth();
}
}
// restore the original value of shrinkToFit
mygrid.jqGrid('setGridParam',{shrinkToFit:orgShrinkToFit});
// set the grid width
mygrid.jqGrid('setGridWidth',width);
},
dummyTestRegex = new RegExp(dummyColumnNamePrefix+"(\\d)+");
你可以看到here的工作演示。
更新:Another answer 和 the demo 展示了如何创建具有另一种输入数据格式的网格:[[]、[]、...](数组数组)-矩阵。