Angular 2 Data Driven Forms
Data driven form
Section titled “Data driven form”Component
import {Component, OnInit} from '@angular/core';import { FormGroup, FormControl, FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES, Validators, FormBuilder, FormArray} from "@angular/forms";import {Control} from "@angular/common";
@Component({ moduleId: module.id, selector: 'app-data-driven-form', templateUrl: 'data-driven-form.component.html', styleUrls: ['data-driven-form.component.css'], directives: [FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES]})export class DataDrivenFormComponent implements OnInit { myForm: FormGroup;
constructor(private formBuilder: FormBuilder) {}
ngOnInit() { this.myForm = this.formBuilder.group({ 'loginCredentials': this.formBuilder.group({ 'login': ['', Validators.required], 'email': ['', [Validators.required, customValidator]], 'password': ['', Validators.required] }), 'hobbies': this.formBuilder.array([ this.formBuilder.group({ 'hobby': ['', Validators.required] }) ]) }); }
removeHobby(index: number){ (<FormArray>this.myForm.find('hobbies')).removeAt(index); }
onAddHobby() { (<FormArray>this.myForm.find('hobbies')).push(new FormGroup({ 'hobby': new FormControl('', Validators.required) })) }
onSubmit() { console.log(this.myForm.value); }}
function customValidator(control: Control): {[s: string]: boolean} { if(!control.value.match("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")) { return {error: true} }}HTML Markup
<h3>Register page</h3><form [formGroup]="myForm" (ngSubmit)="onSubmit()"> <div formGroupName="loginCredentials"> <div class="form-group"> <div> <label for="login">Login</label> <input id="login" type="text" class="form-control" formControlName="login"> </div> <div> <label for="email">Email</label> <input id="email" type="text" class="form-control" formControlName="email"> </div> <div> <label for="password">Password</label> <input id="password" type="text" class="form-control" formControlName="password"> </div> </div> </div> <div class="row" > <div formGroupName="hobbies"> <div class="form-group"> <label>Hobbies array:</label> <div *ngFor="let hobby of myForm.find('hobbies').controls; let i = index"> <div formGroupName="{{i}}"> <input id="hobby_{{i}}" type="text" class="form-control" formControlName="hobby"> <button *ngIf="myForm.find('hobbies').length > 1" (click)="removeHobby(i)">x</button> </div> </div> <button (click)="onAddHobby()">Add hobby</button> </div> </div> </div> <button type="submit" [disabled]="!myForm.valid">Submit</button></form>Remarks
Section titled “Remarks”this.myForm = this.formBuilder.group
creates a form object with user’s configuration and assigns it to this.myForm variable.
'loginCredentials': this.formBuilder.group
method creates a group of controls which consist of a formControlName eg. login and value ['', Validators.required], where the first parameter is the initial value of the form input and the secons is a validator or an array of validators as in 'email': ['', [Validators.required, customValidator]],.
'hobbies': this.formBuilder.arrayCreates an array of groups where the index of the group is formGroupName in the array and is accessed like :
<div *ngFor="let hobby of myForm.find('hobbies').controls; let i = index"> <div formGroupName="{{i}}">...</div></div>onAddHobby() { (<FormArray>this.myForm.find('hobbies')).push(new FormGroup({ 'hobby': new FormControl('', Validators.required) })) }this sample method adds new formGroup to the array.
Currently accessing requires specifing the type of control we want to access, in this example this type is : <FormArray>
removeHobby(index: number){ (<FormArray>this.myForm.find('hobbies')).removeAt(index); }same rules as above apply to removing a specific form control from the array