Reactive Form Validation avec Bootstrap 5 et Angular

Nous allons voir comment afficher des messages d'erreur dans notre formulaire Reactive Form avec Bootstrap 5 et Angular.


Pour cela nous allons prendre l'exemple d'un formulaire permettant de publier des posts (un post possède trois champs : title, content et category).

Création du formulaire

Tout d'abord nous allons créer notre FormGroup dans notre composant Angular. Les messages d'erreur se baseront sur les Validators de chaque FormControl.

export class FormComponent implements OnInit {

  form: FormGroup

  constructor(private fb: FormBuilder) { }

  ngOnInit(): void {
    this.initForm()
  }

  initForm() {
    this.form = this.fb.group({
      title: ['', [Validators.required, Validators.minLength(3)]],
      content: ['', [Validators.required, Validators.minLength(3)]],
      category: [null, [Validators.required]]
    })
  }
  
  get title() { return this.form.get('title') }

  get content() { return this.form.get('content') }

  get category() { return this.form.get('category') }
  
}

Fichier form.component.ts

Pour simplifier l'utilisation des FormControl dans le template HTML, nous déclarons des getters pour chaque FormControl du formulaire.


Côté HTML nous ajoutons notre formulaire en respectant bien les balises et les classes conseillées par la documentation de Bootstrap pour les formulaires.

<form [formGroup]="form" *ngIf="form">
    <div class="mb-3">
        <label for="title" class="form-label">Title</label>
        <input type="text" class="form-control" 
               id="title" formControlName="title"> 
    </div>
    <!-- ... -->
</form>

Nous avons l'attribut "formGroup" pour lier le formulaire HTML avec l'objet FormGroup de notre composant. Et nous ajoutons l'attribut "formControlName" sur chaque input pour les lier aux FormControl de notre formulaire.

Mettre en forme le champ invalide

Pour qu'un champ s'affiche en rouge lorsqu'il est invalide, nous devons ajouter la classe Bootstrap "is-invalid" sur la balise input.


Pour l'expérience utilisateur, nous allons afficher le champ en rouge uniquement lorsque celui-ci est invalide et a été touché ou modifié par l'utilisateur.


Pour cela nous allons utiliser les attributs touched et dirty de l'objet FormControl.

<div class="mb-3">
    <label for="title" class="form-label">Title</label>
    <input type="text" class="form-control" 
           id="title" formControlName="title" 
           [class.is-invalid]="title.invalid 
                                && (title.touched || title.dirty)">
        
</div>

Le code ci-dessus se traduit par, si mon champ est invalide et qu'il a été touché ou modifié par l'utilisateur, alors j'ajoute la classe is-invalid.

Ajout de la classe is-invalid lorsque le champ est invalide

Un champ est déclaré comme invalide lorsqu'il ne respecte pas ses Validators. Dans le cas du champ "title", il doit être renseigné et faire au minimum 3 caractères, sinon il est invalide.

Afficher le message d'erreur

Pour afficher un message d'erreur en dessous d'un champ invalide, nous devons utiliser la classe Bootstrap "invalid-feedback".

Un élément HTML avec la classe "invalid-feedback" n'est visible que lorsqu'un élément voisin possède la classe "is-invalid".

Nous utilisons ensuite la propriété "errors" du FormControl pour distinguer les erreurs de chaque Validators et afficher un message pertinent à l'utilisateur.

<div class="mb-3">
    <label for="title" class="form-label">Title</label>
    <input type="text" class="form-control" 
           id="title" formControlName="title" 
           [class.is-invalid]="title.invalid 
                                && (title.touched || title.dirty)">
    
    <div class="invalid-feedback" *ngIf="title.errors">
        <ng-container *ngIf="title.errors['required']">
            The title is required
        </ng-container>
        <ng-container *ngIf="title.errors['minlength']">
            The title must have a minimum of 3 characters
        </ng-container>
    </div>
</div>

L'utilisateur est guidé grâce aux messages d'erreur qui s'adaptent au fur et à mesure qu'il remplit le champ.

Validation du formulaire

Si l'utilisateur oubli certains champs et qu'il valide le formulaire, nous devons lui indiquer que le formulaire n'est pas valide en affichant les champs en erreur.


Pour cela, une astuce consiste à marquer tous les FormControl comme "touched" grâce à la méthode markAllAsTouched du FormGroup.


Le fait de marquer tous les FormControl comme "touched" va valider notre condition côté HTML qui ajoute la classe "is-invalid", ce qui provoque l'affichage de notre "invalid-feedback".

<form [formGroup]="form" *ngIf="form" (ngSubmit)="createPost()">
    <!-- ... -->
</form>
  createPost() {
    if (this.form.invalid) {
      this.form.markAllAsTouched()
      return
    }
    // ...
  }

Voilà le résultat final avec un formulaire plus complet.

Conclusion

Nous avons mis en place la validation d'un formulaire de type ReactiveForm en utilisant le style de Bootstrap 5.


Pour cela nous avons utilisé les classes "is-invalid" et "invalid-feedback" de Bootstrap. Côté Angular nous avons aussi utilisé les variables "invalid", "touched", "dirty", "errors" et la méthode "markAllAsTouched".


Notre code est simple et facile à comprendre, tout en fournissant une bonne expérience à l'utilisateur.

Abonnez vous pour ne pas rater les nouveaux articles !

© Gaëtan Rouziès - Tous Droits Réservés