Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular + Material - How to handle multiple checkboxes with formgroup

Tags:

I have a list of interests i am getting from the backend. I want a user to be able to select the interests they want. I will store only the interests they checked in the DB and pre-populate when they load the page. But first i need to get these interests the user has selected.

interest.component.ts

export class InterestsComponent implements OnInit {    interestFormGroup : FormGroup   interests:any;   selected: any;     constructor(public interestService: InterestService, private formBuilder: FormBuilder,   ) { }    ngOnInit() {      this.interestFormGroup = this.formBuilder.group({       interests: this.formBuilder.array([])     });       this.interestService.all().subscribe((res) => {        this.interests = res;      });    }    change() {     console.log(this.interestFormGroup.value);   }  } 

interest.component.html

<div id="interest">      <div class="interest-list">          <form [formGroup]="interestFormGroup">             <div *ngFor="let interest of interests" >                 <mat-checkbox class="example-margin" formNameArray="interests" (change)="change()">{{interest}}</mat-checkbox>             </div>         </form>      </div>  </div> 

In my console.log on the change event it shows there is no values being added to the interests array within the interestFormGroup. Even tho the checkboxes are checked.

like image 429
Kay Avatar asked Oct 14 '17 20:10

Kay


People also ask

How does angular handle multiple checkboxes?

The MultiSelect has built-in support to select multiple values through checkbox, when mode property set as CheckBox . To use checkbox, inject the CheckBoxSelection module in the MultiSelect.

What is the use of FormGroup in angular?

A FormGroup aggregates the values of each child FormControl into one object, with each control name as the key. It calculates its status by reducing the status values of its children. For example, if one of the controls in a group is invalid, the entire group becomes invalid.

How do you make a checkbox readonly in angular 8?

If checkbox will be checked then ng-readonly will get TRUE value and TextBox will be converted into Read-Only TextBox. If checkbox will be unchecked then ng-readonly will get FALSE value and Read-Only TextBox will be converted into again Read-Write textbox.


1 Answers

You should add controls to FormArray manually like:

this.interests = res; const formArray = this.interestFormGroup.get('interests') as FormArray; this.interests.forEach(x => formArray.push(new FormControl(false))); 

then change template as follows:

<form [formGroup]="interestFormGroup" (ngSubmit)="submit()">    <ng-container formArrayName="interests">       <div *ngFor="let interest of interests; let i = index" >          <mat-checkbox class="example-margin" [formControlName]="i">            {{interest}}          </mat-checkbox>       </div>    </ng-container>    <button>Submit</button> </form> 

And when you will submit form you need to transform FormArray values to your desired result:

submit() {   const result = Object.assign({},      this.interestFormGroup.value, {        interests: this.interests         .filter((x, i) => !!this.interestFormGroup.value.interests[i])});    console.log(result); } 

Alternative solution is listen change event and manually add and remove value to FormArray:

<div *ngFor="let interest of interests; let i = index" >    <mat-checkbox class="example-margin"                  (change)="onChange($event)" [value]="interest">{{interest}}</mat-checkbox> </div>  onChange(event) {   const interests = <FormArray>this.interestFormGroup.get('interests') as FormArray;    if(event.checked) {     interests.push(new FormControl(event.source.value))   } else {     const i = interests.controls.findIndex(x => x.value === event.source.value);     interests.removeAt(i);   } } 

Stackblitz example

like image 76
yurzui Avatar answered Oct 22 '22 08:10

yurzui