4

How to create form with nesting fields, i know about formArray in angular2 RC but am bit confused how to use it correctly ? let suppose i have an form like this

// Main Form with formArray named as `global_modifier`
this.myForm = this._fb.group({
  .......
  name: ['', []],
  global_modifier: this._fb.array([
    this.initGlobalModifiers()
  ])
  ....
});


removeModifier(i: number) {
  const control = <FormArray>this.myForm.controls['global_modifier'];
  control.removeAt(i);
}

addModifier() {
  const control = <FormArray>this.myForm.controls['global_modifier'];
  control.push(this.initGlobalModifiers());
}

/*global_modifier function having nested fields named `items` .....*/
initGlobalModifiers() {
  return this._fb.group({
  .....
    modifier_title: ['', []],
    items: this._fb.array([
      this.initItems()
    ])
    .........
  });
}


removeItem(i: number) {
  const control = <FormArray>this.myForm.controls['items'];
  control.removeAt(i);
}

addItem() {
  const control = <FormArray>this.myForm.controls['items'];
  control.push(this.initItems());
}

// items intilization
initItems() {
  return this._fb.group({
    item_title: ['', []],
    item_price: ['', []]
  });
}

now i am confused how to use this form in the html ??

i am trying this but did't work as expected..

<form [formGroup]="myForm" novalidate>
  <input type="text" placeholder="name" formControlName="name" maxlength="50">
  <div formArrayName="global_modifier" *ngFor="let cont of myForm.controls.global_modifier.controls; let i=index, let fst=first">
    <div [formGroupName]="i">
      <input type="text" placeholder="modifier_title" formControlName="modifier_title" maxlength="50">
      <button *ngIf="fst" [ngClass]="{'inputAddButton ':fst}" (click)="addModifier(i)" type="button">
        <i class="fa fa-plus fa-white" aria-hidden="true"></i>
      </button>
      <button *ngIf="!fst" [ngClass]="{'inputDeleteButton ':!fst}" (click)="removeModifier(i)">
        <i class="fa fa-trash-o fa-white" aria-hidden="true"></i>
      </button>

      <!--block For form mlutiple entrys-------------------->
      <div formArrayName="items">
        <div *ngFor="let items of cont.items; let item_index=index, let fst=first">
          <div [formGroupName]="i">
            <div style="margin-bottom:10px">
                     ............... NOTHING dISPLAY HERE ???
            </div>
          </div>
        </div>
      </div>
      <!--block For form mlutiple entrys---=------------>
      <br>
    </div>
  </div>
</form>

whats the error in my code ? or anyone having working example of nested forms in angular2 ?

2 Answers 2

6

