La validació de formularis és una part essencial del desenvolupament d'aplicacions web, ja que garanteix que les dades introduïdes pels usuaris siguin correctes i compleixin amb els requisits especificats. En Angular, la validació de formularis es pot fer de manera senzilla i eficient utilitzant formularis basats en plantilles o formularis reactius.

Objectius d'aquest tema

  • Comprendre la importància de la validació de formularis.
  • Aprendre a implementar validacions bàsiques i personalitzades en formularis basats en plantilles.
  • Aprendre a implementar validacions bàsiques i personalitzades en formularis reactius.
  • Gestionar els estats de validació i proporcionar retroalimentació a l'usuari.

Tipus de validació

  1. Validació bàsica: Validacions predefinides com ara requerit, mínim, màxim, patró, etc.
  2. Validació personalitzada: Validacions definides per l'usuari per a requisits específics.

Validació en formularis basats en plantilles

Exemple de validació bàsica

<form #form="ngForm" (ngSubmit)="onSubmit(form)">
  <div>
    <label for="name">Nom:</label>
    <input type="text" id="name" name="name" ngModel required minlength="3">
    <div *ngIf="form.submitted && form.controls.name?.invalid">
      <small *ngIf="form.controls.name?.errors?.required">El nom és requerit.</small>
      <small *ngIf="form.controls.name?.errors?.minlength">El nom ha de tenir almenys 3 caràcters.</small>
    </div>
  </div>
  <button type="submit">Enviar</button>
</form>

Explicació

  • ngModel: Enllaça el camp del formulari amb el model de dades.
  • required, minlength: Atributs de validació HTML5.
  • form.controls.name?.invalid: Verifica si el camp és invàlid.
  • form.controls.name?.errors?.required: Verifica si l'error és perquè el camp és requerit.
  • form.controls.name?.errors?.minlength: Verifica si l'error és perquè el camp no compleix amb la longitud mínima.

Exemple de validació personalitzada

<form #form="ngForm" (ngSubmit)="onSubmit(form)">
  <div>
    <label for="email">Correu electrònic:</label>
    <input type="email" id="email" name="email" ngModel emailValidator>
    <div *ngIf="form.submitted && form.controls.email?.invalid">
      <small *ngIf="form.controls.email?.errors?.emailValidator">El correu electrònic no és vàlid.</small>
    </div>
  </div>
  <button type="submit">Enviar</button>
</form>
import { Directive } from '@angular/core';
import { NG_VALIDATORS, Validator, AbstractControl, ValidationErrors } from '@angular/forms';

@Directive({
  selector: '[emailValidator]',
  providers: [{ provide: NG_VALIDATORS, useExisting: EmailValidatorDirective, multi: true }]
})
export class EmailValidatorDirective implements Validator {
  validate(control: AbstractControl): ValidationErrors | null {
    const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
    const valid = emailRegex.test(control.value);
    return valid ? null : { emailValidator: true };
  }
}

Explicació

  • emailValidator: Directiva personalitzada per validar correus electrònics.
  • validate: Mètode que retorna un objecte d'errors si la validació falla.

Validació en formularis reactius

Exemple de validació bàsica

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-reactive-form',
  template: `
    <form [formGroup]="form" (ngSubmit)="onSubmit()">
      <div>
        <label for="name">Nom:</label>
        <input id="name" formControlName="name">
        <div *ngIf="form.controls.name.invalid && (form.controls.name.dirty || form.controls.name.touched)">
          <small *ngIf="form.controls.name.errors.required">El nom és requerit.</small>
          <small *ngIf="form.controls.name.errors.minlength">El nom ha de tenir almenys 3 caràcters.</small>
        </div>
      </div>
      <button type="submit" [disabled]="form.invalid">Enviar</button>
    </form>
  `
})
export class ReactiveFormComponent {
  form: FormGroup;

  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      name: ['', [Validators.required, Validators.minLength(3)]]
    });
  }

  onSubmit() {
    if (this.form.valid) {
      console.log('Form Submitted!', this.form.value);
    }
  }
}

Explicació

  • FormBuilder: Servei per crear formularis reactius.
  • formControlName: Enllaça el camp del formulari amb el control del formulari.
  • Validators.required, Validators.minLength(3): Validacions predefinides.

Exemple de validació personalitzada

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

