Reputation: 528
i am trying to create the dynamic reactive form using angular i am able to loop it but it is displaying the exact way
<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
<div *ngFor="let dat of formData;let index = index;">
<label for="{{dat.name}}">{{dat.name }}</label>
<input type="text" id="{{dat.id}}" [formControlName]="dat.name" />
</div>
</form>
<button type="button"><button>
.ts
registerForm: FormGroup;
submitted = false;
formData = [{ id: 'firstName', name: 'firstName' },
{ id: 'lastName', name: 'lastName' },
{ id: 'address', name: 'address' },
{ id: 'emailid', name: 'emailid' }
]
constructor(private formBuilder: FormBuilder) {
this.registerForm = this.formBuilder.group({
formData: []
});
}
onSubmit(){
console.log(this.registerForm.value);
}
including the validation
below is my stackblitz url
https://stackblitz.com/edit/angular-awguej
Upvotes: 0
Views: 693
Reputation: 58039
To complement Krishna's answer, if you want to create a formArray with data, you can create two functions.
//create a formGroup with the data or empy if not data
createNewGroup(data):FormGroup {
return this.formBuilder.group({
id: [data?data.id:null],
name: [data?data.name:null]
})
}
//And a function to create the form
createForm(formData):formGroup
{
//create an array of FormGroup,
//if data, with each element of data a newGroup
//else an array with one element
let group=formData? formData.map(d=>this.createNewGroup(d))
:[this.createNewGroup(null)]
return this.formBuilder.group({
formData: this.formBuilder.array(group)
});
}
So, you can
this.registerForm=createform(this.formData) //create a form with data
this.registerForm=createform(null) //create a empty form
Upvotes: 1
Reputation: 630
You can also add controls like this.
component.ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, FormControl, ValidatorFn } from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
registerForm: FormGroup;
submitted = false;
formData = [{ id: 'firstName', name: 'firstName' },
{ id: 'lastName', name: 'lastName' },
{ id: 'address', name: 'address' },
{ id: 'emailid', name: 'emailid' }
]
constructor(private formBuilder: FormBuilder) {
this.registerForm = this.formBuilder.group({
list: this.formBuilder.array([])
});
}
ngOnInit() {
this.registerForm = this.formBuilder.group({
list: this.formBuilder.array(
this.formData.map(x => this.formBuilder.group({
name: [x['name']],
id: [x['id']]
}))
)
})
}
onSubmit() {
console.log(this.registerForm.value);
}
}
Component.html
<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
<span formArrayName="list">
<div *ngFor="let dat of registerForm.get('list').controls;let index = index;" formGroupName="{{index}}">
<label for="{{dat.name}}">{{dat.name }}</label>
<input type="text" id="{{dat.get('id').value}}" formControlName="name" />
</div>
</span>
<button type="submit">button</button>
</form>
Upvotes: 1
Reputation: 3740
I added a value cause you need an id to control an input field a name to set the label and a value to set the value. If you end up with a more dynamic way this will come in handy.
In your component you do:
formData = [{ id: 'firstName', name: 'firstName', value: '' },
{ id: 'lastName', name: 'lastName', value: '' },
{ id: 'address', name: 'address', value: '' },
{ id: 'emailid', name: 'emailid', value: '' }
]
constructor(private formBuilder: FormBuilder) {
let formGroups: FormGroup[] = [];
for(let i = 0; i < this.formData.length; i++){
formGroups.push(this.formBuilder.group({
id: this.formData[i].id,
name: this.formData[i].name,
value: this.formData[i].value,
}));
}
this.registerForm = this.formBuilder.group({
array: this.formBuilder.array(formGroups)
})
}
onSubmit(){
console.log(this.registerForm.value);
}
And in the html:
<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
<div formArrayName="array">
<div *ngFor="let dat of registerForm.get('array').controls;let i = index;" [formGroupName]="i">
<label>{{dat.get('name').value}} </label>
<input type="string" id={{dat.value.id}} #input formControlName="value">
</div>
</div>
</form>
<button><button>
Upvotes: 1
Reputation: 9687
you can use this.formBuilder.array
for this.
component.html
<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
<div formArrayName="formData">
<div *ngFor="let dat of registerForm.get('formData').controls;let index = index;" [formGroupName]="index">
<label>{{dat.get('name').value }}</label>
<input type="text" formControlName="name" />
</div>
<button type="submit">Submit</button>
</div>
</form>
<button type="button" (click)="addNew()">Add</button>
component.ts
registerForm: FormGroup;
submitted = false;
constructor(private formBuilder: FormBuilder) {
this.registerForm = this.formBuilder.group({
formData: this.formBuilder.array([this.createNewGroup()])
});
}
createNewGroup() {
return this.formBuilder.group({
id: ['id'],
name: ['name']
})
}
addNew(){
let formArr=this.registerForm.get('formData') as FormArray;
formArr.push(this.createNewGroup());
}
onSubmit(){
console.log(this.registerForm.value);
}
Upvotes: 1