Как заменить remapColums с remapColumnsByName в бесплатной jqgrid
Код из ответа о том, как сохранить текущую строку в jqgrid
используется для сохранения состояния jqgrid. Сохраняет состояние столбца jqgrid, используя номера столбцов. Если jqgrid colmodel изменяется на сервере, это вызывает ошибку javascript в браузере.
Замените столбец rownum в комментарии JQGrid и 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));
}
};
1 ответ
Прежде всего хочу отметить, что код, описанный в старом ответе, работает не всегда корректно. Чтобы объяснить проблему, вы можете, например, открыть демонстрационную программу выбора одной строки и несколько раз использовать средство выбора столбцов перед перезагрузкой сетки. Например, вы можете сначала открыть окно выбора столбцов и изменить положение столбца "Клиенты" после столбца "Налог". Вы увидите правильные результаты в сетке. Затем вы можете еще раз открыть окно выбора столбцов и переместить столбец "Дата" после столбца "Клиенты", например. Вы увидите столбцы в порядке "Сумма", "Налог", "Клиент", "Дата",... Теперь вы можете перезагрузить страницу. Вы увидите, что загруженная страница имеет неправильный порядок столбцов: "Клиент", "Сумма", "Налог", "Дата",... Причина проблемы: permutation
используется выбором столбца или remapColumns
использует целочисленное положение столбцов относительно текущего порядка столбцов. Это делает сохранение порядка столбцов более сложным. Нужно сохранить оригинальный порядок столбцов и всегда пересчитывать значения из permutation
массив для переупорядочения оригинала colModel
,
В качестве альтернативы можно сохранить имена столбцов вместо массивов с измененным положением столбца относительно исходной модели столбца. Другими словами нужно заменить permutation
собственностью columnsState
что-то вроде cmOrder
с массивом имен столбцов в сетке, которые выбирал пользователь в прошлый раз.
Метод remapColumnsByName
очень просто Работает как метод remapColumns
, но его первым параметром является массив имен столбцов, а не массив целочисленных индексов.
Демонстрация - это быстрое и грязное изменение демонстрации выбора одной строки для использования. 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
метод.