I'm building a table with pagination that handles some actions based on an array of selected checkboxes; I've the docs and as far a just selecting ALL rows of just a few individually everything's good;
The scenario I'm trying to get to to work is the following: If my PageSize
on my paginator
is "10", and I click the masterToggle
to select "all" rows, I want that to select all the rows on the current page, nothing more, so that would be the 10 rows that are being displayed with the current PageSize
, however, this selects the whole dataSource
of the table which is around 300 records.
Is there a way to make the masterToggle
select only the rows that are displayed based on the PageSize? Then If I change the PageSize
to 20 only the first 10 would stay selected.
This is my code.
/** Whether the number of selected elements matches the total number of rows. */
isAllSelected() {
const numSelected = this.selection.selected.length;
const numRows = this.dataSource.data.length;
return numSelected === numRows;
}
/** Selects all rows if they are not all selected; otherwise clear selection. */
masterToggle() {
this.isAllSelected() ?
this.selection.clear() :
this.dataSource.data.forEach(row => this.selection.select(row));
}
If you're using sorting, paginating, and filtering:
HTML column:
<mat-checkbox (change)="$event ? masterToggle($event) : null"
[checked]="selection.hasValue() && isEntirePageSelected()"
[indeterminate]="selection.hasValue() && !isEntirePageSelected()"
[aria-label]="checkboxLabel()"></mat-checkbox>
Component:
getPageData() {
return this.dataSource._pageData(this.dataSource._orderData(this.dataSource.filteredData));
}
isEntirePageSelected() {
return this.getPageData().every((row) => this.selection.isSelected(row));
}
masterToggle(checkboxChange: MatCheckboxChange) {
this.isEntirePageSelected() ?
this.selection.deselect(...this.getPageData()) :
this.selection.select(...this.getPageData());
}
checkboxLabel(row): string {
if (!row) {
return `${this.isEntirePageSelected() ? 'select' : 'deselect'} all`;
}
return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.id + 1}`;
}
Was able to get it to work by removin the last line on the masterToggle()
method, and replacing that with a custom function that loops through the PageSize of the paginator and calls the select
method of the SelectionModel
for each alert it finds; I also changed the isAllSelected
method to compare the PageSize
and the selected lenght
instead of the whole dataSource
.
/** Whether the number of selected elements matches the total number of rows. */
isAllSelected() {
const numSelected = this.selection.selected.length;
const page = this.dataSource.paginator.pageSize;
return numSelected === page;
}
/** Selects all rows if they are not all selected; otherwise clear selection. */
masterToggle() {
this.isAllSelected() ?
this.selection.clear() : this.selectRows();
}
selectRows() {
for (let index = 0; index < this.dataSource.paginator.pageSize; index++) {
this.selection.select(this.dataSource.data[index]);
this.selectionAmount = this.selection.selected.length;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With