如何用免费的jqgrid中的remapColumnsByNamereplaceremapColums

如何在jqgrid中保存当前行的代码

用于保存jqgrid状态。 它使用列号保存jqgrid列状态。 如果jqgrid colmodel在服务器中更改,这会导致在浏览器中的JavaScript错误。

在JQGrid注释中冻结rownum列和https://github.com/free-jqgrid/jqGrid/blob/master/README49.md描述方法remapColumnsByName 。 我希望使用这个修复问题。

免费的jqgrid是从今天的git master下载的。 在调整列大小或移动行后状态保存

 saveColumnState.call($grid, $grid[0].p.remapColumns); 

被改为

 saveColumnState.call($grid, $grid[0].p.remapColumnsByName); 

并在loadComplete代码中恢复状态

  if (isColState && myColumnsState.permutation.length > 0 && myColumnsState.permutation.length === cm.length) { $grid.jqGrid("remapColumns", myColumnsState.permutation, true); } 

  if (isColState && myColumnsState.permutation.length > 0 && myColumnsState.permutation.length === cm.length) { $grid.jqGrid("remapColumnsByName", myColumnsState.permutation, true); } 

现在行

  if (isColState && myColumnsState.permutation.length > 0 && 

导致错误

 Uncaught TypeError: Cannot read property 'length' of undefined 

如何解决这个问题,使列的状态可以使用,如果列定义更改?

方法被定义为

 var saveColumnState = function (perm) { var colModel = this.jqGrid('getGridParam', 'colModel'), i, l = colModel.length, colItem, cmName, postData = this.jqGrid('getGridParam', 'postData'), columnsState = { search: this.jqGrid('getGridParam', 'search'), page: this.jqGrid('getGridParam', 'page'), rowNum: this.jqGrid('getGridParam', 'rowNum'), sortname: this.jqGrid('getGridParam', 'sortname'), sortorder: this.jqGrid('getGridParam', 'sortorder'), autoedit: autoedit, rownumbers: $grid.jqGrid('getGridParam', 'rownumbers') && !$grid[0].p.colModel[0].hidden, searchWindow: searchParams, editWindow: editParams, permutation: perm, selectedRows: idsOfSelectedRows, colStates: {} }, colStates = columnsState.colStates; if (typeof (postData.filters) !== 'undefined') { columnsState.filters = postData.filters; } for (i = 0; i < l; i++) { colItem = colModel[i]; cmName = colItem.name; if (cmName !== 'rn' && cmName !== 'cb' && cmName !== 'subgrid') { colStates[cmName] = { width: colItem.width, hidden: colItem.hidden }; } } saveObjectInLocalStorage(myColumnStateName, columnsState); }; var saveObjectInLocalStorage = function (storageItemName, object) { if (typeof window.localStorage !== 'undefined') { window.localStorage.setItem(storageItemName, JSON.stringify(object)); } }; 

首先我想提一下在旧的答案中描述的代码并不总是正确的。 为了解释这个问题,您可以打开单行select演示 ,例如在重新加载网格之前多次使用列select器。 例如,您可以先打开列select器,然后在“税”列后更改“客户”列的位置。 您将在网格中看到正确的结果。 然后,您可以再次打开列select器,并在“客户”列之后移动“date”列。 您将按顺序“金额”,“税”,“客户”,“date”,…现在您可以重新加载页面。 您将看到重新加载的页面的列顺序错误:“客户端”,“金额”,“税收”,“date”,…问题的原因:由列select器或remapColumns使用的remapColumns使用整数位置列相对于当前的列顺序 。 这使得保存列顺序更复杂。 一个必须保持原始列顺序,并重新计算总是从permutation数组的值重新sorting原始 colModel

或者,可以保存列名称而不是相对于原始列模型的列位置更改的数组。 换句话说,应该把columnsState permutation属性columnsState成类似cmOrder东西,在上面select用户的同时在网格中input列名。

remapColumnsByName方法非常简单。 它像remapColumns方法remapColumns ,但其第一个参数是列名称数组,而不是整数索引数组。

演示是快速和肮脏的单行select演示更改使用cmOrder属性而不是列状态中的permutation属性和另外使用方法remapColumnsByName 。 如果你像我在回答开始时描述的那样重复相同的testing,你会看到新的演示没有我之前描述的错误。

演示中最重要的部分与原始演示不同,您将在下面find:

 var getColumnNamesFromColModel = function () { var colModel = this.jqGrid("getGridParam", "colModel"); return $.map(colModel, function (cm, iCol) { // we remove "rn", "cb", "subgrid" columns to hold the column information // independent from other jqGrid parameters return $.inArray(cm.name, ["rn", "cb", "subgrid"]) >= 0 ? null : cm.name; }); }, saveColumnState = function () { var p = this.jqGrid("getGridParam"), colModel = p.colModel, i, l = colModel.length, colItem, cmName, postData = p.postData, columnsState = { search: p.search, page: p.page, rowNum: p.rowNum, sortname: p.sortname, sortorder: p.sortorder, cmOrder: getColumnNamesFromColModel.call(this), selectedRows: idsOfSelectedRows, colStates: {} }, colStates = columnsState.colStates; if (postData.filters !== undefined) { columnsState.filters = postData.filters; } for (i = 0; i < l; i++) { colItem = colModel[i]; cmName = colItem.name; if (cmName !== "rn" && cmName !== "cb" && cmName !== "subgrid") { colStates[cmName] = { width: colItem.width, hidden: colItem.hidden }; } } saveObjectInLocalStorage(myColumnStateName(this), columnsState); }, ... 

此外,还原列的顺序的loadCompletecallback如下

 loadComplete: function () { var $this = $(this), p = $this.jqGrid("getGridParam"), i, count; if (firstLoad) { firstLoad = false; if (isColState && myColumnsState.cmOrder != null && myColumnsState.cmOrder.length > 0) { // We compares the values from myColumnsState.cmOrder array // with the current names of colModel and remove wrong names. It could be // required if the column model are changed and the values from the saved stated // not corresponds to the var fixedOrder = $.map(myColumnsState.cmOrder, function (name) { return p.iColByName[name] === undefined ? null : name; }); $this.jqGrid("remapColumnsByName", fixedOrder, true); } if (typeof (this.ftoolbar) !== "boolean" || !this.ftoolbar) { // create toolbar if needed $this.jqGrid("filterToolbar", {stringResult: true, searchOnEnter: true, defaultSearch: myDefaultSearch}); } } refreshSerchingToolbar($this, myDefaultSearch); for (i = 0, count = idsOfSelectedRows.length; i < count; i++) { $this.jqGrid("setSelection", idsOfSelectedRows[i], false); } saveColumnState.call($this, this.p.remapColumns); }, 

我想重申,新演示代码远远不够完美。 我只是使用旧的代码,并修复它使其在免费的jqGrid和使用新的remapColumnsByName方法工作。