Ir para o conteúdo
Como criar validadores personalizados para formulários reativos Angular

Como criar validadores personalizados para formulários reativos Angular

Nesta postagem do blog, aprenderemos a criar validadores personalizados em Angular Reactive Forms. Se você não estiver familiarizado com formulários reativos, saiba como criar seu primeiro formulário Angular reativo aqui.

7min read

Nesta postagem do blog, aprenderemos a criar validadores personalizados em Angular Reactive Forms. Se você não estiver familiarizado com formulários reativos, saiba como criar seu primeiro formulário Angular reativo aqui.

Digamos que temos um formulário de login, conforme mostrado na lista abaixo. Atualmente, os controles de formulário não têm nenhuma validação anexada a ele.

ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null),
        password: new FormControl(null),
        age: new FormControl(null)
    });
}

Aqui, estamos usando FormGroup para criar um formulário reativo. No modelo de componente, você pode anexar loginForm conforme mostrado na listagem de código abaixo. Usando a vinculação de propriedade, a propriedade formGroup do elemento de formulário HTML é definida como loginForm e o valor formControlName desses controles é definido como a propriedade FormControl individual de FormGroup.

<form (ngSubmit)='loginUser()' [formGroup]='loginForm' novalidate class="form">
     <input formControlName='email' type="text" class="form-control" placeholder="Enter Email" />
     <br />
     <input formControlName='password' type="password" class="form-control" placeholder="Enter Password" />
     <br />
     <input formControlName='age' type="number" class="form-control" placeholder="Enter Age" />
     <br />
     <button [disabled]='loginForm.invalid' class="btn btn-default">Login</button>
 </form>

Isso lhe dará um formulário reativo em sua inscrição:

Isso lhe dará um formulário reativo em sua inscrição

Using Validators

Angular nos fornece muitos validadores úteis, incluindo required,minLength,maxLength e pattern. Esses validadores fazem parte da classe Validators, que vem com o pacote @angular/forms.

Vamos supor que você queira adicionar uma validação necessária ao controle de email e uma validação maxLength ao controle de senha. Veja como fazer isso:

ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null, [Validators.required]),
        password: new FormControl(null, [Validators.required, Validators.maxLength(8)]),
        age: new FormControl(null)
    });
}

Para trabalhar com validadores, certifique-se de importá-los na classe do componente:

import { FormGroup, FormControl, Validators } from '@angular/forms';

No modelo, você pode usar validadores para mostrar ou ocultar uma mensagem de erro. Essencialmente, você está lendo o formControl usando o método get() e verificando se ele tem um erro ou não usando o método hasError(). Você também está verificando se o formControl é tocado ou não usando a propriedade tocada.

<input formControlName='email' type="text" class="form-control" placeholder="Enter Email" />
<div class="alert  alert-danger" *ngIf="loginForm.get('email').hasError('required') && loginForm.get('email').touched">
    Email is required
</div>

Se o usuário não inserir um e-mail, o formulário reativo mostrará um erro da seguinte maneira:

Se o usuário não inserir um e-mail, o formulário reativo mostrará um erro

Custom Validators

Digamos que você queira que a faixa etária seja de 18 a 45 anos. Angular não nos fornece validação de alcance; portanto, teremos que escrever um validador personalizado para isso.

Em Angular, criar um validador personalizado é tão simples quanto criar outra função. A única coisa que você precisa ter em mente é que ele usa um parâmetro de entrada do tipo AbstractControl e retorna um objeto de par de valores de chave se a validação falhar.

Vamos criar um validador personalizado chamado ageRangeValidator, onde o usuário deve ser capaz de inserir uma idade somente se ela estiver em um determinado intervalo.

Create a custom validator called ageRangeValidator

O tipo do primeiro parâmetro é AbstractControl porque é uma classe base de FormControl, FormArray e FormGroup e permite que você leia o valor do controle passado para a função de validador personalizada. O validador personalizado retorna um dos seguintes:

  1. Se a validação falhar, ela retornará um objeto, que contém um par de valores-chave. Key é o nome do erro e o valor é sempre booleano true.
  2. Se a validação não falhar, ela retornará nulo.

Agora, podemos implementar o validador personalizado ageRangeValidator na lista abaixo:

