23

I have multiple checkboxes and a button that has to be enabled only if at least one checkbox is selected

<input type="checkbox">VALUE1
<input type="checkbox">VALUE2
<input type="checkbox">VALUE3
<input type="checkbox">VALUE4
<button>Proceed</button>

How is this achieved using Angular2.

P.S: found similar questions but not using Angular2.

Khaled
  • 8,255
  • 11
  • 35
  • 56

4 Answers4

44

One way is to use ngModel on each checkbox, then control the button's disabled property via a method that examines each checkbox model state:

@Component({
  template: `
    <label *ngFor="let cb of checkboxes">
      <input type="checkbox" [(ngModel)]="cb.state">{{cb.label}}
    </label>
    <p><button [disabled]="buttonState()">button</button>
  `
})
class App {
  checkboxes = [{label: 'one'},{label: 'two'}];
  constructor() {}
  buttonState() {
    return !this.checkboxes.some(_ => _.state);
  }
}

Plunker

Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
  • 1
    Appreciate the answer given. Any idea why the buttonState function is triggered multiple times? and how to avoid triggering multiple times? – Gopinath Shiva Dec 09 '16 at 08:12
  • Expression interpolation is done each time Angular sees fit (something has happened in the component and Angular started its change detection algorithm to update 2way bound variables) – Michal Boska Dec 12 '16 at 09:59
  • How would you do this only if ALL checkboes is selecred? – Harry Jan 26 '17 at 09:50
  • @Harry, `return !this.checkboxes.every(_ => _.state);` – Mark Rajcok Jan 27 '17 at 16:07
  • @MarkRajcok Getting error for using this line `return !this.checkboxes.some(_ => _.state);` – Hema Jul 05 '17 at 05:29
  • my problem to this solution is that you are creating the checkboxes dynamically using ngFor and by declaring the `checkboxes` variable in typeScript. But in the problem checkboxes are created in a static way using normal html – Tk1993 Sep 15 '17 at 07:44
9

Use the propertie [disable] as:

<input type="checkbox" [(ng-model)]="disableButton1"> VALUE1
<input type="checkbox" [(ng-model)]="disableButton2"> VALUE1
<input type="checkbox" [(ng-model)]="disableButton3"> VALUE1
<input type="checkbox" [(ng-model)]="disableButton4"> VALUE1
<button type="button" [disabled]="disableButton || disableButton2">Submit</button>
Emir Marques
  • 2,603
  • 2
  • 16
  • 22
  • Thank you, but although that it works, with multiple checkboxes, it ends up selecting all if one is selected – Khaled Dec 07 '15 at 19:00
  • 1
    Update my example. Look now – Emir Marques Dec 07 '15 at 19:07
  • 2
    This works perfectly in the case of a static code, but when checkboxes are being created dynamically, say using `*ng-for` perhaps only option is using a Boolean variable assigned based on the count of selected checkboxes. – Khaled Dec 07 '15 at 19:41
4

You can perform any action by using $event in change event of checkbox.

Sample:

HTML

<input type="checkbox" (change)="changeEvent($event)" />
<button [disabled]="toogleBool">button</button>

TS

 toggleBool: boolean=true;

 changeEvent(event) {
        if (event.target.checked) {
            this.toggleBool= false;
        }
        else {
            this.toggleBool= true;
        }
    }
Tk1993
  • 501
  • 8
  • 21
2

I faced same issue in my project and i solved it.

sample:

HTML

<table class="table">
<thead>
    <tr>
        <th>Select</th>
        <th>Name</th>
    </tr>
</thead>
<tbody>
    <tr *ngFor="let item of items">
        <td><input type="checkbox" [(ngModel)]="item.chosen"></td>
        <td>{{item.name}}</td>
    </tr>
</tbody>
</table>
<button [disabled]="noneSelcted()">OK</button>

TS

import {Componnet} from '@angular/core'

@Componnet({
    selector: 'my-test',
    templateUrl: 'app/home/test.component.html'
})

export class TestComponent{
    items = [
        { name: 'user1', chosen: false},
        { name: 'user2', chosen: false},
        { name: 'user3', chosen: false},
    ];

    noneSelected(){
        return !this.items.some(item => item.chosen);
    }
}
Neel Patel
  • 2,028
  • 18
  • 17