Código de respuesta en cómo mantener la fila actual en jqgrid
se usa para guardar el estado jqgrid. Guarda el estado de la columna jqgrid usando números de columna. Si jqgrid colmodel se cambia en el servidor, esto causa un error de javascript en el navegador.
La columna Freeze rownum en el comentario de JQGrid y https://github.com/free-jqgrid/jqGrid/blob/master/README49.md describe el método remapColumnsByName
. Esperé que usar esto arreglara el problema.
se descargó jqgrid gratis del maestro de git de hoy. En estado guardar después de las columnas se cambió de tamaño o se movió la línea
saveColumnState.call($grid, $grid[0].p.remapColumns);
fue cambiado a
saveColumnState.call($grid, $grid[0].p.remapColumnsByName);
y en restablecimiento de estado en el código loadComplete
if (isColState && myColumnsState.permutation.length > 0 && myColumnsState.permutation.length === cm.length) { $grid.jqGrid("remapColumns", myColumnsState.permutation, true); }
con
if (isColState && myColumnsState.permutation.length > 0 && myColumnsState.permutation.length === cm.length) { $grid.jqGrid("remapColumnsByName", myColumnsState.permutation, true); }
Ahora línea
if (isColState && myColumnsState.permutation.length > 0 &&
causa un error
Uncaught TypeError: Cannot read property 'length' of undefined
¿Cómo arreglar esto para que el estado de la columna pueda usarse si se cambia la definición de la columna?
Los métodos se definen como
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)); } };
En primer lugar, quiero mencionar que el código descrito en la respuesta anterior no siempre es correcto. Para explicar el problema, puede abrir la demostración de selección de una sola fila, por ejemplo, y utilizar el selector de columnas varias veces antes de volver a cargar la cuadrícula. Por ejemplo, puede abrir el selector de columnas primero y cambiar la posición de la columna “Clientes” después de la columna “Impuestos”. Verá los resultados correctos en la grilla. Luego puede abrir el selector de columnas una vez más y mover la columna “Fecha” después de la columna “Clientes”, por ejemplo. Verá las columnas en el orden “Importe”, “Impuesto”, “Cliente”, “Fecha”, … Ahora puede volver a cargar la página. Verá que la página recargada tiene un orden incorrecto de columnas: “Cliente”, “Importe”, “Impuesto”, “Fecha”, … El motivo del problema: la permutation
utilizada por el selector de columna o por remapColumns
usa la posición entera de columnas con respecto al orden actual de las columnas . Hace que el ahorro del orden de las columnas sea más complejo. Uno debe mantener el orden original de las columnas y volver a calcular siempre los valores de la matriz de permutation
a la reordenación de colModel
original .
Alternativamente, uno puede guardar los nombres de las columnas en lugar de las matrices con la posición de la columna modificada en relación con el modelo de la columna original. En otras palabras, uno debería reemplazar la propiedad de permutation
de columnsState
por algo como cmOrder
con una matriz de nombres de columnas en la grilla, que eligió al usuario la última vez.
El método remapColumnsByName
es muy simple. Funciona como el método remapColumns
, pero su primer parámetro es una matriz de nombres de columna en lugar de una matriz de índices enteros.
La demostración es un cambio rápido y sucio de la demo de selección de una sola fila para usar la propiedad cmOrder
lugar de la propiedad de permutation
en columnsState
y para usar el método remapColumnsByName
adicionalmente. Si repite la misma prueba como describí al principio de mi respuesta, verá que la nueva demostración no tiene el error que describí antes.
Las partes más importantes de la demo que es diferente de la demo original se encuentran a continuación:
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); }, ...
además, la callback loadComplete
que restablece el orden de las columnas es la siguiente
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); },
Quiero repetir que el código de la nueva demo está lejos de ser perfecto. Acabo de utilizar el código anterior y lo arreglé para hacerlo funcionar en jqGrid libre y usando el nuevo método remapColumnsByName
.