Skip to content

Commit d35484e

Browse files
Svetloslav15hanastasovkdinevddincheva
authored
feat(igx-grid): add isSelectedAllClicked to rowSelectionChanging event (#12094)
* feat(grid): add isSelectedAllClicked to rowChanging event * fix(selection): add isSelectAllClicked to tests * fix(grid-selection): select internally rows in virtualization * fix(grid): add selection for virtual scroll * chore(selection): remove unused prop * fix(grid): change condition for indeterminate state of grid header selected * fix(grid): simplify selection * fix(grid): update paging sample * chore(grid): remove unused code for selection * fix(grid): add required primary for selection of remote data * fix(grid): improve performance on grid scroll * fix(grid): improve performance on grid scroll Co-authored-by: Hristo <[email protected]> Co-authored-by: Konstantin Dinev <[email protected]> Co-authored-by: Desislava Dincheva <[email protected]>
1 parent 8b64a3d commit d35484e

File tree

11 files changed

+88
-39
lines changed

11 files changed

+88
-39
lines changed

projects/igniteui-angular/src/lib/grids/common/events.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export interface IRowSelectionEventArgs extends CancelableEventArgs, IBaseEventA
8585
readonly added: any[];
8686
readonly removed: any[];
8787
readonly event?: Event;
88+
readonly allRowsSelected?: boolean;
8889
}
8990