export function emailValidator(): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {
    const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
    const valid = emailRegex.test(control.value);
    return valid ? null : { emailValidator: true };
  };
}
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-reactive-form',
  template: `
    <form [formGroup]="form" (ngSubmit)="onSubmit()">
      <div>
        <label for="email">Correu electrònic:</label>
        <input id="email" formControlName="email">
        <div *ngIf="form.controls.email.invalid && (form.controls.email.dirty || form.controls.email.touched)">
          <small *ngIf="form.controls.email.errors.emailValidator">El correu electrònic no és vàlid.</small>
        </div>
      </div>
      <button type="submit" [disabled]="form.invalid">Enviar</button>
    </form>
  `
})
export class ReactiveFormComponent {
  form: FormGroup;

  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      email: ['', [emailValidator()]]
    });
  }

  onSubmit() {
    if (this.form.valid) {
      console.log('Form Submitted!', this.form.value);
    }
  }
}

Explicació

  • emailValidator: Funció de validació personalitzada per validar correus electrònics.
  • ValidatorFn: Tipus de funció de validació en Angular.

Exercicis pràctics

Exercici 1: Validació bàsica en formularis basats en plantilles

Crea un formulari basat en plantilles amb els següents camps:

  • Nom (requerit, mínim 3 caràcters)
  • Correu electrònic (requerit, patró de correu electrònic)

Solució

<form #form="ngForm" (ngSubmit)="onSubmit(form)">
  <div>
    <label for="name">Nom:</label>
    <input type="text" id="name" name="name" ngModel required minlength="3">
    <div *ngIf="form.submitted && form.controls.name?.invalid">
      <small *ngIf="form.controls.name?.errors?.required">El nom és requerit.</small>
      <small *ngIf="form.controls.name?.errors?.minlength">El nom ha de tenir almenys 3 caràcters.</small>
    </div>
  </div>
  <div>
    <label for="email">Correu electrònic:</label>
    <input type="email" id="email" name="email" ngModel required email>
    <div *ngIf="form.submitted && form.controls.email?.invalid">
      <small *ngIf="form.controls.email?.errors?.required">El correu electrònic és requerit.</small>
      <small *ngIf="form.controls.email?.errors?.email">El correu electrònic no és vàlid.</small>
    </div>
  </div>
  <button type="submit">Enviar</button>
</form>

Exercici 2: Validació personalitzada en formularis reactius

Crea un formulari reactiu amb els següents camps:

  • Nom (requerit, mínim 3 caràcters)
  • Correu electrònic (validació personalitzada per correu electrònic)

Solució

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-reactive-form',
  template: `
    <form [formGroup]="form" (ngSubmit)="onSubmit()">
      <div>
        <label for="name">Nom:</label>
        <input id="name" formControlName="name">
        <div *ngIf="form.controls.name.invalid && (form.controls.name.dirty || form.controls.name.touched)">
          <small *ngIf="form.controls.name.errors.required">El nom és requerit.</small>
          <small *ngIf="form.controls.name.errors.minlength">El nom ha de tenir almenys 3 caràcters.</small>
        </div>
      </div>
      <div>
        <label for="email">Correu electrònic:</label>
        <input id="email" formControlName="email">
        <div *ngIf="form.controls.email.invalid && (form.controls.email.dirty || form.controls.email.touched)">
          <small *ngIf="form.controls.email.errors.emailValidator">El correu electrònic no és vàlid.</small>
        </div>
      </div>
      <button type="submit" [disabled]="form.invalid">Enviar</button>
    </form>
  `
})
export class ReactiveFormComponent {
  form: FormGroup;

  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      name: ['', [Validators.required, Validators.minLength(3)]],
      email: ['', [emailValidator()]]
    });
  }

  onSubmit() {
    if (this.form.valid) {
      console.log('Form Submitted!', this.form.value);
    }
  }
}

Conclusió

La validació de formularis en Angular és una eina poderosa que permet assegurar la qualitat de les dades introduïdes pels usuaris. Tant si utilitzes formularis basats en plantilles com formularis reactius, Angular proporciona una àmplia gamma d'opcions per implementar validacions bàsiques i personalitzades. Practicar amb exemples i exercicis t'ajudarà a dominar aquestes tècniques i a crear aplicacions més robustes i fiables.

Curs d'Angular

Mòdul 1: Introducció a Angular

Mòdul 2: Components d'Angular

Mòdul 3: Enllaç de dades i directives

Mòdul 4: Serveis i injecció de dependències

Mòdul 5: Enrutament i navegació

Mòdul 6: Formularis a Angular

Mòdul 7: Client HTTP i observables

Mòdul 8: Gestió d'estat

Mòdul 9: Proves a Angular

Mòdul 10: Conceptes avançats d'Angular

Mòdul 11: Desplegament i millors pràctiques

© Copyright 2024. Tots els drets reservats