Angular Pivot Grid State Persistence
Тhe igxGridState directive allows developers to easily save and restore the grid state. When the IgxGridState
directive is applied on the grid, it exposes the getState
and setState
methods that developers can use to achieve state persistence in any scenario.
Supported Features
IgxGridState
directive supports saving and restoring the state of the following features:
Sorting
Filtering
Cell Selection
Row Selection
Column Selection
Expansion
Pivot Configuration
- Pivot Configuration properties defined by the
IPivotConfiguration
interface. - Pivot Dimension and Value functions are restored using application level code, see Restoring Pivot Configuration section.
- Pivot Row and Column strategies are also restored using application level code, see Restoring Pivot Strategies section.
- Pivot Configuration properties defined by the
Usage
getState
- This method returns the grid state in a serialized JSON string, so developers can just take it and save it on any data storage (database, cloud, browser localStorage, etc). The method accepts first optional parameter serialize
, which determines whether getState
will return an IGridState
object or a serialized JSON string.
The developer may choose to get only the state for a certain feature/features, by passing in the feature name, or an array with feature names as a second argument.
// get all features` state in a serialized JSON string
const gridState = state.getState();
// get an `IGridState` object, containing all features original state objects, as returned by the grid public API
const gridState: IGridState = state.getState(false);
// get the sorting and filtering expressions
const sortingFilteringStates: IGridState = state.getState(false, ['sorting', 'filtering']);
setState
- The setState
method accepts the serialized JSON string or IGridState
object as argument and will restore the state of each feature found in the object/JSON string.
state.setState(gridState);
state.setState(sortingFilteringStates)
options
- The options
object implements the IGridStateOptions
interface, i.e. for every key, which is the name of a certain feature, there is the boolean value indicating if this feature state will be tracked. getState
method will not put the state of these features in the returned value and setState
method will not restore state for it.
public options = { cellSelection: false; sorting: false; }
<igx-pivot-grid [igxGridState]="options"></igx-pivot-grid>
The simple to use single-point API's allows to achieve a full state persistence functionality in just a few lines of code. Copy paste the code from below - it will save the grid state in the browser sessionStorage
object every time the user leaves the current page. Whenever the user returns to main page, the grid state will be restored. No more need to configure those complex advanced filtering and sorting expressions every time to get the data you want - do it once and have the code from below do the rest for your users:
// app.component.ts
@ViewChild(IgxGridStateDirective, { static: true })
public state!: IgxGridStateDirective;
public ngOnInit() {
this.router.events.pipe(take(1)).subscribe((event: NavigationStart) => {
this.saveGridState();
});
}
public ngAfterViewInit() {
this.restoreGridState();
}
public saveGridState() {
const state = this.state.getState() as string;
window.sessionStorage.setItem('grid1-state', state);
}
public restoreGridState() {
const state = window.sessionStorage.getItem('grid1-state');
this.state.setState(state);
}
Restoring Pivot Configuration
IgxGridState
will not persist pivot dimension functions, value formatters, etc. by default (see limitations
). Restoring any of these can be achieved with code on application level. The IgxPivotGrid
exposes two events which can be used to set back any custom functions you have in the configuration: dimensionInit
and valueInit
. Let's show how to do this:
- Assign event handlers for the
dimensionInit
andvalueInit
events:
<igx-pivot-grid #grid1 [data]="data" [pivotConfiguration]="pivotConfig" [igxGridState]="options"
(valueInit)='onValueInit($event)' (dimensionInit)='onDimensionInit($event)'>
</igx-pivot-grid>
The
dimensionInit
andvalueInit
events are emitted for each value and dimension defined in thepivotConfiguration
property.
- In the
valueInit
event handler set all custom aggregators, formatters and styles:
public onValueInit(value: IPivotValue) {
// Needed only for custom aggregators, formatter or styles.
if (value.member === 'AmountofSale') {
value.aggregate.aggregator = IgxTotalSaleAggregate.totalSale;
value.aggregateList?.forEach((aggr: IPivotAggregator) => {
switch (aggr.key) {
case 'SUM':
aggr.aggregator = IgxTotalSaleAggregate.totalSale;
break;
case 'MIN':
aggr.aggregator = IgxTotalSaleAggregate.totalMin;
break;
case 'MAX':
aggr.aggregator = IgxTotalSaleAggregate.totalMax;
break;
}
});
} else if (value.member === 'Value') {
value.formatter = (value) => value ? '$' + parseFloat(value).toFixed(3) : undefined;
value.styles.upFontValue = (rowData: any, columnKey: any): boolean => parseFloat(rowData.aggregationValues.get(columnKey.field)) > 150
value.styles.downFontValue = (rowData: any, columnKey: any): boolean => parseFloat(rowData.aggregationValues.get(columnKey.field)) <= 150;
}
}
- In the
dimensionInit
event handler set all custommemberFunction
implementations:
public onDimensionInit(dim: IPivotDimension) {
switch (dim.memberName) {
case 'AllProducts':
dim.memberFunction = () => 'All Products';
break;
case 'ProductCategory':
dim.memberFunction = (data) => data.Product.Name;
break;
case 'City':
dim.memberFunction = (data) => data.Seller.City;
break;
case 'SellerName':
dim.memberFunction = (data) => data.Seller.Name;
break;
}
}
Restoring Pivot Strategies
IgxGridState
will not persist neither remote pivot operations nor custom dimension strategies (For further information see Pivot Grid Remote Operations sample) by default (see limitations
). Restoring any of these can be achieved with code on application level. The IgxGridState
exposes an event called stateParsed
which can be used to additionally modify the grid state before it gets applied. Let's show how to do this:
stateParsed
is only emitted when we are usingsetState
with string argument.
- Set custom sorting strategy and custom pivot column and row dimension strategies:
<igx-pivot-grid #grid [data]="data" [pivotConfiguration]="pivotConfigHierarchy" [defaultExpandState]='true'
[igxGridState]="options" [sortStrategy]="customStrategy" [pivotUI]='{ showConfiguration: false }' [superCompactMode]="true" [height]="'500px'">
</igx-pivot-grid>
@ViewChild(IgxGridStateDirective, { static: true })
public state!: IgxGridStateDirective;
public customStrategy = NoopSortingStrategy.instance();
public options: IGridStateOptions = {...};
public pivotConfigHierarchy: IPivotConfiguration = {
columnStrategy: NoopPivotDimensionsStrategy.instance(),
rowStrategy: NoopPivotDimensionsStrategy.instance(),
columns: [...],
rows: [...],
values: [...],
filters: [...]
};
- Restoring the state from the
sessionStorage
and applying the custom strategies looks like the following:
public restoreState() {
const state = window.sessionStorage.getItem('grid-state');
this.state.stateParsed.pipe(take(1)).subscribe(parsedState => {
parsedState.sorting.forEach(x => x.strategy = NoopSortingStrategy.instance());
parsedState.pivotConfiguration.rowStrategy = NoopPivotDimensionsStrategy.instance();
parsedState.pivotConfiguration.columnStrategy = NoopPivotDimensionsStrategy.instance();
});
this.state.setState(state as string);
}
Limitations
getState
method uses JSON.stringify() method to convert the original objects to a JSON string. JSON.stringify() does not support Functions, thats why theIgxGridState
directive will ignore the pivot dimensionmemberFunction
, pivot valuesmember
,formatter
, customaggregate
functions,styles
and pivot configuration strategies:columnStrategy
androwStrategy
.