0

I have multiple checkbox arrays in my checkbox form. When user clicks select all button I need to select all checkbox.By using reactive forms and FormArray this is what I had tried:

Ts file

  get formReceivedSummons() {
    return this.form.get('receivedSummons') as FormArray;
  }

  formReceivedSummonsItems(i: number) {
    return (this.formReceivedSummons.controls[i].get('items')) as FormArray;
  }

  constructor(private inquiryStore: InquiryStoreService, private formBuilder: FormBuilder) { }

  ngOnInit() {
    this.form = this.formBuilder.group({
      receivedSummons: this.formBuilder.array([])
    });
    this.getReceivedSummons();
  }

  getReceivedSummons() {
    this.inquiryStore.summons$.subscribe(result => {
      this.receivedSummon = result;
      this.addCheckboxes();
    });
  }

  selectAllCheckbox() {
    this.formReceivedSummons.controls.map(value => value.setValue(true));
  }

  addCheckboxes() {
    this.formReceivedSummons.setValue([]);
    this.receivedSummon.data.items.map(x => {
      const group = this.formBuilder.group({
        header: [this.receivedSummon.header],
        items: this.formBuilder.array([], [minSelectedCheckboxes(1)])
      });
        (group.get('items') as FormArray).push(this.formBuilder.group({
          name: [x.itemNo],
          isChecked: [false, Validators.required]
        }));
      this.formReceivedSummons.push(group);
    });
  }

Html file

    <form [formGroup]="form" (ngSubmit)="submitSelectedCheckboxes()">
      <ng-container formArrayName="receivedSummons" *ngFor="let summon of formReceivedSummons.controls; let i = index">
        <ng-container [formGroup]="summon">
          <ng-container formArrayName="items" *ngFor="let item of formReceivedSummonsItems(i).controls; let j = index">
            <ng-container [formGroup]="item">
              <input type="checkbox" formControlName="isChecked"> {{item.value.name}}
            </ng-container>
          </ng-container>
        </ng-container>
      </ng-container>
      <br>
    </form>
  <button (click)="selectAllCheckbox()">SELECT ALL</button>

I got error when I'm try to select all:

Error: Must supply a value for form control with name: 'header'.

I could not figure out what the errors and could use some guidance and suggestion.

4
  • may I ask why you have several formarrays. Seems to me, that there is only one checkbox in each formarray according to your code. Why not have checkboxes in one array? Commented Sep 9, 2019 at 18:24
  • because my checkbox are based on object response I got, here stackblitz demo..stackblitz.com/edit/… Commented Sep 9, 2019 at 18:35
  • Yes, and there we can see that you have just one checkbox per formarray, also the header is duplicated. You should restructure your form. Commented Sep 9, 2019 at 18:37
  • can you show me on stackblitz please ? Commented Sep 9, 2019 at 18:40

1 Answer 1

1

Your current setup makes little sense, to have a formarray for each checkbox. You should stick all checkboxes in one formarray. Also the header formcontrol is duplicated everywhere. Instead change your code to have the header once, and the checkboxes in the receivedSummons formarray:

ngOnInit() {
  this.form = this.formBuilder.group({
    header: [''], // outside formarray
    receivedSummons: this.formBuilder.array([])
  });
  this.getReceivedSummons();
}

getReceivedSummons() {
  this.inquiryStore.summons$.subscribe(result => {
    this.receivedSummon = result;
    this.addCheckboxes();
    this.isShowResponse = true;
  });
}

addCheckboxes() {
  this.form.get('header').setValue(this.receivedSummon.header)
  this.receivedSummon.data.items.map(x => {
    this.formReceivedSummons.push(
      this.formBuilder.group({
        name: x.itemNo,
        isChecked: false
      }))
  });
}

Then make the changes in template, remove the inner formarray:

<form [formGroup]="form" (ngSubmit)="submitSelectedCheckboxes()">
  <ng-container formArrayName="receivedSummons" *ngFor="let summon of formReceivedSummons.controls; let i = index">
    <ng-container [formGroupName]="i">
      <input type="checkbox" formControlName="isChecked"> {{summon.value.name}}
    </ng-container>
  </ng-container>
</form>

Then finally the selectAll checkboxes, use map as you have, but access the isChecked form control:

selectAll() {
  this.formReceivedSummons.controls.map(value => value.get('isChecked').setValue(true));
}

Finally your forked STACKBLITZ

Sign up to request clarification or add additional context in comments.

4 Comments

did not realize I got duplicated header for each items..let say If I want to submit selected checkbox only how would I achieved this ? by filtering isChecked value ?
Yes, you can use filter to get the checked values :)
Im trying to filter but still got 2 item even I checked only one checkbox ..can suggest the solution ? stackblitz.com/edit/angular-udvmad?file=src/app/…
this.formReceivedSummons.value.filter(x => x.isChecked === true);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.