Skip to content

Commit a737364

Browse files
committed
fix(grid): fix column orders, cellSelection #5460
1 parent 5b31846 commit a737364

File tree

3 files changed

+104
-55
lines changed

3 files changed

+104
-55
lines changed

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

+42-16
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { IPagingState } from '../data-operations/paging-state.interface';
1010
import { DataType } from '../data-operations/data-util';
1111
import { IgxBooleanFilteringOperand, IgxNumberFilteringOperand, IgxDateFilteringOperand,
1212
IgxStringFilteringOperand } from '../data-operations/filtering-condition';
13+
import { GridSelectionRange } from './selection/selection.service';
1314

1415
export interface IGridState {
1516
columns?: IColumnState[];
@@ -18,7 +19,7 @@ export interface IGridState {
1819
sorting?: ISortingExpression[];
1920
groupBy?: IGroupingExpression[];
2021
paging?: IPagingState;
21-
cellSelection?: any[];
22+
cellSelection?: GridSelectionRange[];
2223
rowSelection?: any[];
2324
}
2425

@@ -38,16 +39,22 @@ export interface IColumnState {
3839
sortable: boolean;
3940
filterable: boolean;
4041
editable: boolean;
42+
sortingIgnoreCase: boolean;
43+
filteringIgnoreCase: boolean;
44+
headerClasses: string;
45+
headerGroupClasses: string;
46+
maxWidth: string;
4147
groupable: boolean;
4248
movable: boolean;
4349
hidden: boolean;
4450
dataType: string;
45-
summaries?: any;
4651
hasSummary: boolean;
4752
field: string;
4853
width: any;
4954
header: string;
5055
resizable: boolean;
56+
searchable: boolean;
57+
visibleIndex: number;
5158
}
5259

5360
const COLUMNS = 'columns';
@@ -272,12 +279,17 @@ export class IgxGridStateDirective {
272279
* Helper method that creates a new array with the current grid columns.
273280
*/
274281
private getColumns() {
275-
const gridColumns = this.grid.columns.map((c) => {
282+
const gridColumns: IColumnState = this.grid.columns.map((c) => {
276283
return {
277284
pinned: c.pinned,
278285
sortable: c.sortable,
279286
filterable: c.filterable,
280287
editable: c.editable,
288+
sortingIgnoreCase: c.sortingIgnoreCase,
289+
filteringIgnoreCase: c.filteringIgnoreCase,
290+
headerClasses: c.headerClasses,
291+
headerGroupClasses: c.headerGroupClasses,
292+
maxWidth: c.maxWidth,
281293
groupable: c.groupable,
282294
movable: c.movable,
283295
hidden: c.hidden,
@@ -286,7 +298,9 @@ export class IgxGridStateDirective {
286298
field: c.field,
287299
width: c.width,
288300
header: c.header,
289-
resizable: c.resizable
301+
resizable: c.resizable,
302+
searchable: c.searchable,
303+
visibleIndex: c.visibleIndex
290304
};
291305
});
292306
return { columns: gridColumns };
@@ -323,8 +337,8 @@ export class IgxGridStateDirective {
323337
}
324338

325339
private getCellSelection() {
326-
const selection = this.grid.selectedCells.map(cell => {
327-
return { row: cell.rowIndex, column: cell.columnIndex };
340+
const selection = this.grid.getSelectedRanges().map(range => {
341+
return { rowStart: range.rowStart, rowEnd: range.rowEnd, columnStart: range.columnStart, columnEnd: range.columnEnd };
328342
});
329343
return { cellSelection: selection };
330344
}
@@ -335,21 +349,28 @@ export class IgxGridStateDirective {
335349
private restoreColumns(columns: IColumnState[]): void {
336350
const newColumns = [];
337351
const factory = (this.grid as any).resolver.resolveComponentFactory(IgxColumnComponent);
338-
columns.forEach((col) => {
352+
const sortedColumns = columns.sort(this.sortByVisibleIndex);
353+
sortedColumns.forEach((col) => {
339354
const ref = factory.create(this.grid.viewRef.injector);
340-
ref.instance.field = col.field;
341-
ref.instance.dataType = col.dataType;
355+
ref.instance.pinned = col.pinned;
342356
ref.instance.sortable = col.sortable;
343-
ref.instance.groupable = col.groupable;
344-
ref.instance.editable = col.editable;
345357
ref.instance.filterable = col.filterable;
346-
ref.instance.resizable = col.resizable;
358+
ref.instance.editable = col.editable;
359+
ref.instance.sortingIgnoreCase = col.sortingIgnoreCase;
360+
ref.instance.filteringIgnoreCase = col.filteringIgnoreCase;
361+
ref.instance.headerClasses = col.headerClasses;
362+
ref.instance.headerGroupClasses = col.headerGroupClasses;
363+
ref.instance.maxWidth = col.maxWidth;
364+
ref.instance.groupable = col.groupable;
347365
ref.instance.movable = col.movable;
348-
ref.instance.width = col.width;
349-
ref.instance.pinned = col.pinned;
350366
ref.instance.hidden = col.hidden;
367+
ref.instance.dataType = col.dataType;
351368
ref.instance.hasSummary = col.hasSummary;
369+
ref.instance.field = col.field;
370+
ref.instance.width = col.width;
352371
ref.instance.header = col.header;
372+
ref.instance.resizable = col.resizable;
373+
ref.instance.searchable = col.searchable;
353374
ref.changeDetectorRef.detectChanges();
354375
newColumns.push(ref.instance);
355376
});
@@ -358,6 +379,11 @@ export class IgxGridStateDirective {
358379
this.grid.columnList.notifyOnChanges();
359380
}
360381

382+
private sortByVisibleIndex(colA, colB) {
383+
const a = colA.visibleIndex, b = colB.visibleIndex;
384+
return a > b ? 1 : a < b ? -1 : 0;
385+
}
386+
361387
/**
362388
* Restores the grid filtering state, i.e. sets the `filteringExpressionsTree` property value.
363389
*/
@@ -422,8 +448,8 @@ export class IgxGridStateDirective {
422448
}
423449

424450
private restoreCellSelection(state: any[]) {
425-
state.forEach(cell => {
426-
const range = { rowStart: cell.row, rowEnd: cell.row, columnStart: cell.column, columnEnd: cell.column};
451+
state.forEach(r => {
452+
const range = { rowStart: r.rowStart, rowEnd: r.rowEnd, columnStart: r.columnStart, columnEnd: r.columnEnd};
427453
this.grid.selectRange(range);
428454
});
429455
}

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

+26-7
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
<igx-switch [(ngModel)]="options.sorting" (change)="onChange($event, 'sorting')">Sorting</igx-switch>
3131
</div>
3232
<div class="control-item">
33-
<igx-switch [(ngModel)]="options.groupby" (change)="onChange($event, 'groupby')">Grouping</igx-switch>
33+
<igx-switch [(ngModel)]="options.groupBy" (change)="onChange($event, 'groupBy')">Grouping</igx-switch>
3434
</div>
3535
<div class="control-item">
3636
<igx-switch [(ngModel)]="options.columns" (change)="onChange($event, 'columns')">Columns</igx-switch>
@@ -79,12 +79,31 @@
7979
</div>
8080
</div>
8181

82-
<igx-grid [id]="gridId" #grid1 [igxGridState]="options" [data]="localData" [primaryKey]="'EmployeeID'" width="1200px" height="550px"
83-
[rowEditable]="false" [allowFiltering]="true" [allowAdvancedFiltering]="true"
84-
[paging]="true" [showToolbar]="true" [columnPinning]="true" [columnHiding]="true"
85-
[filterMode]="'excelStyleFilter'" [displayDensity]="'cosy'" [cellSelection]="selectionMode" [rowSelection]="'none'">
86-
<igx-column *ngFor="let c of columns" [sortable]="c.sortable" [movable]="c.movable" [editable]="true" [filterable]="c.filterable" [groupable]="c.groupable"
87-
[field]="c.field" [header]="c.header" [dataType]="c.dataType" [pinned]="c.pinned" [hidden]="c.hidden">
82+
<igx-grid [id]="gridId" #grid1 [igxGridState]="options"
83+
width="1200px" height="550px" [autoGenerate]="false"
84+
[data]="localData"
85+
[primaryKey]="'EmployeeID'"
86+
[rowEditable]="false"
87+
[allowFiltering]="true" [allowAdvancedFiltering]="true" [filterMode]="'excelStyleFilter'"
88+
[paging]="true"
89+
[showToolbar]="true"
90+
[columnPinning]="true"
91+
[columnHiding]="true"
92+
[displayDensity]="'cosy'"
93+
[cellSelection]="selectionMode"
94+
[rowSelection]="'none'">
95+
<igx-column *ngFor="let c of columns"
96+
[sortable]="c.sortable"
97+
[movable]="c.movable"
98+
[editable]="true"
99+
[hasSummary]="c.hasSummary"
100+
[filterable]="c.filterable"
101+
[groupable]="c.groupable"
102+
[field]="c.field"
103+
[header]="c.header"
104+
[dataType]="c.dataType"
105+
[pinned]="c.pinned"
106+
[hidden]="c.hidden">
88107
</igx-column>
89108
</igx-grid>
90109

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

+36-32
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
11
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
22
import { IgxGridComponent, FilteringExpressionsTree, FilteringLogic,
3-
IPagingState, IGroupingExpression, ISortingExpression } from 'igniteui-angular';
3+
IPagingState, IGroupingExpression, ISortingExpression, IgxNumberSummaryOperand, IgxSummaryResult,
4+
IgxGridStateDirective, IGridState, IColumnState } from 'igniteui-angular';
45
import { employeesData } from './localData';
56
import { take } from 'rxjs/operators';
67
import { NavigationStart, Router } from '@angular/router';
7-
import { IgxGridStateDirective, IGridState } from 'projects/igniteui-angular/src/lib/grids/state.directive';
8-
9-
interface IColumnState {
10-
field: string;
11-
header: string;
12-
width?: string;
13-
groupable?: boolean;
14-
dataType?: string;
15-
pinned?: boolean;
16-
sortable?: boolean;
17-
filterable?: boolean;
18-
movable?: true;
19-
hidden?: boolean;
8+
9+
class MySummary extends IgxNumberSummaryOperand {
10+
11+
constructor() {
12+
super();
13+
}
14+
15+
operate(data?: any[]): IgxSummaryResult[] {
16+
const result = super.operate(data);
17+
result.push({
18+
key: 'test',
19+
label: 'Test',
20+
summaryResult: data.filter(rec => rec > 10 && rec < 30).length
21+
});
22+
return result;
23+
}
2024
}
2125

2226
@Component({
@@ -40,20 +44,20 @@ export class GridSaveStateComponent implements OnInit, AfterViewInit {
4044
advancedFiltering: true,
4145
paging: true,
4246
sorting: true,
43-
groupby: true,
47+
groupBy: true,
4448
columns: true
4549
};
4650

4751
@ViewChild(IgxGridStateDirective, { static: true }) public state: IgxGridStateDirective;
4852
@ViewChild(IgxGridComponent, { static: true }) public grid: IgxGridComponent;
4953

50-
public initialColumns: IColumnState[] = [
54+
public initialColumns: any[] = [
5155
// tslint:disable:max-line-length
52-
{ field: 'FirstName', header: 'First Name', width: '150px', dataType: 'string', pinned: true, movable: true, sortable: true, filterable: true},
53-
{ field: 'LastName', header: 'Last Name', width: '150px', dataType: 'string', pinned: true, movable: true, sortable: true, filterable: true },
54-
{ field: 'Country', header: 'Country', width: '140px', dataType: 'string', groupable: true, movable: true, sortable: true, filterable: true },
55-
{ field: 'Age', header: 'Age', width: '110px', dataType: 'number', movable: true, sortable: true, filterable: true},
56-
{ field: 'RegistererDate', header: 'Registerer Date', width: '180px', dataType: 'date', movable: true, sortable: true, filterable: true },
56+
{ field: 'FirstName', header: 'First Name', width: '150px', dataType: 'string', pinned: true, movable: true, sortable: true, filterable: true, summaries: MySummary},
57+
{ field: 'LastName', header: 'Last Name', width: '150px', dataType: 'string', pinned: true, movable: true, sortable: true, filterable: true},
58+
{ field: 'Country', header: 'Country', width: '140px', dataType: 'string', groupable: true, movable: true, sortable: true, filterable: true, resizable: true },
59+
{ field: 'Age', header: 'Age', width: '110px', dataType: 'number', movable: true, sortable: true, filterable: true, hasSummary: true, summaries: MySummary, resizable: true},
60+
{ field: 'RegistererDate', header: 'Registerer Date', width: '180px', dataType: 'date', movable: true, sortable: true, filterable: true, resizable: true },
5761
{ field: 'IsActive', header: 'Is Active', width: '140px', dataType: 'boolean', groupable: true, movable: true, sortable: true, filterable: true }
5862
// tslint:enable:max-line-length
5963
];
@@ -121,13 +125,13 @@ export class GridSaveStateComponent implements OnInit, AfterViewInit {
121125

122126
public getColumnsState(): any {
123127
let state = window.localStorage.getItem(this.stateKey);
124-
state = JSON.parse(state)['columns'];
128+
state = state ? JSON.parse(state).columns : null;
125129
return state;
126130
}
127131

128132
public restoreFiltering() {
129133
const state = window.localStorage.getItem(this.stateKey);
130-
const filteringState: FilteringExpressionsTree = JSON.parse(state).filtering;
134+
const filteringState: FilteringExpressionsTree = state ? JSON.parse(state).filtering : null;
131135
if (filteringState) {
132136
const gridFilteringState: IGridState = { filtering: filteringState};
133137
this.state.setState(gridFilteringState);
@@ -136,7 +140,7 @@ export class GridSaveStateComponent implements OnInit, AfterViewInit {
136140

137141
public restoreAdvancedFiltering() {
138142
const state = window.localStorage.getItem(this.stateKey);
139-
const advFilteringState: FilteringExpressionsTree = JSON.parse(state).advancedFiltering;
143+
const advFilteringState: FilteringExpressionsTree = state ? JSON.parse(state).advancedFiltering : null;
140144
if (advFilteringState) {
141145
const gridAdvancedFilteringState: IGridState = { advancedFiltering: advFilteringState};
142146
this.state.setState(gridAdvancedFilteringState);
@@ -145,34 +149,34 @@ export class GridSaveStateComponent implements OnInit, AfterViewInit {
145149

146150
public restoreSorting() {
147151
const state = window.localStorage.getItem(this.stateKey);
148-
const sortingState: ISortingExpression[] = JSON.parse(state).sorting;
149-
if (state) {
152+
const sortingState: ISortingExpression[] = state ? JSON.parse(state).sorting : null;
153+
if (sortingState) {
150154
const gridSortingState: IGridState = { sorting: sortingState};
151155
this.state.setState(gridSortingState);
152156
}
153157
}
154158

155159
public restoreGroupby() {
156160
const state = window.localStorage.getItem(this.stateKey);
157-
const groupByState: IGroupingExpression[] = JSON.parse(state).groupby;
158-
if (state) {
161+
const groupByState: IGroupingExpression[] = state ? JSON.parse(state).groupBy : null;
162+
if (groupByState) {
159163
const gridGroupiByState: IGridState = { groupBy: groupByState};
160164
this.state.setState(gridGroupiByState);
161165
}
162166
}
163167

164168
public restoreRowSelection() {
165169
const state = window.localStorage.getItem(this.stateKey);
166-
const rowSelectionState = JSON.parse(state).rowSelection;
167-
if (state) {
170+
const rowSelectionState = state ? JSON.parse(state).rowSelection : null;
171+
if (rowSelectionState) {
168172
const gridRowSelectionState: IGridState = { rowSelection: rowSelectionState };
169173
this.state.setState(gridRowSelectionState);
170174
}
171175
}
172176

173177
public restoreCellSelection() {
174178
const state = window.localStorage.getItem(this.stateKey);
175-
const cellSelectionState = JSON.parse(state).cellSelection;
179+
const cellSelectionState = state ? JSON.parse(state).cellSelection : null;
176180
if (state) {
177181
const gridCellSelectionState: IGridState = { cellSelection: cellSelectionState };
178182
this.state.setState(gridCellSelectionState);
@@ -181,7 +185,7 @@ export class GridSaveStateComponent implements OnInit, AfterViewInit {
181185

182186
public restorePaging() {
183187
const state = window.localStorage.getItem(this.stateKey);
184-
const pagingState: IPagingState = JSON.parse(state).paging;
188+
const pagingState: IPagingState = state ? JSON.parse(state).paging : null;
185189
if (state) {
186190
const gridPagingState: IGridState = { paging: pagingState };
187191
this.state.setState(gridPagingState);

0 commit comments

Comments
 (0)