Is it possible to change colModel after loading data using jqgrid?

I have jqGrid where I need to change the model after loading the data, but before it is analyzed in the grid. In other words, I think I want to do this in the loadComplete handler. I see this approach: Setting the JQGrid and colModel column name from JSON data , but I have a bunch of grids already written that use the "load data with jqGrid" approach, and not the "preload data and transfer them to jqGrid" which is used there, and I hope to avoid re-encoding or make it different.

(Hiding and displaying hidden columns is also not practical).

Is it possible?

More details:

Basically, I don’t know which columns I need until I see the data. Let's say I show traffic as:

Date CA WA NY MN 4/20 100 90 85 72 4/21 95 85 89 70 

There is only a place to display the four states, but there can be much more (or fewer) in the data, so I want them to be listed in traffic order. Right now the data is doing this:

 { date : 4-20, ca : 100, wa : 90, ny : 85, mn : 72 hi : 56, il : 30 }, { date : 4-21, ca : 95, wa : 85, // note: for a given row, a column might be relatively lower ny : 89, // than another. The column order is based on the overall mn : 70 hi : 60, il : 45 } 

or it could be:

 { date : 4-20, ny : 110, hi : 95, il : 90, wa : 80 } 

I tried setting up columns like state1, state2, state3, state4 and then using jsonmap to reassign them, but that didn't work.

loadonce = true, datatype = json

+4
jqgrid
source share
1 answer

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) { // ------------------------ // here I add the main code // ------------------------ return obj.page; } } 

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:

enter image description here

or how is it

enter image description here

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.

+7
source share

All Articles