Search code examples
angulartypescriptangular12

Multiple form input Angular CLI: 12.2.13


I am currently working on a component that is supposed to display multiple forms in this manner : Form

By clicking on the "+" or "-" button, you can add or remove forms. I tried to differentiate the "name" of each by using the index of my *ngFor, but it doesn't seems to work. Writing in one input field will display the data in every field of the column. However, only the data of the last field will be modified. Basically it looks like when I add a new form (index = i) all the other ones get replaced by the new form[i].

Here is my code :

import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { LogService } from 'src/app/core/log.service';
import { Declaration } from '../declaration.model';

@Component({
  selector: 'confidential-input-table',
  templateUrl: './input-table.component.html',
  styleUrls: ['./input-table.component.scss']
})
export class InputTableComponent extends DynBaseComponent implements OnInit {
  declaration = new Declaration();
  dataArray : any[] = [];


  constructor(
    protected logger : LogService
  ) {
    super(logger)
  }

  ngOnInit(): void {
    this.declaration = new Declaration();
    this.dataArray.push(this.declaration);
  }

  public onsubmit():void{
    console.log(this.dataArray);
  }
  public addForm(){
    this.declaration = new Declaration();
    this.dataArray.push(this.declaration);
  }
  public removeForm(index : number){
    this.dataArray.splice(index);
  }
  

}
<form (ngSubmit)="onsubmit()">
    <div class="containerForm">
        <div class="rowForm" *ngFor="let obj of dataArray; let i=index">
            <div class="groupForm">
                <label>Emballage{{i}}</label>
                <input type="text" class="controlForm" name="emballage{{i}}" [(ngModel)]="declaration.emballage">
            </div>

            <div class="groupForm">
                <label>Description</label>
                <input type="text" class="controlForm" name="description{{i}}" [(ngModel)]="declaration.description">
            </div>

            <div class="groupForm">
                <label>Quantité</label>
                <input type="text" class="controlForm" name="qte{{i}}" [(ngModel)]="declaration.qte">
            </div>

            <div class="groupForm2"  *ngIf="i!=0">
                <span (click)="removeForm(i)" class="btnRemove" >-</span>
            </div>
        </div>
        <span (click)="addForm()" class="btnAdd">+</span>
        <button class="btnSubmit">Submit</button>

    </div>
</form>


Solution

  • You are using the same instance declaration, you dont need to declare it anyway. To fix it, you can try something like :

    JS :

      ngOnInit(): void {
        this.dataArray.push(new Declaration());
      }
    
      public addForm(){
        this.dataArray.push(new Declaration());
      }
    

    HTML :

    <form (ngSubmit)="onsubmit()">
        <div class="containerForm">
            <div class="rowForm" *ngFor="let obj of dataArray; let i=index">
                <div class="groupForm">
                    <label>Emballage{{i}}</label>
                    <input type="text" class="controlForm" name="emballage{{i}}" [(ngModel)]="obj.emballage">
                </div>
    
                <div class="groupForm">
                    <label>Description</label>
                    <input type="text" class="controlForm" name="description{{i}}" [(ngModel)]="obj.description">
                </div>
    
                <div class="groupForm">
                    <label>Quantité</label>
                    <input type="text" class="controlForm" name="qte{{i}}" [(ngModel)]="obj.qte">
                </div>
    
                <div class="groupForm2"  *ngIf="i!=0">
                    <span (click)="removeForm(i)" class="btnRemove" >-</span>
                </div>
            </div>
            <span (click)="addForm()" class="btnAdd">+</span>
            <button class="btnSubmit">Submit</button>
    
        </div>
    </form>