Angular’s Reactive Forms API provides a powerful and flexible way to create and manage complex form structures and handle various validation scenarios. Here is a step-by-step guide on how to use Angular’s reactive form APIs to build a complex form with nested form groups, form arrays, and validation.
1. **Import ReactiveFormsModule**: To start, you need to import ‘ReactiveFormsModule‘ in your ‘app.module.ts‘ file to use reactive form features.
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
// ...
imports: [
// ...
ReactiveFormsModule
],
// ...
})
export class AppModule { }
2. **Create form controls**: Use ‘FormControl‘, ‘FormGroup‘, and ‘FormArray‘ to create a basic structure of your form. ‘FormControl‘ represents a single input field, ‘FormGroup‘ manages a group of related input fields, and ‘FormArray‘ manages a dynamic list of input fields.
Example: Consider a "Profile" form with basic info (first name, last name), skills (a list of skills), and address (country and city).
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-root',
template: `...`
})
export class AppComponent {
profileForm: FormGroup;
constructor(private fb: FormBuilder) {
this.profileForm = this.fb.group({
basicInfo: this.fb.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required]
}),
skills: this.fb.array([], Validators.required),
address: this.fb.group({
country: ['', Validators.required],
city: ['', Validators.required]
})
});
}
}
3. **Create form UI**: Now you need to bind your form with your UI using the ‘[formGroup]‘, ‘[formGroupName]‘, ‘[formArrayName]‘, and ‘[formControlName]‘ directives.
<form [formGroup]="profileForm">
<h3>Basic Info</h3>
<div formGroupName="basicInfo">
<label>
First Name:
<input type="text" formControlName="firstName">
</label>
<label>
Last Name:
<input type="text" formControlName="lastName">
</label>
</div>
<h3>Skills</h3>
<div formArrayName="skills">
<div *ngFor="let skillControl of skills.controls; index as i;">
<label>
Skill {{i + 1}}:
<input type="text" [formControl]="skillControl">
</label>
</div>
<button (click)="addSkill()">Add Skill</button>
</div>
<h3>Address</h3>
<div formGroupName="address">
<label>
Country:
<input type="text" formControlName="country">
</label>
<label>
City:
<input type="text" formControlName="city">
</label>
</div>
<button (click)="submit()">Submit</button>
</form>
4. **Add custom validation**: In case you need custom validation, create a custom validator function and assign it to the specific form control using the ‘Validators‘ class.
Example: Let’s add a custom validator for the first name that checks if the name starts with a capital letter.
function startsWithCapitalLetter(control: FormControl) {
const value = control.value;
if (!value || value[0] !== value[0].toUpperCase()) {
return { notCapitalLetter: true };
}
return null;
}
// ...
this.profileForm = this.fb.group({
basicInfo: this.fb.group({
firstName: ['', [Validators.required, startsWithCapitalLetter]],
lastName: ['', Validators.required]
}),
// ...
});
5. **Display validation messages**: Use the ‘*ngIf‘ directive to conditionally display validation messages based on form control’s validity and state.
<label>
First Name:
<input type="text" formControlName="firstName">
<span *ngIf="firstName.invalid && firstName.touched">
<small *ngIf="firstName.errors.required">Required.</small>
<small *ngIf="firstName.errors.notCapitalLetter">Must start with a capital letter.</small>
</span>
</label>
6. **Handle form submission**: Finally, handle the ‘submit()‘ method to process the form data.
submit() {
if (this.profileForm.valid) {
console.log(this.profileForm.value);
// Process form data
} else {
// Display error messages, mark all controls as touched to show validation messages
this.profileForm.markAllAsTouched();
}
}
These are the basic steps to create a complex form structure using Angular’s reactive form APIs. You can build more complex forms and handle various validation scenarios by combining and extending these techniques.
For displaying charts: Plot a simple bar chart using pgfplots package:
This is just a representation of plotting a chart with pgfplots. You can customize the chart based on your data and visualization requirements.