Search code examples
angularangular-forms

Angular Template driven form dynamic form part


I don't know what to google to find an answer to my question so I'm asking here. I have to create a form with one part that is always the same, there are some input fields you can only fill once per form. And then there is a group of fields that I want to enable the user to create multiple instances of. It would look something like this: Field 1, Field 2, Button with 'Add field 3-5' and if you click it you can fill in the fields 3-5, afterwards you can either submit the form or add anoter instance of fields 3-5 and so on. I'm completely new to forntend stuff so I don't know if there is a word for this. Anyways I would appreciate your help.


Solution

  • Angular's FormBuilder and FormArray will help you to achieve this easily.

    you can define a FormArray like a FormControl when you create your FormGroup and loop through it in your UI.

      demoForm: FormGroup;
      submitted = false;
      output =  {}
    
      get firstName(): FormControl {
        return this.demoForm.controls["firstName"] as FormControl;
      }
      get lastName(): FormControl {
        return this.demoForm.controls["lastName"] as FormControl;
      }
      get optionals(): FormArray {
        return this.demoForm.controls["optionals"] as FormArray;
      }
    
      constructor(private _formBuilder: FormBuilder) {
        this.demoForm = this._formBuilder.group({
          firstName: this._formBuilder.control('', [Validators.required]),
          lastName: this._formBuilder.control('', [Validators.required]),
          optionals: this._formBuilder.array([]),
      /*  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  */
        });
      }
    

    and in your HTML

    <form [formGroup]="demoForm">
        <input type="text" formControlName="firstName" />
        <input type="text" formControlName="lastName" />
    
        <div formArrayName="optionals">
        <!-- ^^^^^^^^^^^^^^^^^^^^^^^^ -->
            <div [formGroupName]="i" *ngFor="let optionals of optionals.controls; index as i;">
            <!-- ^^^^^^^^^^^^^^^^^^ -->
                <input type="text" formControlName="attr1" />
                <input type="text" formControlName="attr2" />
            </div>
        </div>
    </form>
    
    

    you can add or remove items from the array with something like this :

      AddOptionalItems(){
         // you can add validation here on each item individually.
         const group = new FormGroup({
          attr1: new FormControl(''),
          attr2: new FormControl(''),
        });
        this.optionals.push(group);
      }
    
      RemoveOptionalItems(i:number){
        this.optionals.removeAt(i);
      }
    
    

    here is a small stackblitz with a more complete version.

    EDIT :

    a helpful article: https://netbasal.com/angular-reactive-forms-the-ultimate-guide-to-formarray-3adbe6b0b61a