Creating Dynamic Forms
It is not an uncommon situation to require a dynamic form - one that does not just have a static/pre-defined number of controls. For example, let’s say you have a form that allows a user to enter a guest list. Each guest should be entered into their own text field, e.g:
We want to be able to click the Add guest
button to add as many fields for guests as we want. But, when we define forms like this:
guestForm = this.fb.nonNullable.group(
{
guests: ['', Validators.required],
},
);
How can we account for this dynamic behaviour?
Introducing Form Arrays
We have been focusing on the concept of a FormControl
which is used for an individual field in our forms, and a FormGroup
which is a collection of those controls. Another feature we can make use of us FormArray
. A FormArray
is an array of multiple controls and the values of all of those controls will be output as an array when we check the forms value
. Importantly, a FormArray
provides us a way to easily push new controls into this FormArray
dynamically.
It might sound complex, but it isn’t all that different to what we have been doing already. Let’s see how we might implement our guests example. First, we would add another control to our form, but we will set it to be a FormArray
:
myForm = this.fb.nonNullable.group(
{
username: [
'',
Validators.required,
this.usernameAvailableValidator.validate.bind(
this.usernameAvailableValidator
),
],
age: [null, adultValidator],
password: ['', [Validators.minLength(8), Validators.required]],
confirmPassword: ['', [Validators.required]],
guests: this.fb.array([]),
},
{
validators: [passwordMatchesValidator],
}
);