I found one way that works fine.
The idea of ββmy solution is as follows. You use colModel with many hidden columns with dummy names such as "cm0", "cm1", "cm2", ... All columns have the same data that you need in your case. To make it easier to populate the data, I use the column templates existing with 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:"md",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}); }
After that, I create jqGrid in the standard way, but using jsonReader , which use page as a function :
jsonReader: { repeatitems: false, page: function (obj) {
The function from jsonReader.page returns the same value as the default value of jsonReader , but I use the method with the function because the function will be called just before reading the main content of the JSON data. Inside the code, I get the first row of data and use its property names to populate the jsonmap property of the corresponding column and set the column name. In addition, I make several dummy columns necessary to display all the JSON data visible, and the rest of the dummy column is hidden. The last thing to do is the correction of the grid width, which was calculated earlier. So the grid will look like this:

or how is it

depend on JSON input.
The page function code is as follows:
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; }
Inside the page function, I use small helper functions
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)+");
In the working demo you can see here .
UPDATED : Another answer with a demo shows how to create a grid that has a different input data format: [[], [], ...] (array of arrays) - matrix.