Example T1047398
Visible to All Users

DevExtreme DataGrid - How to modify the persisted state

This example shows how to exclude component settings that you don't need restored after the page is reloaded.

In this example, you can reorder grid columns, sort and group data, and perform other modifications in the UI. After you reload the page, all modifications will persist, except filters applied to grid columns.

DataGrid with modified persisted state

You can use the demonstrated approach with the following UI components:

Implementation Steps

  1. Switch state storing into manual mode
    Set stateStoring.type to "custom" .
  2. Implement the customSave and customLoad functions
    customSave should modify the state and save it to your storage; customLoad should load the state from the storage and return it to the UI component. In this example, customSave removes filters applied to grid columns.

Files to Review

Documentation

More Examples

Example Code

jQuery/src/index.js
JavaScript
$(function () { const storageKey = 'datagrid-state'; $('#gridContainer').dxDataGrid({ dataSource: orders, keyExpr: 'ID', columns: [{ dataField: 'OrderNumber', width: 130, caption: 'Invoice Number', }, { dataField: 'OrderDate', dataType: 'date', sortOrder: 'desc', }, { dataField: 'SaleAmount', alignment: 'right', format: 'currency', }, 'Employee', { caption: 'City', dataField: 'CustomerStoreCity', }, { caption: 'State', dataField: 'CustomerStoreState', groupIndex: 0, }], allowColumnReordering: true, allowColumnResizing: true, showBorders: true, selection: { mode: 'single', }, filterRow: { visible: true, }, groupPanel: { visible: true, }, pager: { showPageSizeSelector: true, allowedPageSizes: [5, 10, 20], }, stateStoring: { enabled: true, type: 'custom', storageKey: storageKey, customLoad() { return JSON.parse(localStorage.getItem(storageKey)); }, customSave(state) { if (state) { for (let i = 0; i < state.columns.length; i++) { state.columns[i].filterValue = null; } } localStorage.setItem(storageKey, JSON.stringify(state)); } } }); });
Angular/src/app/app.component.html
HTML
<div class="default-style"> <dx-data-grid [dataSource]="orders" [allowColumnResizing]="true" [allowColumnReordering]="true" [showBorders]="true" keyExpr="ID"> <dxi-column dataField="OrderNumber" [width]="130" caption="Invoice Number"> </dxi-column> <dxi-column dataField="OrderDate" sortOrder="desc" dataType="date"> </dxi-column> <dxi-column dataField="SaleAmount" alignment="right" format="currency"> </dxi-column> <dxi-column dataField="Employee"></dxi-column> <dxi-column dataField="CustomerStoreCity" caption="City"></dxi-column> <dxi-column dataField="CustomerStoreState" caption="State" [groupIndex]="0"> </dxi-column> <dxo-selection mode="single"></dxo-selection> <dxo-filter-row [visible]="true"></dxo-filter-row> <dxo-group-panel [visible]="true"></dxo-group-panel> <dxo-pager [showPageSizeSelector]="true" [allowedPageSizes]="[5, 10, 20]"> </dxo-pager> <dxo-state-storing [enabled]="true" type="custom" [storageKey]="storageKey" [customLoad]="loadState" [customSave]="saveState"> </dxo-state-storing> </dx-data-grid> </div>
Angular/src/app/app.component.ts
TypeScript
import { Component } from '@angular/core'; import { Order, Service } from './app.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], providers: [Service] }) export class AppComponent { orders: Order[]; storageKey: string = "datagrid-state"; constructor(private service: Service) { this.orders = service.getOrders(); } loadState() { return JSON.parse(localStorage.getItem(this.storageKey)); } saveState(state) { if (state) { for (let i = 0; i < state.columns.length; i++) { state.columns[i].filterValue = null; } } localStorage.setItem(this.storageKey, JSON.stringify(state)); } }
Vue/src/components/Home.vue
Code
<template> <DxDataGrid :data-source="orders" key-expr="ID" :allow-column-resizing="true" :allow-column-reordering="true" :show-borders="true"> <DxColumn :width="130" data-field="OrderNumber" caption="Invoice Number" /> <DxColumn data-field="OrderDate" sort-order="desc" data-type="date" /> <DxColumn data-field="SaleAmount" alignment="right" format="currency" /> <DxColumn data-field="Employee"/> <DxColumn data-field="CustomerStoreCity" caption="City" /> <DxColumn :group-index="0" data-field="CustomerStoreState" caption="State" /> <DxSelection mode="single" /> <DxFilterRow :visible="true" /> <DxGroupPanel :visible="true" /> <DxPager :show-page-size-selector="true" :allowed-page-sizes="[5, 10, 20]" /> <DxStateStoring :enabled="true" type="custom" :storage-key="storageKey" :custom-load="loadState" :custom-save="saveState" /> </DxDataGrid> </template> <script> import { DxDataGrid, DxColumn, DxSelection, DxFilterRow, DxGroupPanel, DxPager, DxStateStoring } from 'devextreme-vue/data-grid'; import { orders } from '../data'; export default { name: 'Home', components: { DxDataGrid, DxColumn, DxSelection, DxFilterRow, DxGroupPanel, DxPager, DxStateStoring }, data() { return { orders, storageKey: "datagrid-state" } }, methods: { loadState() { return JSON.parse(localStorage.getItem(this.storageKey)); }, saveState(state) { if (state) { for (let i = 0; i < state.columns.length; i++) { state.columns[i].filterValue = null; } } localStorage.setItem(this.storageKey, JSON.stringify(state)); } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>
React/src/App.js
JavaScript
import { useCallback } from 'react'; import 'devextreme/dist/css/dx.common.css'; import 'devextreme/dist/css/dx.material.blue.light.compact.css'; import './App.css'; import { DataGrid, Column, Selection, FilterRow, GroupPanel, Pager, StateStoring } from 'devextreme-react/data-grid'; import { orders } from './data'; const storageKey = "datagrid-state"; const allowedPageSizes = [5, 10, 20]; function App() { const loadState = useCallback(() => { return JSON.parse(localStorage.getItem(storageKey)); }, []); const saveState = useCallback((state) => { if (state) { for (let i = 0; i < state.columns.length; i++) { state.columns[i].filterValue = null; } } localStorage.setItem(storageKey, JSON.stringify(state)); }, []); return ( <div className="App"> <DataGrid dataSource={orders} keyExpr="ID" allowColumnResizing={true} allowColumnReordering={true} showBorders={true}> <Column dataField="OrderNumber" caption="Invoice Number" width={130} /> <Column dataField="OrderDate" sortOrder="desc" dataType="date" /> <Column dataField="SaleAmount" alignment="right" format="currency" /> <Column dataField="Employee" /> <Column dataField="CustomerStoreCity" caption="City" /> <Column dataField="CustomerStoreState" caption="State" groupIndex={0} /> <Selection mode="single" /> <FilterRow visible={true} /> <GroupPanel visible={true} /> <Pager showPageSizeSelector={true} allowedPageSizes={allowedPageSizes} /> <StateStoring enabled={true} type="custom" storageKey={storageKey} customLoad={loadState} customSave={saveState} /> </DataGrid> </div> ); } export default App;

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.