Я нашел один способ, который, кажется, работает хорошо.
Идея моего решения заключается в следующем.Вы используете 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
как функция :
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)+");
Рабочую демонстрацию вы можетесм. здесь .
ОБНОВЛЕНО : Другой ответ с демо показывает, как создать сетку, которая имеет другой форматвходных данных: [[], [], ...] (массив массивов) - матрица.