function ageRangeValidator(control: AbstractControl): { [key: string]: boolean } | null {
 
    if (control.value !== undefined && (isNaN(control.value) || control.value < 18 || control.value > 45)) {
        return { 'ageRange': true };
    }
    return null;
}

Aqui, estamos codificando o intervalo máximo e mínimo no validador. Na próxima seção, veremos como passar esses parâmetros.

Agora, você pode usar ageRangeValidator com o controle de idade, conforme mostrado na listagem abaixo. Como você pode ver, você precisa adicionar o nome da função de validador personalizada na matriz:

ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null, [Validators.required]),
        password: new FormControl(null, [Validators.required, Validators.maxLength(8)]),
        age: new FormControl(null, [ageRangeValidator])
    });
}

No modelo, o validador personalizado pode ser usado como qualquer outro validador. Estamos usando a validação ageRange para mostrar ou ocultar a mensagem de erro.

<input formControlName='age' type="number" class="form-control" placeholder="Enter Age" />
 <div class="alert  alert-danger" *ngIf="loginForm.get('age').dirty && loginForm.get('age').errors && loginForm.get('age').errors.ageRange ">
     Age should be in between 18 to 45 years
 </div>

Se o usuário não inserir uma idade entre 18 e 45 anos, o formulário reativo mostrará um erro:

Agora, o controle de idade está funcionando com o validador personalizado. O único problema com ageRangeValidator é a faixa etária codificada que valida apenas números entre 18 e. Para evitar um intervalo fixo, precisamos passar a idade máxima e mínima para ageRangeValidator.

Passando parâmetros para um validador personalizado

Um validador personalizado Angular não usa diretamente parâmetros de entrada extras além da referência do controle. Para passar parâmetros extras, você precisa adicionar um validador personalizado dentro de uma função de fábrica. A função de fábrica retornará um validador personalizado.

Você ouviu direito: em JavaScript, uma função pode retornar outra função.

Essencialmente, para passar parâmetros para um validador personalizado, você precisa seguir estas etapas:

  1. Crie uma função de fábrica e passe os parâmetros que serão passados para o validador personalizado para essa função.
  2. O tipo de retorno da função de fábrica deve ser ValidatorFn, que faz parte de @angular/forms
  3. Retorne o validador personalizado da função de fábrica.

A sintaxe da função de fábrica será a seguinte:

Agora você pode refatorar o ageRangeValidator para aceitar parâmetros de entrada, conforme mostrado na listagem abaixo:

function ageRangeValidator(min: number, max: number): ValidatorFn {
    return (control: AbstractControl): { [key: string]: boolean } | null => {
        if (control.value !== undefined && (isNaN(control.value) || control.value < min || control.value > max)) {
            return { 'ageRange': true };
        }
        return null;
    };
}

Estamos usando os parâmetros de entrada max e min para validar o controle de idade. Agora, você pode usar ageRangeValidator com controle de idade e passar os valores para max e min, conforme mostrado na listagem abaixo:

min = 10;
max = 20;
ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null, [Validators.required]),
        password: new FormControl(null, [Validators.required, Validators.maxLength(8)]),
        age: new FormControl(null, [ageRangeValidator(this.min, this.max)])
    });
}

No modelo, o validador personalizado pode ser usado como qualquer outro validador. Estamos usando a validação ageRange para mostrar ou ocultar uma mensagem de erro:

<input formControlName='age' type="number" class="form-control" placeholder="Enter Age" />
  <div class="alert  alert-danger" *ngIf="loginForm.get('age').dirty && loginForm.get('age').errors && loginForm.get('age').errors.ageRange ">
      Age should be in between {{min}} to {{max}} years
  </div>

Nesse caso, se o usuário não inserir uma idade entre 10 e 20 anos, a mensagem de erro será mostrada conforme abaixo:

Nesse caso, se o usuário não inserir uma idade entre 10 e 20 anos, a mensagem de erro será exibida

E aí está: como criar um validador personalizado para Angular Reactive Forms.

Gostou deste post?

Se você gostou deste post, por favor, compartilhe-o. Além disso, se você ainda não conferiu nossos componentes Angular, certifique-se de fazê-lo!

Ignite UI for Angular

Solicite uma demonstração