简体   繁体   中英

Dynamically add new fields on a click event?

Here is my FormGroup:

this.productGroup = this.fb.group({
  name: ['', Validators.compose([Validators.required, Validators.maxLength(80)])],
  desc: ['', Validators.maxLength(3000)],
  category: ['', Validators.required]
  variants: this.fb.array([
    this.fb.group({
      type: '',
      options: ''
    })
  ])
});

I need to dinamically add type and options control fields after the user click on a button. FormArray should look like this after User Input: [ {type: 'size', options: 'Small', 'Big'}, {type: 'color', options: 'red', 'blue, 'yellow'}, ... ] .

Here whats I'm trying to do:

// Add new item to FormArray
addItem(): void {
  this.variantsArray = this.productGroup.get('variants') as FormArray;
  this.variantsArray.push(this.fb.group({
    type: '',
    options: ''
  }));
}

// Template
<form [formGroup]="productGroup">
  // inputs...
  <div formArrayName="variants" *ngFor="let item of productGroup.controls['variants']; let i = index;">
      <div [formGroupName]="i">
        <div class="row">
          <mat-form-field class="col-12">
            <input formControlName="type">
          </mat-form-field>
        </div>
        <div class="row">
          <mat-form-field class="col-12">
            <input formControlName="options">
          </mat-form-field>
        </div>
      </div>
      <div class="row">
        <a href="javascript:" (click)="addItem()"> Adicionar Variante </a>
        <a href="javascript:" (click)="removeItem(i)" *ngIf="i > 0"> Remover Variante </a>
      </div>
    </div>
</form>

How to make it work?

I don't know exactly what you want to achieve but I think I got your problem.

The following code:

variants: this.fb.array([
    this.fb.group({
      type: '',
      options: ''
    })
  ])

does not produce an array, so you can't iterate over it with *ngFor .

If you look a little deeper into it you will see that

productGroup.controls['variants']

has a property with the controls.

So just change the *ngFor to:

*ngFor="let item of productGroup.controls['variants'].controls; let i = index;"

and you should be fine.

For adding the formElemnt dynamically in the reactive form, you need to first create the form element or a form group and push it in the original formarry for that field.

EX: i have a customerForm like below

this.customerForm = this.fb.group({
  firstName: ['', [Validators.required, Validators.minLength(3)]],
  lastName: ['', [Validators.required, Validators.maxLength(50)]],
  emailGroup: this.fb.group({
    email: ['', [Validators.required, Validators.email]],
    confirmEmail: ['', Validators.required],
  }, { validator: emailMatcher }),
  phone: ''
  addresses: this.fb.array([this.createAddress()])
});

On click of add Address in View I can call a function in component that will push a new address to the addresses array in form.

  addAddress(): void {
   this.addresses.push(this.createAddress());
  }

 createAddress(): FormGroup {
   return this.fb.group({
      street1: ['', Validators.required],
      street2: '',
      city: '',
      state: '',
      zip: ''
   });
 }

In your view you can iterate over this address array and display the addresses. Initially it won't show as the array value will be empty! Hope it Helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM