简体   繁体   中英

Select All checkbox Angular material 5 | Gmail style if selecting individual it will also select

I need to create a select all functionality in angular material, I am sharing code below which is partially working.

<section *ngFor="let ing of pizzaIng; let i = index" class="example-section">
  <mat-checkbox (change)="selectChildren()"
     [(ngModel)]="ing.checked">
    {{ing.name}}
  </mat-checkbox>
</section>
  <mat-checkbox (change)="updateCheck()"
      class="example-margin"
      [(ngModel)]="selectAll">
    Select All
  </mat-checkbox>

.ts file

export class CheckboxConfigurableExample {
    pizzaIng: any;
    selectAll = false;

    constructor() {
        this.pizzaIng = [{
                name: "Pepperoni",
                checked: false
            },
            {
                name: "Sasuage",
                checked: true
            },
            {
                name: "Mushrooms",
                checked: false
            }
        ];
    }


    selectChildren() {

        for (var i = 0; i < this.pizzaIng.length; i++) {
            if (this.pizzaIng[i].checked === true) {
                return this.selectAll = true;
            } else {
                return this.selectAll = false;
            }

        }
    }




    updateCheck() {
        console.log(this.selectAll);
        if (this.selectAll === true) {
            this.pizzaIng.map((pizza) => {
                pizza.checked = true;
            });

        } else {
            this.pizzaIng.map((pizza) => {
                pizza.checked = false;
            });
        }
    }
}  

select all/deselect is working but the individual selection is not working properly, if selected the first one it is selecting the select all but it should work when selected all individual, Please help.

Just change your selectchildren to this, using every will check all the checkboxes are checked, and it should work fine. You already have a checked property which has the values as checked or not, you can check if all entries are checked then youc an enable the selectAll, else disable it.

  selectChildren() {    
    if (this.pizzaIng.every(a => a.checked)) {
      this.selectAll = true;
    } else {
      this.selectAll = false;
    }
  }

Here is the demo

HTML

<mat-table [dataSource]="dataSource">
<ng-container matColumnDef="select">
    <mat-header-cell *matHeaderCellDef class="customMatCheckContainer">
        <mat-checkbox (change)="$event ? masterToggle() : null"
                    [checked]="selection.hasValue() && isAllSelected()"
                    [indeterminate]="selection.hasValue() && !isAllSelected()">
        </mat-checkbox>
    </mat-header-cell>
    <mat-cell *matCellDef="let row" class="customMatCheckContainer">
        <mat-checkbox (click)="$event.stopPropagation()"
                    (change)="$event ? selection.toggle(row) : null"
                    [checked]="selection.isSelected(row)">
        </mat-checkbox>
    </mat-cell>
</ng-container>

<ng-container matColumnDef="displayName">
    <mat-header-cell *matHeaderCellDef> Display Name </mat-header-cell>
    <mat-cell *matCellDef="let row"> {{row.displayName}} </mat-cell>
</ng-container>

<ng-container matColumnDef="userEmail">
    <mat-header-cell *matHeaderCellDef> Email </mat-header-cell>
    <mat-cell *matCellDef="let row"> {{row.email}} </mat-cell>
</ng-container>

<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;" (click)="selection.toggle(row)"></mat-row>

TS

Import the following modules in your module file: MatTableModule, MatCheckboxModule, MatSelectModule

You will get all selected entries in 'selection' variable.

import { MatSort, MatTableDataSource } from '@angular/material';
import { SelectionModel } from '@angular/cdk/collections';

displayedColumns = ['select', 'displayName', 'userEmail'];
dataSource: MatTableDataSource<any>;
selection = new SelectionModel<Element>(true, []);

constructor() {
    this.dataSource = new MatTableDataSource(this.data);
}

public isAllSelected() {
    const numSelected = this.selection.selected.length;
    const numRows = this.dataSource.data.length;
    return numSelected === numRows;
}

public masterToggle() {
    this.isAllSelected() ? this.selection.clear() : this.dataSource.data.forEach(row => this.selection.select(row));
}

more short solution is in your html , no need to add if and else conditions

<section *ngFor="let ing of pizzaIng; let i = index" class="example-section">
  <mat-checkbox
     [(ngModel)]="ing.checked">
    {{ing.name}}
  </mat-checkbox>
</section>
  <mat-checkbox 
      class="example-margin"
      [checked]="isAllChecked()" (change)="checkAll()"
      [(ngModel)]="selectAll">
    Select All
  </mat-checkbox>

in yout .ts

isAllChecked() {
    return this.pizzaIng.every(obj => obj.checked);
  }

  checkAll() {
     this.pizzaIng.forEach(obj => obj.checked = this.selectAll);
  }

here is a link of working demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM