Nate May
Nate May

Reputation: 4072

How can I add a formGroup to another formGroup

I found this answer which shows how I can add form controls to the parent form:

Reuse components in angular2 model driven forms

but I would like to be able to add new formGroups to different areas of the page like this.

<form [formGroup]="myForm">
  <!--... other inputs -->
  <md-tab-group formGroupName="nutrition">
    <md-tab formGroupName="calories">
      <template md-stretch-tabs="always" md-tab-label>Calories</template>
      <template md-tab-content>
        <calories></calories> <!-- I want to add controll groups like this-->
      </template>
    </md-tab>
    <md-tab formGroupName="carbs">
      <template md-stretch-tabs="always" md-tab-label>Carbs</template>
      <template md-tab-content>
        <carbs></carbs>
      </template>
    </md-tab>
  </md-tab-group>
</form>

the whole form model should look like this:

{
   name: '',
   nutrition:{
      calories: {
        total: ''
        // more
      },
      carbs: {
        total: ''
        // more
      }
}

I have been able to add the nutrition formGroup like this:

<nutrition [parentForm]="myForm"></nutrition>

import { Component, OnInit, Input } from '@angular/core';
import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'nutrition',
  template: `
  <div [formGroup]="parentForm"></div>
  `
})
export class NutritionComponent implements OnInit {

    @Input() parentForm: FormGroup;

    nutritionGroup: FormGroup;

    constructor(private _fb: FormBuilder) {
    }

    ngOnInit() {
      this.nutritionGroup = new FormGroup({
        blank: new FormControl('', Validators.required)
      });
      this.parentForm.addControl('nutrition', this.nutritionGroup);
    }
}

but I can't figure out how to pass in the nutrition form group to the calories formGroup like this:

<calories [parentControl]="nutrition"></calories>

import { Component, OnInit, Input } from '@angular/core';
import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'calories',
  template: ``
})
export class CaloriesComponent implements OnInit {

  @Input() parentControl: FormGroup;
  caloriesForm: FormGroup;

  constructor(private _fb: FormBuilder) {  }
  ngOnInit(){
    this.caloriesForm = new FormGroup({
        blank: new FormControl('', Validators.required)
      });

    this.parentControl.addControl('calories', this.caloriesForm);
  }
}

Can this be done?

Upvotes: 6

Views: 15575

Answers (1)

William
William

Reputation: 1030

If you are (or anyone is) still interested, after adding the control to your parentControl, you need to emit it back to the parent component, so it can be updated.

import { Output, EventEmitter } from '@angular/core';

@Output() onFormGroupChange: EventEmitter<FormGroup> = new EventEmitter<FormGroup>();

this.parentControl.addControl('calories', this.caloriesForm);
this.onFormGroupChange.emit(this.parentControl);

On parent html element, you need to reasign it back to parentControl: (onFormGroupChange)="setParentControl($event)"

And the method on your ts

public setParentControl(formGroup: FormGroup) {
    this.myForm = formGroup;
}

Then you will have the control in your FormGroup myForm and do whatever you like, on your parent element: console.log(this.myForm.controls['calories'])

Haven't included all the code, but only what you need :)

Upvotes: 8

Related Questions