Search code examples
angularinputdynamicngfor

angular *ngFor dynamic amount of inputs


I need to give the user the option of how many input fields, then enter each input into a separate position of an array.

I'm a bit confused how to do this. Here's the basic work:

app.component.html:


<div class="form-group" *ngFor="let d of amount">
 <div class="form-group" *ngFor="let d of data">
   <input type="text" 
       class="form-control" 
       placeholder="{{d.placeholder}}" 
       [(ngModel)]="model[d.modelPropName]"
       name="{{d.name}}"
      />
</div>
</div> 

app.component.ts:

 { placeholder: 'First name', name: 'name', modelPropName: 'model.name'},
 { placeholder: 'Last name', name: 'lastName', modelPropName: 'model.lastName'},
 { placeholder: 'Age', name: 'age', modelPropName: 'model.age'}
];

 model: any = {};
 data = MY_DATA;
 amount = [1,2,3]

 constructor() { }

 ngOnInit() {}

 submit() {
     console.log('Data submitted: ', this.model);
   }  

I do need it to appear something like this:

ui description

I've used this for reference example: Angular 4 - creating input type dynamically with ngFor


Solution

  • One option you could do is use the Reactive forms. With this option, you have the option to do stuff like validation on the form inputs too

    So would look like...

    TS:

    public form: FormGroup;
    
    constructor(fb: FormBuilder) {
        this.form = this.fb.group({
            users: this.fb.array([this.newUser()]),
        });
    }
    
    get users(): FormArray {
        return this.form.get('users') as FormArray;
    }
    
    private newUser(): FormGroup {
        return this.fb.group({
            name: ['', Validators.required],
            ...
        });
    }
    
    public addUser(): void {
        this.subCategories.push(this.newUser());
    }
    
    public removeUser(index: number): void {
        this.subCategories.removeAt(index);
    }
    

    HTML:

    <div class="form-group" formArrayName="users">
        <button (click)="addNewUser()" >Add user</button>
        <ng-container *ngFor="let users of users.controls; let i = index" [formGroupName]="I">
           <input type="text" class="form-control" formControlName="name" />
           ... Other Form inputs
           <div class="btn btn-danger" (click)="removeUser(i)">Delete</div>
        </ng-contianer>
    </div>