Desenvolvimento

16 nov, 2017

Validations com Angular 5 (2+) – Parte 01

Publicidade

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.