用于保存jqgrid状态。它使用列号保存jqgrid列状态。如果在服务器中更改了jqgrid colmodel,这将导致浏览器中的javascript错误。
免费的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)); } };
首先,我想提一下,旧答案中描述的代码并不总是正确的。为了解释该问题,您可以打开单行选择示例,并在重新加载网格之前 多次 使用列选择器。例如,您可以先打开列选择器,然后在“税”列之后更改“客户”列的位置。您将在网格中看到正确的结果。然后,您可以再次打开列选择器,然后将“日期”列移到“客户”列之后。您将按“金额”,“税收”,“客户”,“日期”,……的顺序查看各列。现在,您可以重新加载页面。您会看到重新加载的页面具有错误的列顺序:“客户”,“金额”,“税收”,“permutation``remapColumns 列相对于当前列顺序的整数位置 。这使保存列顺序更加复杂。一要保持 原来的 列顺序并重新计算总是从数值permutation数组的重新排序 原 colModel。
permutation``remapColumns
permutation
colModel
或者,可以保存列名,而不是保存相对于原始列模型而言具有更改的列位置的数组。换句话说应该更换permutation的财产columnsState喜欢的东西cmOrder与网格中,其选用了用户最后一次列名的数组。
columnsState
cmOrder
该方法remapColumnsByName非常简单。它的工作原理与方法相同remapColumns,但其第一个参数是列名数组,而不是整数索引数组。
remapColumnsByName
remapColumns
是对单行选择演示的快速而肮脏的更改,以使用cmOrderproperty代替permutationproperty columnsState并remapColumnsByName另外使用方法。如果您重复我在回答开始时描述的相同测试,您将看到新的演示版没有我之前描述的错误。
该演示最重要的部分与原始演示不同,您将在下面找到:
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); }, ...
此外loadComplete,恢复列顺序的回调如下
loadComplete
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方法工作。