cómo persistir la fila actual en jqgrid

¿Cómo presistir la fila actual si la red se abre de nuevo o la página se actualiza?

La respuesta en persistencia de las preferencias de la columna jqGrid describe cómo mantener el ancho de la columna y algunos otros parámetros.

En esta demostración demo, hice clic en alguna fila y presioné F5. La fila anterior clicada no fue resaltada. ¿Cómo guardar / restaurar la fila actual en el almacenamiento local?

Actualizar

Si la estructura de la columna jqGrid se modifica en la aplicación y el usuario abre la aplicación desde el navegador nuevamente, restrecolumnstate crea un colmodel no válido donde faltan algunos elementos. Esto causa una excepción en refreshSearchingToolbar que asume que todos los elementos de colmodel están presentes.

Cómo arreglar esto ? ¿Cómo dedeccionar colmodol modificado y no restaurar colmodel en este caso? ¿O debería restaurarColumnState update colModel para que se cree la matriz adecuada?

** Actualización 2 **

Si myColumnsState.permutation contiene null $grid.jqGrid("remapColumns", myColumnsState.permutation, true) creó un colmodel no válido. Aquí hay capturas de pantalla del depurador VS inmediatamente antes y después de la llamada remapColumns

enter image description here

después:

después

Lo arreglé cambiando el código a

  if (isColState && myColumnsState.permutation.length > 0) { var i, isnull = false; for (i = 0; i < myColumnsState.permutation.length; i = i + 1) { if (myColumnsState.permutation[i] == null) { isnull = true; break; } } if (!isnull) { $grid.jqGrid("remapColumns", myColumnsState.permutation, true); } 

¿Es esta la mejor solución?

Combiné el código de la respuesta anterior sobre las persistentes preferencias de la columna jqGrid con el código de otra respuesta donde sugerí el código que implementó la selección persistente de filas. Es importante mencionar que, en el caso de multiselect:true , se usará la matriz de identificadores de las filas seleccionadas que contiene todos los seleccionados, incluso si las filas están en otra página . Es muy práctico y la implementación muy simple. Así que publiqué la solicitud de función correspondiente, pero permanece hasta ahora sin respuesta.

Ahora puedo presentar dos demos: la primera demostración que usa multiselect: true y la segunda demo, que usa el mismo código, pero con la única selección.

Las partes más importantes del código que usé se encontrarán a continuación.

Una cosa es muy importante mencionar: debe modificar el valor de myColumnStateName en cada página que use . El valor de la variable contiene el nombre del estado de la columna en localStorage . Por lo tanto, si no cambia el nombre, compartirá el estado de diferentes tablas, lo que puede dar lugar a efectos muy extraños. Puede considerar usar nombres construidos a partir del nombre de la página actual o su URL como el valor de myColumnStateName .

 var $grid = $("#list"), getColumnIndex = function (grid, columnIndex) { var cm = grid.jqGrid('getGridParam', 'colModel'), i, l = cm.length; for (i = 0; i < l; i++) { if ((cm[i].index || cm[i].name) === columnIndex) { return i; // return the colModel index } } return -1; }, refreshSerchingToolbar = function ($grid, myDefaultSearch) { var postData = $grid.jqGrid('getGridParam', 'postData'), filters, i, l, rules, rule, iCol, cm = $grid.jqGrid('getGridParam', 'colModel'), cmi, control, tagName; for (i = 0, l = cm.length; i < l; i++) { control = $("#gs_" + $.jgrid.jqID(cm[i].name)); if (control.length > 0) { tagName = control[0].tagName.toUpperCase(); if (tagName === "SELECT") { // && cmi.stype === "select" control.find("option[value='']") .attr('selected', 'selected'); } else if (tagName === "INPUT") { control.val(''); } } } if (typeof (postData.filters) === "string" && typeof ($grid[0].ftoolbar) === "boolean" && $grid[0].ftoolbar) { filters = $.parseJSON(postData.filters); if (filters && filters.groupOp === "AND" && typeof (filters.groups) === "undefined") { // only in case of advance searching without grouping we import filters in the // searching toolbar rules = filters.rules; for (i = 0, l = rules.length; i < l; i++) { rule = rules[i]; iCol = getColumnIndex($grid, rule.field); if (iCol >= 0) { cmi = cm[iCol]; control = $("#gs_" + $.jgrid.jqID(cmi.name)); if (control.length > 0 && (((typeof (cmi.searchoptions) === "undefined" || typeof (cmi.searchoptions.sopt) === "undefined") && rule.op === myDefaultSearch) || (typeof (cmi.searchoptions) === "object" && $.isArray(cmi.searchoptions.sopt) && cmi.searchoptions.sopt.length > 0 && cmi.searchoptions.sopt[0] === rule.op))) { tagName = control[0].tagName.toUpperCase(); if (tagName === "SELECT") { // && cmi.stype === "select" control.find("option[value='" + $.jgrid.jqID(rule.data) + "']") .attr('selected', 'selected'); } else if (tagName === "INPUT") { control.val(rule.data); } } } } } } }, saveObjectInLocalStorage = function (storageItemName, object) { if (typeof window.localStorage !== 'undefined') { window.localStorage.setItem(storageItemName, JSON.stringify(object)); } }, removeObjectFromLocalStorage = function (storageItemName) { if (typeof window.localStorage !== 'undefined') { window.localStorage.removeItem(storageItemName); } }, getObjectFromLocalStorage = function (storageItemName) { if (typeof window.localStorage !== 'undefined') { return JSON.parse(window.localStorage.getItem(storageItemName)); } }, myColumnStateName = 'ColumnChooserAndLocalStorage2.colState', idsOfSelectedRows = [], 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'), sortname: this.jqGrid('getGridParam', 'sortname'), sortorder: this.jqGrid('getGridParam', 'sortorder'), 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); }, myColumnsState, isColState, restoreColumnState = function (colModel) { var colItem, i, l = colModel.length, colStates, cmName, columnsState = getObjectFromLocalStorage(myColumnStateName); if (columnsState) { colStates = columnsState.colStates; for (i = 0; i < l; i++) { colItem = colModel[i]; cmName = colItem.name; if (cmName !== 'rn' && cmName !== 'cb' && cmName !== 'subgrid') { colModel[i] = $.extend(true, {}, colModel[i], colStates[cmName]); } } } return columnsState; }, updateIdsOfSelectedRows = function (id, isSelected) { var index = idsOfSelectedRows.indexOf(id); if (!isSelected && index >= 0) { idsOfSelectedRows.splice(index, 1); // remove id from the list } else if (index < 0) { idsOfSelectedRows.push(id); } }, firstLoad = true; myColumnsState = restoreColumnState(cm); isColState = typeof (myColumnsState) !== 'undefined' && myColumnsState !== null; idsOfSelectedRows = isColState && typeof (myColumnsState.selectedRows) !== "undefined" ? myColumnsState.selectedRows : []; $grid.jqGrid({ // ... some options page: isColState ? myColumnsState.page : 1, search: isColState ? myColumnsState.search : false, postData: isColState ? { filters: myColumnsState.filters } : {}, sortname: isColState ? myColumnsState.sortname : 'invdate', sortorder: isColState ? myColumnsState.sortorder : 'desc', onSelectRow: function (id, isSelected) { updateIdsOfSelectedRows(id, isSelected); saveColumnState.call($grid, $grid[0].p.remapColumns); }, onSelectAll: function (aRowids, isSelected) { var i, count, id; for (i = 0, count = aRowids.length; i < count; i++) { id = aRowids[i]; updateIdsOfSelectedRows(id, isSelected); } saveColumnState.call($grid, $grid[0].p.remapColumns); }, loadComplete: function () { var $this = $(this), i, count; if (firstLoad) { firstLoad = false; if (isColState) { $this.jqGrid("remapColumns", myColumnsState.permutation, 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); }, resizeStop: function () { saveColumnState.call($grid, $grid[0].p.remapColumns); } }); $grid.jqGrid('navGrid', '#pager', {edit: false, add: false, del: false}); $grid.jqGrid('navButtonAdd', '#pager', { caption: "", buttonicon: "ui-icon-closethick", title: "clear saved grid's settings", onClickButton: function () { removeObjectFromLocalStorage(myColumnStateName); window.location.reload(); } }); 

ACTUALIZADO : olvidé mencionar que en caso de uso de selección multiselect: true opción multiselect: true con jqGrid 4.3 es muy importante utilizar la solución que se describe aquí. En la primera demostración utilicé la versión modificada de jquery.jqGrid.src.js que incluye la corrección de errores.

ACTUALIZADO 2 : Para facilitar la generación de un nombre único del elemento de almacenamiento local utilizado para guardar el estado de la cuadrícula, modifiqué un poco las demostraciones. La próxima versión de la demostración de selección myColumnStateName y la demostración de selección única usan myColumnStateName como la función definida como la siguiente

 var myColumnStateName = function (grid) { return window.location.pathname + '#' + grid[0].id; } 

El uso de myColumnStateName se cambia de forma correspondiente. Además extendí el estado de la columna para guardar el valor rowNum .

ACTUALIZADO 3: La respuesta describe cómo se puede usar la nueva posibilidad de jqGrid libre para guardar el estado de la grilla.

La solución de Oleg genera un error cuando actualiza la página como se muestra a continuación.

Error: TypeError no detectado: no se puede leer la propiedad ‘el’ de undefined

Línea: 1936 en jquery.jqGrid.src.js

 var previousSelectedTh = ts.grid.headers[ts.p.lastsort].el, newSelectedTh = ts.grid.headers[idxcol].el; 

La solución a esto es guardar el parámetro de grilla lastsort y restablecerlo cuando la carga se complete como se muestra a continuación.

 saveColumnState = function(perm) { ... columnsState = { search: this.jqGrid('getGridParam', 'search'), page: this.jqGrid('getGridParam', 'page'), sortname: this.jqGrid('getGridParam', 'sortname'), sortorder: this.jqGrid('getGridParam', 'sortorder'), lastsort: this.jqGrid('getGridParam', 'lastsort'), permutation: perm, colStates: { } }, ... }, loadComplete: function(data) { ... if (isColState) { $this.jqGrid("remapColumns", myColumnsState.permutation, true); if(myColumnsState.lastsort > -1) $this.jqGrid("setGridParam", { lastsort: myColumnsState.lastsort }); } ... },