Persisting the Angular Data Grid State
A common requirement for web apps is to save the user customization and settings when interacting with your app, and then restore them once the user comes back at some point in the future. The Kendo UI for Angular Grid exposes the capability to save and restore settings that were previously applied
To persist the Grid state you must store the following Grid information in a single object:
State
—Includes the appliedfilter
,sort
,group
,skip
, andtake
properties.data
—The bound collection.columns
—All declared columns in the Grid.
The following example demonstrates how to persist the Grid state.
Setup
To persist the state of the Grid:
-
Create a custom
GridSettings
object that stores the current state of the Grid, the data, and the column configuration objects.tspublic gridSettings: GridSettings = { state: { skip: 0, take: 5, filter: { logic: 'and', filters: [] }, group: [], }, gridData: process(sampleProducts, { skip: 0, take: 5, filter: { logic: 'and', filters: [] }, group: [], }), columnsConfig: [ { field: 'ProductID', title: 'ID', filterable: false, width: 60 }, { field: 'ProductName', title: 'Product Name', filterable: true, width: 300 }, ... ] };
-
Use the
GridSettings
object and assign the corresponding properties in Grid.html<kendo-grid #grid [data]="gridSettings.gridData" [pageSize]="gridSettings.state.take" [skip]="gridSettings.state.skip" [sort]="gridSettings.state.sort" [filter]="gridSettings.state.filter" [group]="gridSettings.state.group" ... > <kendo-grid-column *ngFor="let col of gridSettings.columnsConfig" [field]="col.field" [title]="col.title" [width]="col.width" ... ></kendo-grid-column> </kendo-grid>
-
Handle the
dataStateChange
event of the Grid and update theGridSettings
object.tspublic dataStateChange(state: State): void { this.gridSettings.state = state; this.gridSettings.gridData = process(sampleProducts, state); }
-
Use a custom button to save the
GridSettings
object.html<button kendoButton (click)="saveGridSettings(grid)">Save current state</button>
tspublic saveGridSettings(grid: GridComponent): void { const columns = grid.columns; //add only the required column properties to save local storage space const gridConfig = { state: this.gridSettings.state, columnsConfig: columns.toArray().map((item) => { return <ColumnSettings>{ field: item['field'], width: item['width'], title: item['title'], filter: item['filter'], format: item['format'], filterable: item['filterable'], orderIndex: item['orderIndex'] }; }) }; this.persistingService.set('gridSettings', gridConfig); }
-
Load the previously stored settings (if any) and map them to update the Grid.
html<button kendoButton *ngIf="savedStateExists" (click)="grid1Settings = mapGridSettings(persistingService.get('gridSettings'))">Load saved state</button>
tspublic mapGridSettings(gridSettings: GridSettings): GridSettings { const state = gridSettings.state; return { state, columnsConfig: gridSettings.columnsConfig.sort((a, b) => a.orderIndex - b.orderIndex), gridData: process(sampleProducts, state) }; }
-
Create a service to store the saved
GridSettings
object in the browser local storage and retrieve it when needed.tsconst getCircularReplacer = () => { const seen = new WeakSet(); return (key, value) => { if (typeof value === "object" && value !== null) { if (seen.has(value)) { return; } seen.add(value); } return value; }; }; @Injectable() export class StatePersistingService { public get<T>(token: string): T { const settings = localStorage.getItem(token); return settings ? JSON.parse(settings) : settings; } public set<T>(token: string, gridConfig: GridSettings): void { localStorage.setItem(token, JSON.stringify(gridConfig, getCircularReplacer())); } }