📢 Je vous présente le livre Angular

  • 1) Il offre un contenu clair et concis, tout en couvrant une multitude de concepts d'Angular.
  • 2) Le livre est structuré en trois niveaux : débutant, intermédiaire et avancé
  • 3) traite des pratiques les plus récentes d'Angular, comme les signaux, les vues différées, la gestion des flux, entre autres
  • 4) De plus, vous y trouverez plusieurs liens vers des exemples de code source pour approfondir vos connaissances en pratique.
Consulter un extrait

Skip to content

Comment créer une fonction personnalisée de validation ?

Voici comment vous pouvez créer une fonction de validation personnalisée et l'ajouter à un FormControl dans Angular:

  1. Créez votre fonction de validation en implémentant l'interface ValidatorFn de Angular:
ts
import { ValidatorFn } from '@angular/forms';

export function emailValidator(): ValidatorFn {
  return (control: AbstractControl<string>): {[key: string]: any} | null => {
    const forbidden = !control.value.endsWith('gmail.com');
    return forbidden ? {'forbiddenEmail': {value: control.value}} : null;
  };
}
  1. Ajoutez la fonction de validation à un FormControl:
ts
import { FormControl } from '@angular/forms';

const emailControl = new FormControl('', emailValidator());

La fonction de validation doit renvoyer un objet contenant une clé et une valeur si la validation échoue, ou null si elle réussit. Si elle renvoie null, cela signifie que le contrôle de formulaire est considéré comme valide. Si elle renvoie un objet, le contrôle de formulaire est considéré comme invalide et le contenu de l'objet est associé au contrôle de formulaire comme une erreur de validation.

Par exemple, dans l'exemple de code ci-dessus, si la valeur du contrôle de formulaire se termine par "gmail.com", la fonction renvoie null, indiquant que le contrôle de formulaire est valide. Si la valeur du contrôle de formulaire ne se termine pas par "gmail.com", la fonction renvoie un objet avec la clé "forbiddenEmail" et la valeur de la valeur du contrôle de formulaire comme valeur.

Vous pouvez utiliser ces erreurs de validation dans votre template HTML pour afficher des messages d'erreur à l'utilisateur ou pour effectuer d'autres actions. Par exemple:

angular-html
@if (emailControl.hasError('forbiddenEmail')) {
  <div >
    Email is invalid.
  </div>
}

Le type de retour de la fonction de validation étant un objet, vous pouvez également ajouter plusieurs erreurs de validation différentes à l'objet renvoyé. Cela vous permet de valider plusieurs règles de validation en même temps pour un même contrôle de formulaire.

Fonction de validation avec des paramètres

Voici comment vous pouvez rendre la fonction de validation plus générique en lui passant une chaîne de caractères comme paramètre:

ts
import { ValidatorFn } from '@angular/forms';

export function emailValidator(domain: string): ValidatorFn {
  return (control: AbstractControl<string>): {[key: string]: any} | null => {
    const forbidden = !control.value.endsWith(domain);
    return forbidden ? {'forbiddenEmail': {value: control.value}} : null;
  };
}

Vous pouvez maintenant utiliser la fonction de validation comme ceci:

ts
const emailControl = new FormControl('', emailValidator('gmail.com'));

Cela vous permet de valider si la valeur du contrôle de formulaire se termine par n'importe quel domaine de votre choix en passant le domaine en tant que paramètre de la fonction de validation.

Mettre une fonction de validation sur un FormGroup

Parfois, nous avons besoin de valider plusieurs champs en même temps ou de comparer leurs valeurs. C'est là que la validation au niveau du FormGroup entre en jeu. Prenons l'exemple classique de la confirmation d'un mot de passe.

Cas d'utilisation

Imaginez que vous créez un formulaire d'inscription où l'utilisateur doit entrer son mot de passe deux fois pour confirmation. Vous voulez vous assurer que les deux champs contiennent la même valeur.

Voici comment créer une fonction de validation personnalisée pour un FormGroup :

ts
import { AbstractControl, ValidationErrors, ValidatorFn, FormGroup } from '@angular/forms';

export const passwordMatchValidator: ValidatorFn = (group: AbstractControl<FormGroup>): ValidationErrors | null => {
  const password = group.get('password');
  const confirmPassword = group.get('confirmPassword');

  if (password && confirmPassword && password.value !== confirmPassword.value) {
    return { passwordMismatch: true };
  }

  return null;
};
ts
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { passwordMatchValidator } from './password-match.validator';

@Component({
  selector: 'app-signup',
  standalone: true,
  template: `
    <form [formGroup]="signupForm" (ngSubmit)="onSubmit()">
      <input formControlName="password" type="password" placeholder="Mot de passe">
      <input formControlName="confirmPassword" type="password" placeholder="Confirmer le mot de passe">
      @if (signupForm.hasError('passwordMismatch')) {
        <div class="error">Les mots de passe ne correspondent pas.</div>
      }
      <button type="submit" [disabled]="signupForm.invalid">S'inscrire</button>
    </form>
  `
})
export class SignupComponent {
  private fb = inject(FormBuilder);
  signupForm = this.fb.group({
      password: ['', [Validators.required, Validators.minLength(6)]],
      confirmPassword: ['', Validators.required]
    }, { validators: passwordMatchValidator });

  onSubmit() {
    if (this.signupForm.valid) {
      console.log('Formulaire valide', this.signupForm.value);
    }
  }
}

Expliquons ce code :

  1. Dans password-match.validator.ts, nous définissons une fonction de validation qui prend un AbstractControl (qui sera notre FormGroup) comme argument.

  2. La fonction récupère les contrôles 'password' et 'confirmPassword' du FormGroup.

  3. Elle compare leurs valeurs et retourne une erreur si elles ne correspondent pas.

  4. Dans signup.component.ts, nous créons notre FormGroup avec FormBuilder et ajoutons notre validateur personnalisé au niveau du groupe.

Attention

N'oubliez pas d'ajouter des validateurs individuels aux champs de mot de passe (comme Validators.required et Validators.minLength) pour une validation complète.

Conseil

Pour une meilleure réutilisabilité, vous pouvez rendre votre validateur plus générique en lui permettant de prendre les noms des champs à comparer comme paramètres.

Chaque mois, recevez en avant-première notre newsletter avec les dernières actualités, tutoriels, astuces et ressources Angular directement par email !