1

I have a form which contain a list of checkboxes and if one of them was checked an input form display.

This is my component.ts :

  coveragestypes : Array<ItemPolicyModel>=  [{id:'1', name :'type 1'},{id : '2',name :'type 2'},{id : '3',name :'type 3'},{id:'4',name:'type 4'}]
 policyForm = new FormGroup({
  coverages :new FormArray([]),
  coveragesValue:new FormArray([]),
 })
ngOnInit() { 
  this.names = this.coveragestypes.map(x => x.name)
  this.addCheckboxes();
}

addCheckboxes() {

this.names.forEach(() => this.coverageFormArray.push(new FormControl()));
this.names.forEach(() => this.coveragesValueFormArray.push(new FormControl('', Validators.pattern(/^-?(0|[1-9]\d*)?$/))));
 }
get coverageFormArray() {
return this.policyForm.controls.coverages as FormArray;
 }
get coveragesValueFormArray() {
  return this.policyForm.controls.coveragesValue as FormArray;
}

And this is my html :

  <div class="checkbox">
        <label formArrayName="coverages"
        *ngFor="let coverage of coverageFormArray.controls;let i = index; ">
              <input type="checkbox" kendoCheckBox [formControlName]="i" />
                {{names[i]}}
              <ng-container *ngIf="coverage.value">
                    <input type="text" [formControl]="policyForm.get('coveragesValue.'+i)">
              </ng-container>
        </label>
  </div>

It is saved like that when I console the policyForm value : coverages: (4) [true, true, false, false] coveragesValue: (4) ["123", "555", "", ""] or I want it to be saved in one form array like that : coverages : [{id : '1', name : 'type1', value : '123'},{id : '2', name : 'type2', value : '555'}]

Can anyone help me please !

hiba nebli
  • 107
  • 2
  • 18
  • https://stackoverflow.com/questions/63797930/get-multiple-checkbox-value-as-an-array-in-angular/63799360#63799360 – Eliseo Feb 02 '21 at 11:27

1 Answers1

1

One way to achieve the formArray.value giving the correct object array representation

coverageExample: Record<String,any> = {id : '1', name : 'type1', value : '123'};
coverageTypes: Record<String,any>[] = [coverageExample];

would be to represent these objects with a formArray of formGroups. Some formControls will only be used to store the object values.

// ...
addCheckboxes() {

    let formGroups: FormGroup[] = this.coveragestypes.map((coverage) => {
            return new FormGroup({
                    id: new FormControl(coverage.id),
                    name: new FormControl(coverage.name),
                    value: new FormControl('', Validators.pattern(/^-?(0|[1-9]\d*)?$/))
                    checked: new FormControl(false)});
        });
    this.coverageFormArray = new FormArray(formGroups);
}
// ...

with this structure coverages.value should return the object you want. And the markup would need to be updated as follows

<div class="checkbox">
    <div *ngFor="let coverage of coverageFormArray.controls;let i = index; ">
        <div [formGroup]="coverage">
            <input type="checkbox" kendoCheckBox [formControl]="coverage.controls.checked" />
    {{coverage.controls.name.value}}        
            <ng-container *ngIf="coverage.controls.checked.value">*
                Value:
                <input type="text" [formControl]="coverage.controls.value">
          </ng-container>
        </div>
    </div>
</div>
// ...

Edit: fixed some markup and added the stackblitz

https://stackblitz.com/edit/how-to-create-a-complex-form-control?file=src/app/app.component.ts

  • I need this formArray in a formGroup 'PolicyForm' so I added this to your code `policyForm = new FormGroup({ coverageFormArray : new FormArray(null)})` Then in the addcheckboxes method `this.policyForm.controls.coverageFormArray = new FormArray(formGroups)` But it gives me error `TypeError: Cannot read property 'forEach' of null` – hiba nebli Feb 02 '21 at 13:09
  • There's no use of the forEach method in the stackblitz linked above, maybe the issue is somewhere else in your code ? You could update the linked stackblitz with your problem constraints to help us better understand the issue – Simplicity's_Strength Feb 02 '21 at 13:24
  • Also please note that i used the addCheckboxes() method in the constructor, this prevents null formArray at init. if you receive the data later in async, you could init the array empty in constructor to avoid nulls. – Simplicity's_Strength Feb 02 '21 at 13:28
  • https://stackblitz.com/edit/how-to-create-a-complex-form-control-ermubs?embed=1&file=src/app/app.component.ts – hiba nebli Feb 02 '21 at 13:31
  • Ah yes you need to initialise with an empty array at line 28 coverageFormArray: new FormArray([]) – Simplicity's_Strength Feb 02 '21 at 13:35
  • Yes I tried it but it gives me this error `ERROR Error: Cannot read property 'controls' of undefined` – hiba nebli Feb 02 '21 at 13:37
  • https://stackblitz.com/edit/how-to-create-a-complex-form-control-policyedit?file=src/app/app.component.ts please take a look at these edits i made on the stackblitz above – Simplicity's_Strength Feb 02 '21 at 13:40
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/228166/discussion-between-hiba-nebli-and-simplicitys-strength). – hiba nebli Feb 02 '21 at 15:55