Forms are using a kind of ElementRef that gets a value assigned, which will be the NgForm.
ViewChild is usefull as it can be used to access the form in an earlier stage of the component life cycle.
Validator can be added as directives in the template: required, email https://angular.io/api/forms/Validators https://angular.io/api?query=validator&type=directive
Angular Adds clases for the validation state on each ngModel field.
ngModel supports:
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
<form (ngSubmit)="onSubmit()" #f="ngForm">
<!-- Grouping data is posible in the form, maybe a good idea for nested serializers -->
<div id="user-data" ngModelGroup="userData" #userData="ngModelGroup">
<div class="form-group">
<label for="username">Username</label>
<input type="text" id="username" class="form-control" ngModel name="username" required>
</div>
<button class="btn btn-default" type="button" (click)="suggestUserName()">Suggest an Username</button>
<div class="form-group">
<label for="email">Mail</label>
<input type="email" id="email" class="form-control" ngModel name="email" required email #email="ngModel">
<span class="help-block" *ngIf='!email.valid && email.touched'>Please enter a valid email!</span>
</div>
</div>
<p *ngIf="!userData.valid && userData.touched">Group invalid</p>
<div class="form-group">
<label for="secret">Secret Questions</label>
<select id="secret" class="form-control" [ngModel]="'pet'" name="secret">
<option value="pet">Your first Pet?</option>
<option value="teacher">Your first teacher?</option>
</select>
</div>
<div class="form-group">
<textarea name="questionAnswer" rows="3" [(ngModel)]="answer"></textarea>
</div>
<p>Your reply: {{ answer }}</p>
<div class="radio" *ngFor="let gender of genders">
<label>
<input type="radio" name="gender" ngModel [value]="gender">
{{ gender }}
</label>
</div>
<button class="btn btn-primary" type="submit" [disabled]="!f.valid">Submit</button>
</form>
</div>
</div>
</div>
.container {
margin-top: 30px;
}
form .ng-invalid.ng-touched {
border: 1px solid red;
}
import { Component } from '@angular/core';
import { NgForm } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
suggestUserName() {
const suggestedName = 'Superuser';
}
onSubmit(form: NgForm) {
console.log("Submited!");
console.log(form); // #f="ngForm" , onSubmit(f)
console.log(form.value);
}
}
import { Component, ViewChild } from '@angular/core';
import { NgForm } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
@ViewChild('f') form: NgForm;
answer = '';
genders = ['male', 'female'];
suggestUserName() {
const suggestedName = 'Superuser';
/* this.form.setValue({
userData: {
username: suggestedName,
email: '',
},
secret: 'pet',
questionAnswer: '',
gender: 'male',
}); */
this.form.form.patchValue({
userData: {
username: suggestedName
}
});
}
onSubmit() {
console.log('Submited!');
console.log(this.form); // #f="ngForm"
console.log(this.form.value);
// Reset form
this.form.reset();
}
}