Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mat-Table Selection only on current PageSize?

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));
  }
like image 843
IvanS95 Avatar asked Oct 17 '18 18:10

IvanS95


2 Answers

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}`;
  }
like image 66
curmil Avatar answered Oct 05 '22 12:10

curmil


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;
    }
  }
like image 21
IvanS95 Avatar answered Oct 05 '22 13:10

IvanS95