Olá, amigos. Tudo bacana?
No Angular existem duas formas de validarmos um formulário. A primeira é nomeada como "template-drive", isso nada mais é que uma validação utilizando as directivas nativas do html ou customizadas (veremos um exemplo mais tarde) como required ou maxlength.
Validação via HTML
1. Criando a entidade usuário:
[cmd ou terminal]
$ generate class usuario
create src/app/usuario.ts (25 bytes)
//usuario.ts export class Usuario { constructor(public id:number, public nome:string, public idade:number,public email: string) { } }
2. Criando o componente Form
De acordo com a documentação do Angular, cada formulário tem duas partes. Uma é o HTML em si, contendo as directivas coerentes com suas validações, e a outra parte é a classe do tipo component que realiza as conexões de interação com os elementos html.
-- [cmd ou terminal] Neste passo criamos, pelo CLI, nosso component form. $ ng generate component form create src/app/form/form.component.html (23 bytes) create src/app/form/form.component.spec.ts (614 bytes) create src/app/form/form.component.ts (302 bytes) create src/app/form/form.component.css (0 bytes) update src/app/app.module.ts (719 bytes)</code>
Agora vamos manipular a classe component do nosso form:
//form.component.ts import { Component, OnInit } from '@angular/core'; import { Usuario } from '../usuario'; @Component({ selector: 'app-form', templateUrl: './form.component.html', styleUrls: ['./form.component.css'] }) export class FormComponent implements OnInit { public form = new Usuario(1, 'Eder Taveira', 35,'edertaveira@gmail.com'); constructor() { } ngOnInit() { } }
Antes de criarmos nosso html, vamos revisar como está o nosso ‘app.module.js’. Ele precisa de algumas modificações que vamos ver agora:
//app.module.js import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { FormsModule } from '@angular/forms'; import { FormComponent } from './form/form.component'; @NgModule({ declarations: [ AppComponent, FormComponent ], imports: [ BrowserModule, FormsModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } [/javascript]
3. Criando o Form HTML:
Usei neste exemplo o bootstrap 4.0, basta colocar o link no arquivo 'index.html', conforme abaixo:
[index.html]
<!-- index.html-- > <!doctype html /> <html lang="en" /> <head> <meta charset="utf-8"> <title>ExampleValidations</title> <base href="/"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0- beta.2/css/bootstrap.min.css" crossorigin="anonymous"> <meta name="viewport" content="width=device-width, initial- scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> </head> <body> <div class="container"> <app-root> </app- root> </div> </pre> </body> </html>
Finalmente chegamos no nosso form de fato. Eu coloquei nos comentários as explicações acerca da validação. Veja abaixo:
<!-- home.component.html--> <form #userForm="ngForm"> <!-- Aqui está nosso form, onde declaramos a variavel userForm como ngForm--> <div class="form-group"> <label for="nome">Nome</label> <!-- Abaixo declaramos nosso input na qual é required e onde criamos a variavel "nome" como ngModel (vindo de nossa entidade 'form') --> <input type="text" class="form-control" id="nome" required #nome="ngModel" [(ngModel)]="form.nome" name="nome"> <!-- Caso o campo #nome seja válido ou primitivo (caso tenha o valor inicial) este alert é ocultado--> <div [hidden]="nome.valid || nome.pristine" class="alert alert-danger"> O Nome é Obrigatório </div> </div> <div class="form-group"> <label for="idade">Idade</label> <!-- Similar ao Nome apenas coloquei o minlength para validarmos também --> <input type="text" class="form-control" id="idade" minlength="2" required #idade="ngModel" [(ngModel)]="form.idade" name="idade"> <!-- Outro exemplo de verificação de validação, caso a idade seja inválida ou já acionada via teclado --> <div class="alert alert-danger" *ngIf="idade.invalid && (idade.dirty || idade.touched)"> <div *ngIf="idade.errors.required"> A Idade é obrigatória. </div> <div *ngIf="idade.errors.minlength"> O tamanho máximo da idade é de 2 numeros </div> </div> </div> <div class="form-group"> <label for="email">Email</label> <input type="text" class="form-control" id="email" [(ngModel)]="form.email" name="email"> </div> <button type="submit" class="btn btn- success">Enviar</button> </form>
Abaixo segue a imagem ao acessar a página:
Veja como ficou ao interagir no campo idade (Repare nas classes inseridas ao nosso input ‘idade’)
Uma observação acerca do dirty e touched. ‘dirty’ é o contrário de ‘pristine’, ou seja o campo ainda não manipulado, não houve interação com o mesmo. A clausula ‘touched’ basicamente significa que o campo perdeu o foco, de maneira grosseira diriamos que o campo foi ‘tocado’.
Usando FormGroup, FormControls e Validations
Existe uma outra forma de fazer validações, que é utilizando FormGroup e FormControls. Chamamos este método de Reactive Forms. Primeiramente vamos criar em nosso método ngOnInit() nosso FormGroup,
Veja abaixo:
//form.component.js import { Component, OnInit } from '@angular/core'; import { Usuario } from '../usuario'; import { FormGroup, FormControl, Validators } from '@angular/forms'; @Component({ selector: 'app-form', templateUrl: './form.component.html', styleUrls: ['./form.component.css'] }) export class FormComponent implements OnInit { public form = new Usuario(1, 'Eder Taveira', 35, 'edertaveira@gmail.com'); public userForm: FormGroup; constructor() {} ngOnInit() { this.userForm = new FormGroup({ 'nome': new FormControl(this.form.nome, [Validators.required]), 'idade': new FormControl(this.form.idade, [Validators.required, Validators.minLength(2)]), 'email': new FormControl(this.form.email, [Validators.required, Validators.email]) }); } }
Caso rodemos este código da maneira que está, ele gerará um erro como este: ‘Can’t bind to ‘formGroup’ since it isn’t a known property of ‘form’. Isso nos informa que precisamos importar em nosso arquivo app.module.ts, a classe ReactiveFormsModule. Então veja como ficou nosso arquivo abaixo:
//app.module.js import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { FormComponent } from './form/form.component'; @NgModule({ declarations: [ AppComponent, FormComponent ], imports: [BrowserModule, FormsModule, ReactiveFormsModule], providers: [], bootstrap: [AppComponent] }) export class AppModule {}
Agora nosso HTML usando Reactive Forms:
<!-- form.component.html-- > <form [formGroup]="userForm"> <!-- Informo ao Angular qual o nome do formGroup deste formulário-- > <div class="form-group"> <label for="nome">Nome</label> <!-- usamos a directiva formControlName --> <input type="text" class="form-control" id="nome" formControlName="nome"> <!-- Pegamos o formControl utilizando o get em nosso formGroup --> <div *ngIf="userForm.get('nome').invalid && (userForm.get('nome').dirty || userForm.get('nome').touched)" class="alert alert-danger"> O Nome é Obrigatório </div> </div> <div class="form-group"> <label for="idade">Idade</label> <input type="text" class="form-control" id="idade" formControlName="idade" > <div class="alert alert-danger" *ngIf="userForm.get('idade').invalid && (userForm.get('idade').dirty || userForm.get('idade').touched)"> <div *ngIf="userForm.get('idade').hasError('required')"> A Idade é obrigatória. </div> <div *ngIf="userForm.get('idade').hasError('minlength')"> O tamanho máximo da idade é de 2 números </div> </div> </div> <div class="form-group"> <label for="email">Email</label> <input type="text" class="form-control" formControlName="email" id="email"> <div class="alert alert-danger" *ngIf="userForm.get('email').invalid && (userForm.get('email').dirty || userForm.get('email').touched)"> <div *ngIf="userForm.get('email').hasError('required')"> A Idade é obrigatória. </div> <!-- Verificamos aqui se é um email ou não de acordo com o que setamos em nosso formControl 'email' --> <div *ngIf="userForm.get('email').hasError('email')"> Não é um formato de email válido. </div> </div> </div> <button type="submit" class="btn btn-success">Enviar</button> </form> <pre>
Note que colocamos a classe ReactiveFormsModule em nossos imports. Pronto, já conseguimos rodar nosso sistema de validações de maneira correta:
Até a próxima pessoal.