material angular select all checkbox

Issue

I’m trying to implement select all checkbox on angular material. When user click on specifc checkbox (item), master checkbox should show Indeterminate and turn to checked if all checkboxes are selected. Currently I’m having some weird behaviour. Can anyone let me know where I made mistake? Here is stackblitz.
Here is my sample code:

app.html

<fieldset class="demo-fieldset">
  <div>
    <mat-checkbox aria-label="Select All" [checked]="isChecked(selected3, itemsObject)" [indeterminate]="isIndeterminate(selected3, itemsObject)" (click)="toggleAll(selected3, itemsObject)">
      Select All list of user (Array of objects) {{isChecked(selected3, itemsObject)}}
    </mat-checkbox>
  </div>
  <div class="demo-select-all-checkboxes" *ngFor="let item of itemsObject">
    <mat-checkbox [checked]="exists(item, selected3)" (click)="toggle(item, selected3)">
      {{ item.val }}
    </mat-checkbox>
    {{exists(item, selected3)}}

  </div>
</fieldset>

app.ts

import {
  Component
} from '@angular/core';

@Component({
  selector: 'app',
  templateUrl: 'app.html',
  styleUrls: ['app.css'],
})
export class CheckboxConfigurableExample {
  itemsObject = [{
    id: 1,
    val: 'john'
  }, {
    id: 2,
    val: 'jane'
  }];
  selected3 = [];

  toggle(item, list) {
    var idx = list.indexOf(item);
    if (idx > -1) {
      list.splice(idx, 1);
    } else {
      list.push(item);
    }
  }

  exists(item, list) {
    return list.indexOf(item) > -1;
  };

  isIndeterminate(x, t) {
    return (x.length !== 0 && x.length !== t.length);
  };

  isChecked(x, t) {
    return x.length === t.length;
  };

  toggleAll(x, t) {
    var l1 = x.length,
      l2 = t.length;
    if (l1 === l2) {
      x.splice(0, l1);
    } else if (l1 === 0 || l1 > 0) {
      //First we need to empty array, because we are using push to fill in array
      x.splice(0, l2);
      t.forEach(y => x.push(y));
    }
  };
}

Here is my stackblitz

Solution

Try this code:

Component:

import {Component} from '@angular/core';
import {

  MatCheckboxChange
} from '@angular/material';

/**
 * @title Configurable checkbox
 */
@Component({
  selector: 'checkbox-configurable-example',
  templateUrl: 'checkbox-configurable-example.html',
  styleUrls: ['checkbox-configurable-example.css'],
})
export class CheckboxConfigurableExample {
  itemsObject = [{
    id: 1,
    val: 'john'
  }, {
    id: 2,
    val: 'jane'
  }];
  selected3 = [];

  toggle(item,event: MatCheckboxChange) {
     if (event.checked) {
      this.selected3.push(item);
    } else {
      const index = this.selected3.indexOf(item);
      if (index >= 0) {
        this.selected3.splice(index, 1);
      }
    }
   console.log(item + "<>", event.checked);
  }

  exists(item) {
    return this.selected3.indexOf(item) > -1;
  };

  isIndeterminate() {
    return (this.selected3.length > 0 && !this.isChecked());
  };

  isChecked() {
    return this.selected3.length === this.itemsObject.length;
  };



  toggleAll(event: MatCheckboxChange) { 

    if ( event.checked ) {

       this.itemsObject.forEach(row => {
          // console.log('checked row', row);
          this.selected3.push(row)
          });

        // console.log('checked here');
    } else {
      // console.log('checked false');
       this.selected3.length = 0 ;
    }
}
}

Template:

<fieldset class="demo-fieldset">
  <div>
     <mat-checkbox aria-label="Select All" [checked]="isChecked()" [indeterminate]="isIndeterminate()" (change)="$event ? toggleAll($event) : null">
      Select All list of user (Array of objects) {{isChecked(selected3)}}
    </mat-checkbox>
  </div>
  <div class="demo-select-all-checkboxes" *ngFor="let item of itemsObject">
    <mat-checkbox (click)="$event.stopPropagation()"
                    (change)="$event ? toggle(item, $event) : null"
                    [checked]="exists(item)">
      {{ item.val }}
    </mat-checkbox>
    {{exists(item)}}

  </div>
</fieldset>

Answered By – Ajay Barokar

Answer Checked By – Mary Flores (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.