Saltar al contenido
Cómo crear validadores personalizados para formularios reactivos Angular

Cómo crear validadores personalizados para formularios reactivos Angular

En esta entrada del blog, aprenderemos a crear validadores personalizados en Angular Reactive Forms. Si eres nuevo en los formularios reactivos, aprende a crear tu primer formulario reactivo Angular aquí.

7min read

En esta entrada del blog, aprenderemos a crear validadores personalizados en Angular Reactive Forms. Si eres nuevo en los formularios reactivos, aprende a crear tu primer formulario reactivo Angular aquí.

Digamos que tenemos un formulario de inicio de sesión como se muestra en la lista a continuación. Actualmente, los controles de formulario no tienen ninguna validación adjunta.

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

Aquí, estamos usando FormGroup para crear un formulario reactivo. En la plantilla de componente, puede adjuntar loginForm como se muestra en la lista de códigos a continuación. Mediante el enlace de propiedades, la propiedad formGroup del elemento de formulario HTML se establece en loginForm y el valor formControlName de estos controles se establece en la propiedad 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>

Esto le dará un formulario reactivo en su solicitud:

Esto le dará un formulario reactivo en su solicitud

Using Validators

Angular nos proporciona muchos validadores útiles, incluidos required,minLength,maxLength y pattern.  Estos validadores forman parte de la clase Validators, que viene con el paquete @angular/forms.

Supongamos que desea agregar una validación necesaria al control de correo electrónico y una validación maxLength al control de contraseña. A continuación, te explicamos cómo hacerlo:

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 trabajar con validadores, asegúrese de importarlos en la clase de componente:

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

En la plantilla, puede usar validadores para mostrar u ocultar un mensaje de error. Básicamente, estás leyendo el formControl usando el método get() y verificando si tiene un error o no usando el método hasError(). También está comprobando si el formControl se toca o no utilizando la propiedad 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>

Si el usuario no ingresa un correo electrónico, el formulario reactivo mostrará un error de la siguiente manera:

Si el usuario no ingresa un correo electrónico, el formulario reactivo mostrará un error

Custom Validators

Supongamos que desea que el rango de edad sea de 18 a 45 años. Angular no nos proporciona validación de rango; Por lo tanto, tendremos que escribir un validador personalizado para esto.

En Angular, crear un validador personalizado es tan sencillo como crear otra función. Lo único que debe tener en cuenta es que toma un parámetro de entrada de tipo AbstractControl y devuelve un objeto de par clave-valor si se produce un error en la validación.

Vamos a crear un validador personalizado llamado ageRangeValidator, donde el usuario debería poder ingresar una edad solo si está en un rango determinado.

Create a custom validator called ageRangeValidator

El tipo del primer parámetro es AbstractControl porque es una clase base de FormControl, FormArray y FormGroup, y permite leer el valor del control pasado a la función validadora personalizada. El validador personalizado devuelve una de las siguientes opciones:

  1. Si se produce un error en la validación, devuelve un objeto, que contiene un par clave-valor. Key es el nombre del error y el valor siempre es booleano verdadero.
  2. Si no se produce un error en la validación, devuelve null.

Ahora, podemos implementar el validador personalizado ageRangeValidator en la siguiente lista:

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;
}

Aquí, estamos codificando el rango máximo y mínimo en el validador. En la siguiente sección, veremos cómo pasar estos parámetros.

Ahora, puede usar ageRangeValidator con el control de edad como se muestra en la lista a continuación. Como puede ver, debe agregar el nombre de la función validadora personalizada en la 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])
    });
}

En la plantilla, el validador personalizado se puede utilizar como cualquier otro validador. Estamos usando la validación ageRange para mostrar u ocultar el mensaje de error.

<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>

Si el usuario no introduce una edad comprendida entre los 18 y los 45 años, el formulario reactivo mostrará un error:

Ahora, el control de edad funciona con el validador personalizado. El único problema con ageRangeValidator es ese rango de edad codificado de forma rígida que solo valida números entre 18 y 18. Para evitar un rango fijo, necesitamos pasar la edad máxima y mínima a ageRangeValidator.

Pasar parámetros a un validador personalizado

Un validador personalizado Angular no toma directamente parámetros de entrada adicionales aparte de la referencia del control. Para pasar parámetros adicionales, debe agregar un validador personalizado dentro de una función de fábrica. A continuación, la función de fábrica devolverá un validador personalizado.

Escuchaste bien: en JavaScript, una función puede devolver otra función.

Esencialmente, para pasar parámetros a un validador personalizado, debe seguir estos pasos:

  1. Cree una función de fábrica y pase los parámetros que se pasarán al validador personalizado a esta función.
  2. El tipo de retorno de la función de fábrica debe ser ValidatorFn, que forma parte de @angular/forms
  3. Devuelve el validador personalizado de la función de fábrica.

La sintaxis de la función de fábrica será la siguiente:

Ahora puede refactorizar ageRangeValidator para aceptar parámetros de entrada como se muestra en la lista a continuación:

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 utilizando los parámetros de entrada max y min para validar el control de edad. Ahora, puede usar ageRangeValidator con control de edad y pasar los valores de max y min como se muestra en la lista a continuación:

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)])
    });
}

En la plantilla, el validador personalizado se puede utilizar como cualquier otro validador. Estamos usando la validación de ageRange para mostrar u ocultar un mensaje de error:

<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>

En este caso, si el usuario no introduce una edad comprendida entre los 10 y los 20 años, el mensaje de error se mostrará como se ve a continuación:

En este caso, si el usuario no introduce una edad comprendida entre los 10 y los 20 años, se mostrará el mensaje de error

Y ahí lo tienes: cómo crear un validador personalizado para Angular Reactive Forms.

¿Te ha gustado este post?

Si te ha gustado este post, compártelo. Además, si aún no has echado un vistazo a nuestros Angular componentes, ¡asegúrate de hacerlo!

Ignite UI for Angular

Solicitar una demostración