Reputation: 6613
So I have a form that has some basic family information. Then I want to have part of the form to add in children of the family. I'm using reactive forms, that looks something like this:
this.details = fb.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required],
email: ['', Validators.compose([Validators.required, Validators.email])],
phone: ['', Validators.required]
});
Now, at some point in the UI, there will be inputs for children names, with the option to add more. Can I programatically add more input fields to the this.details
group?
Update
@incognito's answer is perfect for the original question I asked. It shall remain the selected answer. While doing some digging on his answer I also found FormArray, which is the direction I ended up going, so I wanted to add that here. It looks like:
this.form = this.fb.group({
...
children: this.fb.array([
this.fb.group({
name: ['', Validators.required],
age: ['', Validators.required],
gender: ['', Validators.required]
})
])
});
Then, the view looks like:
<form [formGroup]="form">
<div *ngFor="let child of form.controls.children.controls; let i = index;"
formArrayName="children"
class="childForm">
<div [formGroupName]="i"
class="row">
<div class="col-md-4">
<input type="text"
class="form-control"
formControlName="name">
</div>
<div class="col-md-4">
<input type="number"
class="form-control"
formControlName="age">
</div>
<div class="col-md-4">
<select class="form-control"
formControlName="gender">
<option value="male">Male</option>
<option value="female">Female</option>
</select>
</div>
</div>
</div>
<button (click)="addChild()"
class="btn btn-primary">
<i class="fa fa-plus"></i> Add Another Child
</button>
</form>
And the addChild
function referenced in the button at the bottom of the form looks like:
addChild() {
const children = <FormArray>this.form.get('children');
children.push(this.fb.group({
name: [''],
age: [''],
gender: ['']
}));
}
So, again, this is a different way of going about it, and I only discovered it after digging in on @incognito's answer. Thanks @incognito!
Upvotes: 1
Views: 785
Reputation: 11000
Sure you can. Implementation might be better, but something like this:
<button (click)="addKid()"> Add kid </button
numberOfKids: number = 0;
addKid() {
this.numberOfKids++;
let input = this.renderer.createElement('input');
this.renderer.appendChild(form, input);
this.renderer.setProperty(input, 'formControlName', this.numberOfKids);
this.details.addControl(this.numberOfKids, new FormControl(''));
}
So every formControl for every kid will be named as a number.
This implementation is based on Renderer2 (recommended way to "directly" manipulate DOM elements)
Upvotes: 1