Skip to main content

Form Utilities

Tess UI Library fornisce un set completo di utilità per semplificare il lavoro con i form reattivi di Angular.

Async Validator Registry

Il servizio AsyncValidatorRegistry permette di registrare e gestire validatori asincroni dinamicamente.

Uso Base

import { Component, inject } from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { AsyncValidatorRegistry, CommonAsyncValidators } from '@tess-ui-library/core';

@Component({
selector: 'app-registration',
standalone: true,
imports: [ReactiveFormsModule],
template: `
<input [formControl]="emailControl" />
@if (emailControl.errors?.['uniqueEmail']) {
<span>Questa email è già in uso</span>
}
`
})
export class RegistrationComponent {
private validatorRegistry = inject(AsyncValidatorRegistry);

emailControl = new FormControl('', {
asyncValidators: this.validatorRegistry.getAsyncValidator('uniqueEmail')!
});

constructor() {
// Registra il validatore all'avvio dell'app (es. in APP_INITIALIZER)
this.validatorRegistry.registerAsyncValidator(
'uniqueEmail',
CommonAsyncValidators.uniqueEmail((email) =>
this.checkEmailExists(email)
)
);
}

private checkEmailExists(email: string): Promise<boolean> {
return this.http.get<boolean>(\`/api/users/check-email?email=\${email}\`)
.toPromise();
}
}

Registrazione Globale

È raccomandato registrare i validatori asincroni globalmente all'avvio dell'applicazione:

// app.config.ts
import { APP_INITIALIZER, ApplicationConfig } from '@angular/core';
import { AsyncValidatorRegistry, CommonAsyncValidators } from '@tess-ui-library/core';
import { UserService } from './services/user.service';

export function initializeValidators(
registry: AsyncValidatorRegistry,
userService: UserService
): () => void {
return () => {
registry.registerAsyncValidator(
'uniqueEmail',
CommonAsyncValidators.uniqueEmail((email) =>
userService.checkEmailExists(email)
)
);

registry.registerAsyncValidator(
'uniqueUsername',
CommonAsyncValidators.uniqueValue((username) =>
userService.checkUsernameExists(username)
)
);
};
}

export const appConfig: ApplicationConfig = {
providers: [
{
provide: APP_INITIALIZER,
useFactory: initializeValidators,
deps: [AsyncValidatorRegistry, UserService],
multi: true,
},
],
};

API

registerAsyncValidator(name: string, validator: AsyncValidatorFn): void

Registra un validatore asincrono con un nome specifico.

getAsyncValidator(name: string): AsyncValidatorFn | undefined

Recupera un validatore asincrono registrato per nome.

unregisterAsyncValidator(name: string): void

Rimuove un validatore asincrono registrato.

hasAsyncValidator(name: string): boolean

Verifica se un validatore asincrono è registrato con il nome specificato.

Common Async Validators

La libreria fornisce validatori asincroni pronti all'uso:

uniqueEmail(checkFn: (email: string) => Promise<boolean>)

Validatore per verificare l'unicità di un'email.

CommonAsyncValidators.uniqueEmail((email) =>
this.userService.checkEmailExists(email)
)

uniqueValue(checkFn: (value: any) => Promise<boolean>)

Validatore generico per verificare l'unicità di un valore.

CommonAsyncValidators.uniqueValue((username) =>
this.userService.checkUsernameExists(username)
)

Form Helpers

markAllAsTouched(form: FormGroup): void

Marca tutti i controlli di un form come "touched", utile per mostrare tutti gli errori di validazione.

import { markAllAsTouched } from '@tess-ui-library/core';

onSubmit() {
if (this.form.invalid) {
markAllAsTouched(this.form);
return;
}
// submit logic...
}

resetForm(form: FormGroup): void

Resetta un form ai suoi valori iniziali e marca tutti i controlli come "untouched" e "pristine".

import { resetForm } from '@tess-ui-library/core';

onCancel() {
resetForm(this.form);
}

getFormErrors(form: FormGroup): Record<string, any>

Estrae tutti gli errori di validazione da un form in un oggetto flat.

import { getFormErrors } from '@tess-ui-library/core';

const errors = getFormErrors(this.form);
console.log(errors);
// Output: { 'email': { required: true }, 'age': { min: { min: 18, actual: 16 } } }

Error Messages

getErrorMessage(errors: ValidationErrors, fieldLabel?: string): string

Converte gli errori di validazione in messaggi leggibili.

import { getErrorMessage } from '@tess-ui-library/core';

const emailControl = this.form.get('email');
if (emailControl?.errors) {
const message = getErrorMessage(emailControl.errors, 'Email');
console.log(message); // "Email is required"
}

Messaggi Personalizzati

Puoi configurare messaggi di errore personalizzati:

import { ERROR_MESSAGES } from '@tess-ui-library/core';

// Nel tuo app.config.ts
{
provide: ERROR_MESSAGES,
useValue: {
required: (field: string) => \`Il campo \${field} è obbligatorio\`,
email: () => 'Inserisci un indirizzo email valido',
minlength: (field: string, error: any) =>
\`\${field} deve avere almeno \${error.requiredLength} caratteri\`,
}
}

Input Masks

applyCurrencyMask(value: string): string

Applica una maschera di valuta a un valore.

import { applyCurrencyMask } from '@tess-ui-library/core';

const masked = applyCurrencyMask('1234.56');
console.log(masked); // "€ 1.234,56" (o formato locale)

applyPhoneMask(value: string): string

Applica una maschera telefonica a un valore.

import { applyPhoneMask } from '@tess-ui-library/core';

const masked = applyPhoneMask('1234567890');
console.log(masked); // "+1 (123) 456-7890"

Custom Masks

Puoi definire maschere personalizzate usando una direttiva:

import { Directive, HostListener } from '@angular/core';

@Directive({
selector: '[appCreditCardMask]',
standalone: true,
})
export class CreditCardMaskDirective {
@HostListener('input', ['$event'])
onInput(event: Event) {
const input = event.target as HTMLInputElement;
let value = input.value.replace(/\s/g, '');

// Aggiungi spazi ogni 4 cifre
const formatted = value.match(/.{1,4}/g)?.join(' ') || '';
input.value = formatted;
}
}

Best Practices

  1. Registra validatori globalmente: Usa APP_INITIALIZER per registrare validatori asincroni all'avvio
  2. Debounce validatori asincroni: Usa updateOn: 'blur' o debounceTime per evitare chiamate API eccessive
  3. Messaggi di errore consistenti: Usa ERROR_MESSAGES token per messaggi centralizzati
  4. Form groups annidati: Usa getFormErrors per gestire errori in strutture complesse
  5. Cleanup: Ricordati di fare unsubscribe dai validatori quando il componente viene distrutto

Vedi Anche