Persistenti preferenze della colonna jqGrid

Ho alcuni jqGrids sulla mia applicazione ASP.NET MVC 3 con un numero di colonne. Ho aggiunto quanto segue alle definizioni delle colonne per rendere predefinite alcune colonne da hide:

colModel: [ { name: 'IceCreamID', hidden: true}, { name: 'RecipeID', hidden: true } 

e questo funziona bene. Quelle colonne non sono visibili sulla mia griglia.

Quindi ho aggiunto questo per implementare il selettore di colonne:

 var grid = $('#icecreamGrid'); grid.jqGrid('navButtonAdd', '#icecreamPager', { caption: "Columns", buttonicon: "ui-icon-calculator", title: "Choose Columns", onClickButton: function() { grid.jqGrid('columnChooser'); } }); 

Fantastico, richiama il selettore colonne ora. Ho quindi aggiunto quanto segue alle colonne che non avrei mai voluto mostrare nel selettore colonne:

 colModel: [ { name: 'IceCreamID', hidden: true, hidedlg: true}, 

Quindi ora posso hide / mostrare le colonne bene. Ora, come faresti a mantenere queste informazioni? DB? Come un biscotto? Altro modo? Esiste un modo preferito per memorizzare questo tipo di informazioni che è in realtà una preferenza utente piuttosto che qualcosa correlato ai dati stessi?


Ulteriori informazioni

Sulla base del commento di Oleg di seguito, voglio fornire un po ‘più di informazioni.

Il punto qui è che ho griglie con 10-15 colonne che potrebbero essere visualizzate in base alle preferenze dell’utente. Per un semplice esempio, una delle mie griglia ha le seguenti 9 colonne:

 IceCream|ShortName|HasNuts|SugarAdded|LimitedRun|PromoItem|Facility|FirstRun|LastRun 

Gli utenti possono hide / mostrare una di queste 9 colonne in base alle loro preferenze personali.

Quello che voglio fare è fornire un modo per mantenere le colonne che un particolare utente vuole vedere in modo che non debba ri-scegliere quelle colonne per visualizzarle ogni volta che viene mostrata la pagina con quella griglia.

Ti ho trovato una domanda molto interessante. La domanda sul salvataggio dello stato utente della griglia è interessante in molti casi. Ci sono alcune risposte interessanti su questi problemi che usano i cookie (vedi qui per esempio).

A mio avviso, il salvataggio dello stato della griglia nel database sul server o nel localStorage è un modo migliore come l’utilizzo dei cookie. Il modo migliore dipende dai requisiti del progetto in cui lo si utilizza. Ad esempio, l’utilizzo della memoria del database sul server consente di implementare lo stato di roaming della griglia. Se si utilizza il localStorage invece dei cookie, le preferenze dell’utente andranno perse se l’utente accede a un altro computer o solo se l’utente utilizzerà un altro browser Web sullo stesso computer.

Un altro problema con lo stato della griglia è la manutenzione. Le informazioni sulle colonne della griglia in genere contenute nei file JavaScript o HTML e non nel database. Nel caso in cui entrambe le fonti non possano essere sincrone sui cambiamenti nella griglia. Diversi scenari del problema di aggiornamento potresti facilmente immaginare. Tuttavia, i vantaggi delle preferenze dell’utente sono così ampi in alcuni scenari che i problemi con piccoli svantaggi non sono così importanti e possono essere risolti relativamente facilmente.

Quindi passerò un po ‘di tempo per implementare due demo che mostrano come può essere implementato. Ho usato localStorage nei miei demo per molte ragioni. Ne cito solo due da lì:

  1. I cookie sono il modo in cui inviano informazioni permanentemente diverse al o dal server che non è realmente richiesto. Aumenta la dimensione dell’intestazione HTTP e diminuisce le prestazioni del sito web (vedi qui per esempio).
  2. I cookie hanno restrizioni molto difficili. Corrisponde alla sezione 6.3 di rfc2109 o 6.1 di rfc6265: almeno 4096 byte per cookie, almeno 50 cookie per dominio (20 in rfc2109), almeno 3000 cookie totali (300 in rfc2109). Quindi i cookie non si possono usare per salvare troppe informazioni. Ad esempio, se si salva lo stato di ogni griglia di ogni pagina Web, è ansible raggiungere rapidamente i limiti.

D’altra parte localStorage sono supportati da tutti i browser moderni e saranno supportati in Internet Explorer a partire da IE8 (vedi qui ). Il localStorage verrà automaticamente salvato per origini (come a1.example.com, a2.example.com, a3.example.com, ecc.) E ha un limite arbitrario di 5 MB per origine (vedi qui ). Quindi se usi lo spazio con cura, sarai lontano dai limiti.

Quindi ho usato nelle mie demo il localStorage . Dovrei inoltre ricordare che ci sono alcuni plugin come jStorage che usano localStorage se sono supportati dal browser e usano un’altra memoria, ma la stessa interfaccia per te in caso di browser vecchi come IE6 / IE7. Nel caso in cui tu abbia solo meno spazio di archiviazione: 128 kB invece di 5 MB, ma è meglio come 4K che si ha per i cookie (vedi qui ).

Ora sull’implementazione. Creo due demo: questa ed è la versione estesa: questa .

Nella prima demo i seguenti stati di griglia verranno salvati e ripristinati automaticamente nella pagina di ricarica ( F5 nella maggior parte dei browser Web):

  • quale colonna è nascosta
  • l’ordine delle colonne
  • la larghezza di ogni colonna
  • il nome della colonna in base alla quale verrà ordinata la griglia e la direzione di ordinamento
  • il numero della pagina corrente
  • il filtro corrente della griglia e il flag se il filtro è applicato. Ho usato multipleSearch: true setting nella griglia.

Allo stesso modo si può estendere (o ridurre) l’elenco di opzioni che fanno parte dello stato della griglia salvato.

Le parti più importanti del codice dalla demo che troverai di seguito:

 var $grid = $("#list"), 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 $.parseJSON(window.localStorage.getItem(storageItemName)); } }, myColumnStateName = 'ColumnChooserAndLocalStorage.colState', 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, 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; }, firstLoad = true; myColumnsState = restoreColumnState(cm); isColState = typeof (myColumnsState) !== 'undefined' && myColumnsState !== null; $grid.jqGrid({ // ... other 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', loadComplete: function () { if (firstLoad) { firstLoad = false; if (isColState) { $(this).jqGrid("remapColumns", myColumnsState.permutation, true); } } saveColumnState.call($(this), this.p.remapColumns); } }); $grid.jqGrid('navButtonAdd', '#pager', { caption: "", buttonicon: "ui-icon-calculator", title: "choose columns", onClickButton: function () { $(this).jqGrid('columnChooser', { done: function (perm) { if (perm) { this.jqGrid("remapColumns", perm, true); saveColumnState.call(this, perm); } } }); } }); $grid.jqGrid('navButtonAdd', '#pager', { caption: "", buttonicon: "ui-icon-closethick", title: "clear saved grid's settings", onClickButton: function () { removeObjectFromLocalStorage(myColumnStateName); } }); 

myColumnStateName attentamente definire myColumnStateName (il valore `'ColumnChooserAndLocalStorage.colState'``) nella demo) su valori diversi nelle diverse pagine.

La seconda demo è l'estensione della prima utilizzando la tecnica dalla mia vecchia risposta alla tua altra domanda. La demo utilizza la barra degli strumenti di ricerca e sincronizza le informazioni aggiuntive tra il modulo di ricerca avanzato e la barra degli strumenti di ricerca.

AGGIORNATO : la prossima risposta contiene la versione estesa del codice incluso sopra. Mostra come mantenere ulteriormente le righe (o le righe) selezionate. Un'altra risposta mostra come mantenere l'elenco dei nodes espansi della griglia ad albero ed espandere i nodes sulla nuova pagina della pagina.