Check this example that worked for me until rc4 (didn't check in newer versions):

form markup

  ngOnInit() {
    this.myForm = this.formBuilder.group({
    'loginCredentials': this.formBuilder.group({
    'login': ['', Validators.required],
    'email': ['',  [Validators.required, customValidator]],
    'password': ['',  Validators.required]
   }),
    'hobbies': this.formBuilder.array([
      this.formBuilder.group({
        'hobby': ['', Validators.required]
      })
    ])
  });
}

removeHobby(index: number){
    (<FormArray>this.myForm.find('hobbies')).removeAt(index);
  }

  onAddHobby() {
    (<FormArray>this.myForm.find('hobbies')).push(new FormGroup({
      'hobby': new FormControl('', Validators.required)
    }))
  }

html markup

<h3>Register page</h3>
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
  <div formGroupName="loginCredentials">
    <div class="form-group">
      <div>
        <label for="login">Login</label>
        <input  id="login" type="text" class="form-control" formControlName="login">
  </div>
  <div>
    <label for="email">Email</label>
    <input  id="email" type="text" class="form-control"  formControlName="email">
  </div>
  <div>
    <label for="password">Password</label>
    <input  id="password" type="text" class="form-control"  formControlName="password">
      </div>
    </div>
  </div>
  <div class="row" >
    <div  formGroupName="hobbies">
      <div class="form-group">
        <label>Hobbies array:</label>
        <div  *ngFor="let hobby of myForm.find('hobbies').controls; let i = index">
          <div formGroupName="{{i}}">
            <input id="hobby_{{i}}" type="text" class="form-control"  formControlName="hobby">
            <button *ngIf="myForm.find('hobbies').length > 1" (click)="removeHobby(i)">x</button>
          </div>
        </div>
        <button (click)="onAddHobby()">Add hobby</button>
      </div>
    </div>
  </div>
  <button type="submit" [disabled]="!myForm.valid">Submit</button>
</form>

Remarks

this.myForm = this.formBuilder.group

creates a form object with user's configuration and assigns it to this.myForm variable.


'loginCredentials': this.formBuilder.group

method creates a group of controls which consist of a formControlName eg. login and value ['', Validators.required], where the first parameter is the initial value of the form input and the secons is a validator or an array of validators as in 'email': ['', [Validators.required, customValidator]],.


'hobbies': this.formBuilder.array

Creates an array of groups where the index of the group is formGroupName in the array and is accessed like :

<div *ngFor="let hobby of myForm.find('hobbies').controls; let i = index">
<div formGroupName="{{i}}">...</div>
</div>

onAddHobby() {
(<FormArray>this.myForm.find('hobbies')).push(new FormGroup({
'hobby': new FormControl('', Validators.required)
}))
}

this sample method adds new formGroup to the array. Currently accessing requires specifing the type of control we want to access, in this example this type is : <FormArray>


removeHobby(index: number){
(<FormArray>this.myForm.find('hobbies')).removeAt(index);
}

same rules as above apply to removing a specific form control from the array

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

6 Comments

thanks but i am looking for nested from upto 3 level nesting
Then you have to continue the same way as first nesting :)
if that way is possible than why i had post this question :p
I never tried this sort of 3 level nesting, so I can be wrong but I guess it should work after some tweaking. I will play around with it when I have some time in the evening :)
@MatWaligora Did you figure out a 3 level nesting?
|
3

Nested Form with nested ARRAY

Plunker : https://plnkr.co/edit/sUjE1ULYhfDHLNBw2sRv?p=info Scotch.IO : https://scotch.io/tutorials/how-to-build-nested-model-driven-forms-in-angular-2

I think your error is in

addModifier() {
  const control = <FormArray>this.myForm.controls['global_modifier'];
  control.push(this.initGlobalModifiers());
}

you should push to your Form/FormGroup object not to control. See the PLUNKER to see the working example.

correct adding method :

  addAddress() {
        const control = <FormArray>this.myForm.controls['addresses'];
        control.push(this.initAddress());
    }

Nested Form with nested OBJECTS

 <form [formGroup]="myForm">
          <div formGroupName="address">
          <fieldset class="form-group">
                  <label>Street</label>
                  <input name="ulica" formControlName="street">
                  <label>City</label>
                  <input name="miasto" formControlName="city">
          </fieldset>
                      <label>Corresponding Address</label>
                      <fieldset class="form-group" formGroupName="correspondingAddress">
                         <label>Street</label>
                         <input name="ulica" formControlName="steet">
                         <label>City</label>
                         <input name="miasto" formControlName="city">
                      </fieldset>
           </div>
            </form>

...

 ngOnInit() {
    this.myForm = this._fb.group({
      address: this._fb.group({
        street : [''],
        city: [''],
        correspondingAddress: this._fb.group({
          street : [''],
          city: ['']
        })
      })
    });
  }

4 Comments

i was talking about formArray but still thanks for your answer
You have formArray example in my post. I find narrowing the nested forms term to only formArray misleading, because inner formGroup is an example of nested form too. I will edit my post an push formArray to the top. Did you manage to solve your problem?
@jmachnik, do you know if it's possible to use nested formArray? I mean inside address for example, if I have can another formArray inside it? Thanks in advance.
I think that's PROBABLY possible. Just try it :), let me know.

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.