如何在免费的 jqgrid 中用 remapColumnsByName 替换 remapColums
How to replace remapColums with remapColumnsByName in free jqgrid
代码来自 how to persist current row in jqgrid
中的答案
用于保存jqgrid状态。它使用列号保存 jqgrid 列状态。如果在服务器中更改了 jqgrid colmodel,这会导致浏览器出现 javascript 错误。
comment and https://github.com/free-jqgrid/jqGrid/blob/master/README49.md 描述方法 remapColumnsByName
。我希望使用它可以解决问题。
免费的 jqgrid 是从今天 git 大师那里下载的。
在调整列大小或移动行后的状态保存
saveColumnState.call($grid, $grid[0].p.remapColumns);
已更改为
saveColumnState.call($grid, $grid[0].p.remapColumnsByName);
并在状态恢复中加载完成代码
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));
}
};
首先我想提一下,旧答案中描述的代码并不总是正确的。为了解释这个问题,您可以打开 the single row select demo 并在重新加载网格之前多次使用列选择器 。例如,您可以先打开列选择器,然后在 "Tax" 列之后更改 "Clients" 列的位置。您将在网格中看到正确的结果。然后您可以再次打开列选择器并将 "Date" 列移动到 "Clients" 列之后。您将看到顺序为 "Amount"、"Tax"、"Client"、"Date" 的列...现在您可以重新加载页面。您会看到重新加载的页面有错误的列顺序:"Client"、"Amount"、"Tax"、"Date"、...问题的原因:permutation
由列选择器或 remapColumns
使用 列相对于当前列顺序 的整数位置。它使列顺序的保存更加复杂。必须保持 original 列顺序并始终重新计算 permutation
数组中的值以重新排序 original colModel
.
或者,可以保存 列名称 而不是相对于原始列模型更改了列位置的数组。换句话说,应该将 columnsState
的 permutation
属性 替换为类似 cmOrder
的内容,其中包含上次选择用户的网格中的列名数组。
方法remapColumnsByName
很简单。它的工作原理类似于方法 remapColumns
,但它的第一个参数是列名数组而不是整数索引数组。
The demo 是对单行 select 演示的快速更改,使用 cmOrder
属性 而不是 permutation
属性 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: 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
方法。
代码来自 how to persist current row in jqgrid
中的答案用于保存jqgrid状态。它使用列号保存 jqgrid 列状态。如果在服务器中更改了 jqgrid colmodel,这会导致浏览器出现 javascript 错误。
remapColumnsByName
。我希望使用它可以解决问题。
免费的 jqgrid 是从今天 git 大师那里下载的。 在调整列大小或移动行后的状态保存
saveColumnState.call($grid, $grid[0].p.remapColumns);
已更改为
saveColumnState.call($grid, $grid[0].p.remapColumnsByName);
并在状态恢复中加载完成代码
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));
}
};
首先我想提一下,旧答案中描述的代码并不总是正确的。为了解释这个问题,您可以打开 the single row select demo 并在重新加载网格之前多次使用列选择器 。例如,您可以先打开列选择器,然后在 "Tax" 列之后更改 "Clients" 列的位置。您将在网格中看到正确的结果。然后您可以再次打开列选择器并将 "Date" 列移动到 "Clients" 列之后。您将看到顺序为 "Amount"、"Tax"、"Client"、"Date" 的列...现在您可以重新加载页面。您会看到重新加载的页面有错误的列顺序:"Client"、"Amount"、"Tax"、"Date"、...问题的原因:permutation
由列选择器或 remapColumns
使用 列相对于当前列顺序 的整数位置。它使列顺序的保存更加复杂。必须保持 original 列顺序并始终重新计算 permutation
数组中的值以重新排序 original colModel
.
或者,可以保存 列名称 而不是相对于原始列模型更改了列位置的数组。换句话说,应该将 columnsState
的 permutation
属性 替换为类似 cmOrder
的内容,其中包含上次选择用户的网格中的列名数组。
方法remapColumnsByName
很简单。它的工作原理类似于方法 remapColumns
,但它的第一个参数是列名数组而不是整数索引数组。
The demo 是对单行 select 演示的快速更改,使用 cmOrder
属性 而不是 permutation
属性 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: 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
方法。