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;
}