4

I've been struggling with reactive forms with checkboxes .

  1. If none of the items is selected , submit button should be disabled . This is done

  2. There's an option called "None of the above" . Selecting this should unselect all the selected items(if any) in the checkboxes

  3. Selecting back any item but 'None of the above' should unselect the 'None of the above'

HTML

<form [formGroup]="form" (ngSubmit)="submit()">
  <label formArrayName="orders" *ngFor="let order of form.controls.orders.controls; let i = index">
    <input type="checkbox" [formControlName]="i" (click)="onChange(orderData)">
    {{ordersData[i].name}}
  </label>
  <br>
  <button [disabled]="!form.valid">submit</button>
</form>

TS

  onChange(event) {
    console.log(event);
  }

You can find complete code related to this on StackBlitz.

Sudarshana Dayananda
  • 5,165
  • 2
  • 23
  • 45

3 Answers3

3

Hi try this stackblitz first https://stackblitz.com/edit/angular-nqggqr

  1. You have to remove None of the above option from your array and put it outside of *ngFor
  2. Use a variable for None of the above to make change when user change the check box <input type="checkbox" [checked]="uncheck" (change)="unCheckAll()" />
  3. In your .ts In unCheckAll() reset your form and all checkbox will be changed.
  4. In onChange() just set uncheck variable to false.

Everything is implemented in above stackblitz

Ali Wahab
  • 482
  • 6
  • 13
  • Hey @AliWahab Thanks . But clicking on "None of the above" should disable the submit Button . – Anusha Krishnamurthy Dec 07 '19 at 08:51
  • Hi @AnushaKrishnamurthy, I have update the stackblitz. Please check and review. There was a little issue in your code. You used `(click)` on input type check box. `change` event should be used when working with checkbox and select. I have modified the code please see the `onChange()` and `unCheckAll()` methods. Currently it is just enabling the button. Form is still invalid beacuse nothing is checked. If you want `nocheckbox` value in your form. We have to come up with a different approach. – Ali Wahab Dec 07 '19 at 09:17
0

You need to do simple change to onChange(event) method. You can do this easily using setValue and patchValue in Angular FormArray.

Pass formControlName to the onChange method as an argument. In your case it is index. Use setValue and patchValue to change values to the elements in the FormArray.

HTML

...
<input type="checkbox" [formControlName]="i" (click)="onChange(i)">
...

TS

  onChange(index) {
    if (index === 3)
      this.form.controls.orders.setValue([false, false, false, true]);
    else
      this.form.controls.orders.get('3').patchValue(false);
  }

StackBlitz Demo.

Sudarshana Dayananda
  • 5,165
  • 2
  • 23
  • 45
0

update your onChange function to take object of order data

onChange(event: any) {
const indexOfNone = this.ordersData.findIndex(function(item, i) {
  return item.name.toUpperCase() === "NONE OF THE ABOVE";
});

if (event.name.toUpperCase() == "NONE OF THE ABOVE") {
  this.arrays.controls.forEach(e => {
    e.setValue(false);
  });
  this.form.controls.orders.get(indexOfNone.toString()).patchValue(true);
} else
  this.form.controls.orders.get(indexOfNone.toString()).patchValue(false);

}

and also your html like so

 <input type="checkbox" [formControlName]="i" (click)="onChange(ordersData[i])" name="orders"  [value]="ordersData[i].name"  >
{{ordersData[i].name}}

feel free to take out the loop const indexOfNone = this.ordersData.findIndex(function(item, i) { return item.name.toUpperCase() === "NONE OF THE ABOVE"; }); to somewhere global perhaps if the value will not change after init time, that should minimize the performance cost as it doesn't need to loop everytime a checkbox value is changed.

Mike Araya
  • 155
  • 1
  • 11