i work with angular material table,my table contains a selection Model to handle the selected All and selected One and contains some columns and some rows. what i have now that i can select all or select one element and all is good, what i need is to handle the event Shift click as Excel to select the checkbox as a multiples rows. and when i select a collection in same time there checkbox will be selected and i have the possibility to uncheck one one i click on it.(i found this behaviour in ag grid table but i need that with mat table ) my Html code is like that : <ng-container matColumnDef="select"> <th mat-header-cell *matHeaderCellDef> <mat-checkbox id="allCheck" (change)="setAllChekedOrUnchecked($event)" [checked]="isAllElementSelected" [indeterminate]="iSsomeElementsSelected"> </mat-checkbox> </th> <td mat-cell *matCellDef="let row"> <mat-checkbox [checked]="row.complete" (click)="oneElementSelected($event, row)"> </mat-checkbox> </td> </ng-container> <ng-container matColumnDef="entityCode"> <th mat-header-cell *matHeaderCellDef>TOUTES</th> <td mat-cell *matCellDef="let element" style="cursor: pointer"> <span (click)="openConfirmationDialog(element)">{{ element.entityCode }}</span> </td> </ng-container>` my ts file : dataSource!: MatTableDataSource<any>; selection = new SelectionModel<Interclassement>(true, []); selectedElements: Interclassement[] = []; setAllChekedOrUnchecked($event: MatLegacyCheckboxChange) { this.dataSource.data.forEach(elt => { elt.complete = $event.checked; }); this.isAllElementSelected = $event.checked; if ($event.checked) { this.selection.select(...this.dataSource.data); } else { this.selection.clear(); } this.iSsomeElementsSelected = this.someElementsSelected(); } iSsomeElementsSelected: boolean = false; someElementsSelected() { return this.selection.selected.some(t => t.complete && !this.isAllElementSelected); } oneElementSelected($event: any, row: any) { if ($event.checked) { this.selection.select(row); } else { this.selection.deselect(row); } row.complete = $event.checked; this.isAllElementSelected = this.selection.selected.length === this.dataSource.data.length; this.iSsomeElementsSelected = this.someElementsSelected(); } // Shift+Click logic : but it doesn't work. lastSelectedId: number | null = null; getRowRange(idA: number, idB: number): any[] { const rows = this.dataSource.data; const startIndex = rows.findIndex(row => row.id === idA); const endIndex = rows.findIndex(row => row.id === idB); if (startIndex === -1 || endIndex === -1) { throw new Error('Invalid row range'); } const [from, to] = startIndex < endIndex ? [startIndex, endIndex] : [endIndex, startIndex]; return rows.slice(from, to + 1); } toggleSelection(event: MouseEvent, row: any) { if (event.shiftKey && this.lastSelectedId !== null) { const rowsToToggle = this.getRowRange(this.lastSelectedId, row.id); const shouldSelect = !this.selection.isSelected(rowsToToggle[0]); rowsToToggle.forEach(row => { if (shouldSelect) { this.selection.select(row); } else { this.selection.deselect(row); } }); } else { this.selection.toggle(row); } this.lastSelectedId = row.id; } Continue reading...