Skip to content

Commit 8a993e2

Browse files
committed
feat(grid): Add selection, adv filtering #5460
1 parent 56913bd commit 8a993e2

File tree

3 files changed

+120
-55
lines changed

3 files changed

+120
-55
lines changed

projects/igniteui-angular/src/lib/grids/state.directive.ts

+59-42
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@ import { IgxBooleanFilteringOperand, IgxNumberFilteringOperand, IgxDateFiltering
1212
IgxStringFilteringOperand } from '../data-operations/filtering-condition';
1313

1414
export interface IGridState {
15-
columns: IColumnState[];
16-
filtering: FilteringExpressionsTree;
17-
advancedFiltering: FilteringExpressionsTree;
18-
sorting: ISortingExpression[];
19-
groupby: IGroupingExpression[];
20-
paging: IPagingState;
21-
selection: any[];
15+
columns?: IColumnState[];
16+
filtering?: FilteringExpressionsTree;
17+
advancedFiltering?: FilteringExpressionsTree;
18+
sorting?: ISortingExpression[];
19+
groupby?: IGroupingExpression[];
20+
paging?: IPagingState;
21+
cellSelection?: any[];
22+
rowSelection?: any[];
2223
}
2324

2425
interface IGridStateOptions {
@@ -28,7 +29,8 @@ interface IGridStateOptions {
2829
sorting?: boolean;
2930
groupby?: boolean;
3031
paging?: boolean;
31-
selection?: boolean;
32+
cellSelection?: boolean;
33+
rowSelection?: boolean;
3234
}
3335

3436
interface IColumnState {
@@ -56,7 +58,8 @@ const ACTION_ADVANCED_FILTERING = 'advancedFiltering';
5658
const ACTION_SORTING = 'sorting';
5759
const ACTION_GROUPBY = 'groupby';
5860
const ACTION_PAGING = 'paging';
59-
const ACTION_SELECTION = 'selection';
61+
const ACTION_ROW_SELECTION = 'rowSelection';
62+
const ACTION_CELL_SELECTION = 'cellSelection';
6063

6164
@Directive({
6265
selector: '[igxGridState]'
@@ -70,7 +73,8 @@ export class IgxGridStateDirective {
7073
sorting: true,
7174
groupby: true,
7275
paging: true,
73-
selection: true,
76+
cellSelection: true,
77+
rowSelection: true
7478
};
7579

7680
private state: IGridState | IColumnState | IFilteringExpressionsTree |
@@ -110,17 +114,11 @@ export class IgxGridStateDirective {
110114
* this.state.setState(gridState);
111115
* ```
112116
*/
113-
public setState(state: IGridState |
114-
IColumnState |
115-
IFilteringExpressionsTree |
116-
ISortingExpression |
117-
IGroupingExpression |
118-
IPagingState | string) {
117+
public setState(state: IGridState | string) {
119118
if (typeof state === 'string') {
120119
state = JSON.parse(state as string, this.parseCallback) as string;
121120
}
122-
this.state = state as IGridState | IColumnState | IFilteringExpressionsTree |
123-
ISortingExpression | IGroupingExpression | IPagingState;
121+
this.state = state as IGridState;
124122
this.restoreGridState(this.state);
125123
}
126124

@@ -137,25 +135,16 @@ export class IgxGridStateDirective {
137135
* let state = this.state.getState();
138136
* ```
139137
*/
140-
public getState(serialize = true, feature?: string | string[]): IGridState |
141-
IColumnState |
142-
IFilteringExpressionsTree |
143-
ISortingExpression |
144-
IGroupingExpression |
145-
IPagingState | string {
146-
let state: IGridState |
147-
IColumnState |
148-
IFilteringExpressionsTree |
149-
ISortingExpression |
150-
IGroupingExpression |
151-
IPagingState | string;
138+
public getState(serialize = true, feature?: string | string[]): IGridState | string {
139+
let state: IGridState | string;
152140
if (feature) {
141+
state = {};
153142
if (Array.isArray(feature)) {
154143
feature.forEach(f => {
155-
state[f] = this.getGridFeature(f);
144+
state = Object.assign(state, this.getGridFeature(f));
156145
});
157146
} else {
158-
state[feature] = this.getGridFeature(feature);
147+
state = this.getGridFeature(feature);
159148
}
160149
} else {
161150
state = this.getAllGridFeatures() as IGridState;
@@ -191,7 +180,7 @@ export class IgxGridStateDirective {
191180
break;
192181
}
193182
case ACTION_ADVANCED_FILTERING: {
194-
state = this.getAdvancedFiltering();
183+
state = this.restoreAdvancedFiltering(state);
195184
break;
196185
}
197186
case ACTION_SORTING: {
@@ -206,8 +195,12 @@ export class IgxGridStateDirective {
206195
this.restorePaging(state);
207196
break;
208197
}
209-
case ACTION_SELECTION: {
210-
state = this.getSelection();
198+
case ACTION_ROW_SELECTION: {
199+
state = this.restoreRowSelection(state);
200+
break;
201+
}
202+
case ACTION_CELL_SELECTION: {
203+
state = this.restoreCellSelection(state);
211204
break;
212205
}
213206
}
@@ -261,8 +254,12 @@ export class IgxGridStateDirective {
261254
state = this.getPaging();
262255
break;
263256
}
264-
case ACTION_SELECTION: {
265-
state = this.getSelection();
257+
case ACTION_ROW_SELECTION: {
258+
state = this.getRowSelection();
259+
break;
260+
}
261+
case ACTION_CELL_SELECTION: {
262+
state = this.getCellSelection();
266263
break;
267264
}
268265
}
@@ -279,6 +276,7 @@ export class IgxGridStateDirective {
279276
sortable: c.sortable,
280277
filterable: c.filterable,
281278
editable: c.editable,
279+
groupable: c.groupable,
282280
movable: c.movable,
283281
hidden: c.hidden,
284282
dataType: c.dataType,
@@ -317,9 +315,16 @@ export class IgxGridStateDirective {
317315
return { groupby: groupingState };
318316
}
319317

320-
private getSelection() {
318+
private getRowSelection() {
321319
const selection = this.grid.selectedRows();
322-
return { selection: selection };
320+
return { rowSelection: selection };
321+
}
322+
323+
private getCellSelection() {
324+
const selection = this.grid.selectedCells.map(cell => {
325+
return { row: cell.rowIndex, column: cell.columnIndex };
326+
});
327+
return { cellSelection: selection };
323328
}
324329

325330
/**
@@ -363,7 +368,7 @@ export class IgxGridStateDirective {
363368
* Restores the grid advanced filtering state, i.e. sets the `advancedFilteringExpressionsTree` property value.
364369
*/
365370
private restoreAdvancedFiltering(state) {
366-
const advFilterTree = this.createExpressionsTreeFromObject(state.advancedFiltering);
371+
const advFilterTree = this.createExpressionsTreeFromObject(state);
367372
this.grid.advancedFilteringExpressionsTree = advFilterTree;
368373
}
369374

@@ -410,10 +415,17 @@ export class IgxGridStateDirective {
410415
}
411416
}
412417

413-
private restoreSelection(state: any[]) {
418+
private restoreRowSelection(state: any[]) {
414419
this.grid.selectRows(state);
415420
}
416421

422+
private restoreCellSelection(state: any[]) {
423+
state.forEach(cell => {
424+
const range = { rowStart: cell.row, rowEnd: cell.row, columnStart: cell.column, columnEnd: cell.column};
425+
this.grid.selectRange(range);
426+
});
427+
}
428+
417429
/**
418430
* This method builds a FilteringExpressionsTree from a provided object.
419431
*/
@@ -431,7 +443,12 @@ export class IgxGridStateDirective {
431443
expressionsTree.filteringOperands.push(subTree);
432444
} else {
433445
const expr = item as IFilteringExpression;
434-
const dataType = this.state[ACTION_COLUMNS].find(c => c.field === expr.fieldName).dataType;
446+
let dataType: string;
447+
if (this.grid.columnList.length > 0) {
448+
dataType = this.grid.columnList.find(c => c.field === expr.fieldName).dataType;
449+
} else {
450+
dataType = this.state[ACTION_COLUMNS].find(c => c.field === expr.fieldName).dataType;
451+
}
435452
expr.condition = this.generateFilteringCondition(dataType, expr.condition.name);
436453
expr.searchVal = (dataType === 'date') ? new Date(Date.parse(expr.searchVal)) : expr.searchVal;
437454
expressionsTree.filteringOperands.push(expr);

src/app/grid-state/grid-state.component.html

+16-4
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,15 @@
77
<li>Use the <strong>delete</strong> and <strong>reload</strong> buttons to clear the localStorage content and reload the page with clear state.</li>
88
</ul>
99
</div>
10+
<div class="switches" style="min-width: inherit">
11+
<igx-buttongroup [values]="selectionModes" (onSelect)="selectCellSelectionMode($event)"></igx-buttongroup>
12+
</div>
1013
<div class="switches">
1114
<div class="control-item">
12-
<igx-switch [(ngModel)]="options.selection" (change)="onChange($event, 'selection')">Row Selection</igx-switch>
15+
<igx-switch [(ngModel)]="options.rowSelection" (change)="onChange($event, 'rowSelection')">Row Selection</igx-switch>
16+
</div>
17+
<div class="control-item">
18+
<igx-switch [(ngModel)]="options.cellSelection" (change)="onChange($event, 'cellSelection')">Cell Selection</igx-switch>
1319
</div>
1420
<div class="control-item">
1521
<igx-switch [(ngModel)]="options.filtering" (change)="onChange($event, 'filtering')">Filtering</igx-switch>
@@ -43,14 +49,20 @@
4349
<div class="control-item">
4450
<button igxButton="raised" (click)="restoreFiltering()">Filtering</button>
4551
</div>
52+
<div class="control-item">
53+
<button igxButton="raised" (click)="restoreAdvancedFiltering()">Adv Filtering</button>
54+
</div>
4655
<div class="control-item">
4756
<button igxButton="raised" (click)="restoreSorting()">Sorting</button>
4857
</div>
4958
<div class="control-item">
5059
<button igxButton="raised" (click)="restoreGroupby()">GroupBy</button>
5160
</div>
5261
<div class="control-item">
53-
<button igxButton="raised" (click)="restoreSelection">Selection</button>
62+
<button igxButton="raised" (click)="restoreRowSelection()">Row Selection</button>
63+
</div>
64+
<div class="control-item">
65+
<button igxButton="raised" (click)="restoreCellSelection()">Cell Selection</button>
5466
</div>
5567
<div class="control-item">
5668
<button igxButton="raised" (click)="restorePaging()">Paging</button>
@@ -67,10 +79,10 @@
6779
</div>
6880
</div>
6981

70-
<igx-grid [id]="gridId" #grid1 [igxGridState]="options" [data]="localData" [primaryKey]="'ProductID'" width="1200px" height="550px"
82+
<igx-grid [id]="gridId" #grid1 [igxGridState]="options" [data]="localData" [primaryKey]="'EmployeeID'" width="1200px" height="550px"
7183
[rowEditable]="false" [allowFiltering]="true" [allowAdvancedFiltering]="true"
7284
[paging]="true" [showToolbar]="true" [columnPinning]="true" [columnHiding]="true"
73-
[filterMode]="'excelStyleFilter'" [displayDensity]="'cosy'">
85+
[filterMode]="'excelStyleFilter'" [displayDensity]="'cosy'" [cellSelection]="selectionMode" [rowSelection]="'none'">
7486
<igx-column *ngFor="let c of columns" [sortable]="c.sortable" [movable]="c.movable" [editable]="true" [filterable]="c.filterable" [groupable]="c.groupable"
7587
[field]="c.field" [header]="c.header" [dataType]="c.dataType" [pinned]="c.pinned" [hidden]="c.hidden">
7688
</igx-column>

src/app/grid-state/grid-state.component.ts

+45-9
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ export class GridSaveStateComponent implements OnInit, AfterViewInit {
3333
public serialize = true;
3434

3535
public options = {
36-
selection: false,
36+
cellSelection: true,
37+
rowSelection: true,
3738
filtering: true,
38-
advancedFiltering: false,
39+
advancedFiltering: true,
3940
paging: true,
4041
sorting: true,
41-
groupby: false,
42+
groupby: true,
4243
columns: true
4344
};
4445

@@ -56,7 +57,15 @@ export class GridSaveStateComponent implements OnInit, AfterViewInit {
5657
// tslint:enable:max-line-length
5758
];
5859

60+
public selectionMode = 'multiple';
61+
public selectionModes = [];
62+
5963
constructor(private router: Router) {
64+
this.selectionModes = [
65+
{ label: 'none', selected: this.selectionMode === 'none', togglable: true },
66+
{ label: 'single', selected: this.selectionMode === 'single', togglable: true },
67+
{ label: 'multiple', selected: this.selectionMode === 'multiple', togglable: true }
68+
];
6069
}
6170

6271
public ngOnInit() {
@@ -87,6 +96,7 @@ export class GridSaveStateComponent implements OnInit, AfterViewInit {
8796

8897
public saveGridState() {
8998
const state = this.state.getState(this.serialize);
99+
// const state = this.state.getState(this.serialize, ['sorting', 'filtering']);
90100
if (typeof state === 'string') {
91101
window.localStorage.setItem(this.stateKey, state);
92102
} else {
@@ -102,18 +112,32 @@ export class GridSaveStateComponent implements OnInit, AfterViewInit {
102112
}
103113

104114
public restoreColumns() {
105-
let state = window.localStorage.getItem(this.stateKey);
106-
state = JSON.parse(state)['columns'];
115+
const state = this.getColumnsState();
107116
if (state) {
108117
this.state.setState({ columns: state });
109118
}
110119
}
111120

121+
public getColumnsState(): any {
122+
let state = window.localStorage.getItem(this.stateKey);
123+
state = JSON.parse(state)['columns'];
124+
return state;
125+
}
126+
112127
public restoreFiltering() {
113128
let state = window.localStorage.getItem(this.stateKey);
114129
state = JSON.parse(state)['filtering'];
115130
if (state) {
116-
this.state.setState({ filtering: state });
131+
this.state.setState({ filtering: state, columns: this.getColumnsState() });
132+
}
133+
}
134+
135+
public restoreAdvancedFiltering() {
136+
this.restoreColumns();
137+
let state = window.localStorage.getItem(this.stateKey);
138+
state = JSON.parse(state)['advancedFiltering'];
139+
if (state) {
140+
this.state.setState({ advancedFiltering: state, columns: this.getColumnsState() });
117141
}
118142
}
119143

@@ -133,11 +157,19 @@ export class GridSaveStateComponent implements OnInit, AfterViewInit {
133157
}
134158
}
135159

136-
public restoreSelection() {
160+
public restoreRowSelection() {
161+
let state = window.localStorage.getItem(this.stateKey);
162+
state = JSON.parse(state)['rowSelection'];
163+
if (state) {
164+
this.state.setState({ rowSelection: state });
165+
}
166+
}
167+
168+
public restoreCellSelection() {
137169
let state = window.localStorage.getItem(this.stateKey);
138-
state = JSON.parse(state)['selection'];
170+
state = JSON.parse(state)['cellSelection'];
139171
if (state) {
140-
this.state.setState({ selection: state });
172+
this.state.setState({ cellSelection: state });
141173
}
142174
}
143175

@@ -160,6 +192,10 @@ export class GridSaveStateComponent implements OnInit, AfterViewInit {
160192
this.state.options[action] = event.checked;
161193
}
162194

195+
public selectCellSelectionMode(args) {
196+
this.selectionMode = this.selectionModes[args.index].label;
197+
}
198+
163199
public onSerializeChange(event: any) {
164200
// this.serialize = !!event.checked;
165201
}

0 commit comments

Comments
 (0)