9091
export interface IColumnSelectionEventArgs extends CancelableEventArgs, IBaseEventArgs {

projects/igniteui-angular/src/lib/grids/grid-base.directive.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3798,6 +3798,7 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
37983798
* @hidden @internal
37993799
*/
38003800
public dataRebound(event) {
3801+
this.selectionService.clearHeaderCBState();
38013802
this.dataChanged.emit(event);
38023803
}
38033804

projects/igniteui-angular/src/lib/grids/grid/grid-row-selection.spec.ts

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ describe('IgxGrid - Row Selection #grid', () => {
140140
event: jasmine.anything() as any,
141141
newSelection: allRowsArray,
142142
oldSelection: [],
143-
removed: []
143+
removed: [],
144+
allRowsSelected: true
144145
};
145146
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
146147

@@ -157,7 +158,8 @@ describe('IgxGrid - Row Selection #grid', () => {
157158
added: [],
158159
removed: allRowsArray,
159160
event: jasmine.anything() as any,
160-
cancel: false
161+
cancel: false,
162+
allRowsSelected: false
161163
};
162164
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
163165
});
@@ -207,7 +209,8 @@ describe('IgxGrid - Row Selection #grid', () => {
207209
event: jasmine.anything() as any,
208210
newSelection: [1],
209211
oldSelection: [],
210-
removed: []
212+
removed: [],
213+
allRowsSelected: false
211214
};
212215
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
213216

@@ -230,7 +233,8 @@ describe('IgxGrid - Row Selection #grid', () => {
230233
event: jasmine.anything() as any,
231234
newSelection: [1, 2],
232235
oldSelection: [1],
233-
removed: []
236+
removed: [],
237+
allRowsSelected: false
234238
};
235239
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
236240

@@ -248,7 +252,8 @@ describe('IgxGrid - Row Selection #grid', () => {
248252
event: jasmine.anything() as any,
249253
newSelection: [2],
250254
oldSelection: [1, 2],
251-
removed: [1]
255+
removed: [1],
256+
allRowsSelected: false
252257
};
253258
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
254259

@@ -265,7 +270,8 @@ describe('IgxGrid - Row Selection #grid', () => {
265270
event: jasmine.anything() as any,
266271
newSelection: [],
267272
oldSelection: [2],
268-
removed: [2]
273+
removed: [2],
274+
allRowsSelected: false
269275
};
270276
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
271277
});
@@ -289,7 +295,8 @@ describe('IgxGrid - Row Selection #grid', () => {
289295
event: mockEvent,
290296
newSelection: [2],
291297
oldSelection: [],
292-
removed: []
298+
removed: [],
299+
allRowsSelected: false
293300
});
294301

295302
// Click again on same row
@@ -314,7 +321,8 @@ describe('IgxGrid - Row Selection #grid', () => {
314321
event: mockEvent,
315322
newSelection: [3],
316323
oldSelection: [2],
317-
removed: [2]
324+
removed: [2],
325+
allRowsSelected: false
318326
});
319327
});
320328
it('Should select the row only on checkbox click when selectRowOnClick has value false', () => {
@@ -510,7 +518,8 @@ describe('IgxGrid - Row Selection #grid', () => {
510518
event: mockEvent,
511519
newSelection: [2, 3, 4, 5],
512520
oldSelection: [2],
513-
removed: []
521+
removed: [],
522+
allRowsSelected: false
514523
});
515524

516525
for (let index = 1; index < 5; index++) {
@@ -852,7 +861,8 @@ describe('IgxGrid - Row Selection #grid', () => {
852861
event: jasmine.anything() as any,
853862
newSelection: [1],
854863
oldSelection: [],
855-
removed: []
864+
removed: [],
865+
allRowsSelected: false
856866
};
857867
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
858868

@@ -874,7 +884,8 @@ describe('IgxGrid - Row Selection #grid', () => {
874884
event: jasmine.anything() as any,
875885
newSelection: [2],
876886
oldSelection: [1],
877-
removed: [1]
887+
removed: [1],
888+
allRowsSelected: false
878889
};
879890
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
880891
});
@@ -1026,7 +1037,8 @@ describe('IgxGrid - Row Selection #grid', () => {
10261037
event: mockEvent,
10271038
newSelection: [5],
10281039
oldSelection: [2],
1029-
removed: [2]
1040+
removed: [2],
1041+
allRowsSelected: false
10301042
});
10311043

10321044
GridSelectionFunctions.verifyRowSelected(secondRow);
@@ -1361,7 +1373,8 @@ describe('IgxGrid - Row Selection #grid', () => {
13611373
event: jasmine.anything() as any,
13621374
newSelection: [gridData[1]],
13631375
oldSelection: [],
1364-
removed: []
1376+
removed: [],
1377+
allRowsSelected: false
13651378
};
13661379
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
13671380

@@ -1376,7 +1389,8 @@ describe('IgxGrid - Row Selection #grid', () => {
13761389
event: jasmine.anything() as any,
13771390
newSelection: [gridData[1], gridData[2], gridData[3], gridData[4]],
13781391
oldSelection: [gridData[1]],
1379-
removed: []
1392+
removed: [],
1393+
allRowsSelected: false
13801394
};
13811395
expect(grid.rowSelectionChanging.emit).toHaveBeenCalledWith(args);
13821396
});

projects/igniteui-angular/src/lib/grids/headers/grid-header-row.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,10 @@
129129
<igx-checkbox
130130
[tabindex]="-1"
131131
[readonly]="true"
132-
[checked]="context.selectedCount > 0 && context.totalCount === context.selectedCount"
132+
[checked]="context.selectedCount > 0 && grid.selectionService.areAllRowSelected()"
133133
[disableRipple]="true"
134134
[ngStyle]="{'visibility': grid.isMultiRowSelectionEnabled? 'visible' : 'hidden' }"
135-
[indeterminate]="context.selectedCount > 0 && context.selectedCount !== context.totalCount"
135+
[indeterminate]="context.selectedCount > 0 && grid.selectionService.hasSomeRowSelected()"
136136
[aria-label]="grid.headSelectorBaseAriaLabel"
137137
#headerCheckbox>
138138
</igx-checkbox>

projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.selection.spec.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,8 @@ describe('IgxHierarchicalGrid selection #hGrid', () => {
640640
newSelection: ['00'],
641641
oldSelection: [],
642642
removed: [],
643-
owner: childGrid
643+
owner: childGrid,
644+
allRowsSelected: false
644645
});
645646

646647
// Click on checkbox on second row
@@ -657,7 +658,8 @@ describe('IgxHierarchicalGrid selection #hGrid', () => {
657658
newSelection: ['01'],
658659
oldSelection: ['00'],
659660
removed: ['00'],
660-
owner: childGrid
661+
owner: childGrid,
662+
allRowsSelected: false
661663
});
662664

663665
// Click on a row in parent grid
@@ -674,7 +676,8 @@ describe('IgxHierarchicalGrid selection #hGrid', () => {
674676
event: mockEvent,
675677
newSelection: ['1'],
676678
oldSelection: [],
677-
removed: []
679+
removed: [],
680+
allRowsSelected: false
678681
});
679682

680683
// Click on a header checkbox in parent grid
@@ -690,7 +693,8 @@ describe('IgxHierarchicalGrid selection #hGrid', () => {
690693
event: mockEvent,
691694
newSelection: ['1', '0', '2', '3', '4'],
692695
oldSelection: ['1'],
693-
removed: []
696+
removed: [],
697+
allRowsSelected: true
694698
});
695699
});
696700
it('should be able to select multiple rows only on checkbox click when selectRowOnClick is disabled', () => {

projects/igniteui-angular/src/lib/grids/selection/selection.service.ts

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -479,14 +479,14 @@ export class IgxGridSelectionService {
479479
this.rowSelection.clear();
480480
}
481481
rowIDs.forEach(rowID => this.rowSelection.add(rowID));
482-
this.allRowsSelected = undefined;
482+
this.clearHeaderCBState();
483483
this.selectedRowsChange.next();
484484
}
485485

486486
/** Deselect specified rows. No event is emitted. */
487487
public deselectRowsWithNoEvent(rowIDs: any[]): void {
488+
this.clearHeaderCBState();
488489
rowIDs.forEach(rowID => this.rowSelection.delete(rowID));
489-
this.allRowsSelected = undefined;
490490
this.selectedRowsChange.next();
491491
}
492492

@@ -512,7 +512,7 @@ export class IgxGridSelectionService {
512512

513513
/** Select range from last selected row to the current specified row. */
514514
public selectMultipleRows(rowID, rowData, event?): void {
515-
this.allRowsSelected = undefined;
515+
this.clearHeaderCBState();
516516
if (!this.rowSelection.size || this.isRowDeleted(rowID)) {
517517
this.selectRowById(rowID);
518518
return;
@@ -528,17 +528,17 @@ export class IgxGridSelectionService {
528528
this.emitRowSelectionEvent(newSelection, added, [], event);
529529
}
530530

531-
public areAllRowSelected(): boolean {
532-
if (!this.grid.data) {
531+
public areAllRowSelected(newSelection?): boolean {
532+
if (!this.grid.data && !newSelection) {
533533
return false;
534534
}
535-
if (this.allRowsSelected !== undefined) {
535+
if (this.allRowsSelected !== undefined && !newSelection) {
536536
return this.allRowsSelected;
537537
}
538-
539-
const dataItemsID = this.getRowIDs(this.allData);
540-
return this.allRowsSelected = Math.min(this.rowSelection.size, dataItemsID.length) > 0 &&
541-
new Set(Array.from(this.rowSelection.values()).concat(dataItemsID)).size === this.rowSelection.size;
538+
const selectedData = newSelection ? newSelection : [...this.rowSelection]
539+
const allData = this.getRowIDs(this.allData);
540+
const unSelectedRows = allData.filter(row => !selectedData.includes(row));
541+
return this.allRowsSelected = this.allData.length > 0 && unSelectedRows.length === 0;
542542
}
543543

544544
public hasSomeRowSelected(): boolean {
@@ -561,10 +561,11 @@ export class IgxGridSelectionService {
561561

562562
const args = {
563563
oldSelection: currSelection, newSelection,
564-
added, removed, event, cancel: false
564+
added, removed, event, cancel: false, allRowsSelected: this.areAllRowSelected(newSelection)
565565
};
566566
this.grid.rowSelectionChanging.emit(args);
567567
if (args.cancel) {
568+
this.clearHeaderCBState();
568569
return;
569570
}
570571
this.selectRowsWithNoEvent(args.newSelection, true);
@@ -578,14 +579,14 @@ export class IgxGridSelectionService {
578579
return rowIndex < 0 ? {} : this.grid.gridAPI.get_all_data(true)[rowIndex];
579580
}
580581

581-
public getRowIDs(data): Array<any> {
582-
return this.grid.primaryKey && data.length ? data.map(rec => rec[this.grid.primaryKey]) : data;
583-
}
584-
585582
public clearHeaderCBState(): void {
586583
this.allRowsSelected = undefined;
587584
}
588585

586+
public getRowIDs(data): Array<any> {
587+
return this.grid.primaryKey && data.length ? data.map(rec => rec[this.grid.primaryKey]) : data;
588+
}
589+
589590
/** Clear rowSelection and update checkbox state */
590591
public clearAllSelectedRows(): void {
591592
this.rowSelection.clear();

projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,7 @@ export class IgxTreeGridComponent extends IgxGridBaseDirective implements GridTy
10721072
parentData[this.childDataKey] = children;
10731073
}
10741074
this.selectionService.clearHeaderCBState();
1075-
this.pipeTrigger++;
1075+
this.pipeTrigger++;
10761076
if (this.rowSelection === GridSelectionMode.multipleCascade) {
10771077
// Force pipe triggering for building the data structure
10781078
this.cdr.detectChanges();

src/app/grid-remote-paging/grid-remote-paging.sample.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<div class="dark-grid">
22
<igx-grid igxPreventDocumentScroll #grid1 [data]="data | async" width="100%" height="540px" [batchEditing]="true"
3-
[pagingMode]="mode">
3+
[pagingMode]="mode" rowSelection="multiple">
44
<igx-column field="ID"></igx-column>
55
<igx-column field="ProductName"></igx-column>
66
<igx-column field="QuantityPerUnit"></igx-column>

src/app/grid-remote-paging/grid-remote-paging.sample.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export class GridRemotePagingSampleComponent implements OnInit, AfterViewInit, O
1717
public paging = true;
1818
public data: Observable<any[]>;
1919
public selectOptions = [5, 10, 15, 25, 50];
20+
public areAllRowsSelected: boolean = false;
2021

2122
private _perPage = 15;
2223
private _dataLengthSubscriber;
@@ -40,6 +41,19 @@ export class GridRemotePagingSampleComponent implements OnInit, AfterViewInit, O
4041
this.totalCount = data;
4142
this.grid1.isLoading = false;
4243
});
44+
45+
this.grid1.dataChanged.subscribe(() => {
46+
if (this.areAllRowsSelected) {
47+
this.grid1.selectAllRows();
48+
}
49+
});
50+
51+
this.grid1.rowSelectionChanging.subscribe((args) => {
52+
this.areAllRowsSelected = args.allRowsSelected;
53+
if (args.allRowsSelected) {
54+
this.grid1.selectAllRows();
55+
}
56+
});
4357
}
4458

4559
public ngOnDestroy() {
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<div class="dark-grid">
2-
<igx-grid batchEditing ='true' #grid1 [data]="remoteData | async" [height]="'500px'" [width]="'100%'" [autoGenerate]='true' (dataPreLoad)="handlePreLoad()" [clipboardOptions]="clipboardOptions"
3-
(sortingDone)="processData(true)" (columnInit)='onColumnInit($event)'>
2+
<igx-grid batchEditing ='true' #grid1 [data]="remoteData | async" [height]="'500px'" [width]="'100%'" [primaryKey]="'ProductID'" [autoGenerate]='true' (dataPreLoad)="handlePreLoad()" [clipboardOptions]="clipboardOptions"
3+
(sortingDone)="processData(true)" (columnInit)='onColumnInit($event)' rowSelection="multiple">
44
</igx-grid>
55
</div>

0 commit comments

Comments
 (0)