Drew13
Drew13

Reputation: 1371

Uncheck all check boxes created with *ngFor

I have a table which has a column that contains a checkbox for each row using *ngFor. Upon clicking a button I want to uncheck all the checkboxes. I tried using [(ngModel)]="boxChecked" for each checkbox and setting that value to false in the method that my button click calls but that results in each checkbox being checked whenever I check only one of them. This does uncheck all checkboxes upon button click but I still need to be able to individually check the checkboxes.

<ng-template pTemplate="body" let-sub let-expanded="expanded" let-columns="columns">
      <tr [pSelectableRow]="subcontract">
        <td *ngFor="let col of columns" [ngSwitch]="true" style="text-align: center">
          <div *ngSwitchCase="col.export" ><input type="checkbox" (change)="checked($event, sub)" [(ngModel)]="boxChecked"></div>
        </td>
      </tr>
</ng-template>
<button type="button"(click)="reset(table)"></button>

ts:

//I send the ID of the table to this method.
reset(table) {
    table.reset();
    this.boxChecked = false;
}

So far in my research I don't see that there is a get(index i)(to get a single row of the index parameter) method of some sort on my table. Then I could easily just loop through my table and set the checkbox of each iteration(row) to false.

Upvotes: 10

Views: 23457

Answers (3)

Abolfazl Roshanzamir
Abolfazl Roshanzamir

Reputation: 14892

You can use ngModel two way binding to an array:

Preview : enter image description here

define an interface

export interface SelectListItem {
 value: string;
 text: string;
 checked: boolean;
}

fill out a list

export class AppComponent  {
 name = 'Angular 6';

 selectList: SelectListItem[] = [];

 ngOnInit(): void {
  this.selectList.push({ value: '1', text: 'item 1', checked: false });
  this.selectList.push({ value: '2', text: 'item 2', checked: false });
  this.selectList.push({ value: '3', text: 'item 3', checked: true });
  this.selectList.push({ value: '4', text: 'item 4', checked: true });
  this.selectList.push({ value: '5', text: 'item 5', checked: true });
  this.selectList.push({ value: '6', text: 'item 6', checked: false });
 }

 // get list of selected Items
 getSelectedItem() {
   return this.selectList.filter(item => item.checked === true);
 }

// reset list
resetCheckBox() {
 this.selectList.forEach(item => {
   const foundIndex = this.selectList.findIndex(x => x.value === item.value);
   item.checked = false;
   this.selectList[foundIndex] = item;
 });
}

}

and finally in your component.html :

<table class="table">
    <thead>
        <tr>
            <th>
                <input type="button" value="Unchecked All Checkboxes" (click)="resetCheckBox()" class="btn btn-sm btn-primary" />
            </th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let item of selectList; let i=index;">
            <td>
                <input class="form-check-input" name="off" type="checkbox" [(ngModel)]="item.checked">
                <label class="form-check-label">
                  {{item.text}}
                </label>
            </td>
        </tr>
    </tbody>
</table>
<h4>
    Selected Items:
</h4>
<ul>
    <li *ngFor="let item of getSelectedItem()">
        {{item.text}}
    </li>
</ul>

Stackblitz Here

Upvotes: 0

Patrick T
Patrick T

Reputation: 1

Here is a way to do it in Angular 7 using ngModel two way binding to an array. I'm using mat-checkbox, but it should work the same if using native 'input type="checkbox"'.

template:

<div *ngFor="let item of myitems; index as i; ">

    <mat-checkbox [(ngModel)]="checkedarray[i]"></mat-checkbox>

    < your content >

</div>

typescript:

checkedarray: boolean[];

ngOnInit() { 
    this.checkedarray = [];
...
}

clearSelected() {
    this.checkedarray = [];
}

That's it. If you want to do something when a checkbox is changed, you can add an event function like in the following: If id= is not present, Angular will generate one automatically.

template:

<div *ngFor="let item of myitems; index as i; ">

    <mat-checkbox [(ngModel)]="checkedarray[i]" id={{item.id}}  
     (change)="selectItem($event)"> </mat-checkbox>
</div>

typescript:

selectItem(event) {    

    let id = event.source.id;
    let checked = event.checked;

    ... do whatever
}

You can find details on mat-checkbox here:

https://material.angular.io/components/checkbox/overview

Upvotes: 0

Martin Parenteau
Martin Parenteau

Reputation: 73761

Since the check boxes are not bound to a property (which could be reset to uncheck the box), you can use a template reference variable (e.g. #checkboxes):

<input #checkboxes type="checkbox" ...>
...
<button type="button" (click)="uncheckAll()"></button>

to retrieve the check boxes with ViewChildren in the code and uncheck each one:

@ViewChildren("checkboxes") checkboxes: QueryList<ElementRef>;

uncheckAll() {
  this.checkboxes.forEach((element) => {
    element.nativeElement.checked = false;
  });
}

See this stackblitz for a demo.

Upvotes: 24

Related Questions