Validators
Tess UI Library fornisce un set di validatori personalizzati per i form Angular.
Validatori Sincroni
emailValidator
Valida che un valore sia un indirizzo email valido.
import { emailValidator } from '@tess-ui-library/core';
import { FormControl } from '@angular/forms';
const control = new FormControl('', emailValidator);
control.setValue('invalid-email');
console.log(control.errors); // { email: true }
control.setValue('user@example.com');
console.log(control.errors); // null
urlValidator
Valida che un valore sia un URL valido.
import { urlValidator } from '@tess-ui-library/core';
const control = new FormControl('', urlValidator);
control.setValue('not-a-url');
console.log(control.errors); // { url: true }
control.setValue('https://example.com');
console.log(control.errors); // null
phoneValidator
Valida che un valore sia un numero di telefono valido (formati internazionali).
import { phoneValidator } from '@tess-ui-library/core';
const control = new FormControl('', phoneValidator);
control.setValue('123');
console.log(control.errors); // { phone: true }
control.setValue('+39 333 1234567');
console.log(control.errors); // null
alphanumericValidator
Valida che un valore contenga solo caratteri alfanumerici.
import { alphanumericValidator } from '@tess-ui-library/core';
const control = new FormControl('', alphanumericValidator);
control.setValue('Hello@World');
console.log(control.errors); // { alphanumeric: true }
control.setValue('HelloWorld123');
console.log(control.errors); // null
matchValidator(fieldName: string)
Valida che due campi abbiano lo stesso valore (utile per conferma password).
import { matchValidator } from '@tess-ui-library/core';
import { FormGroup, FormControl } from '@angular/forms';
const form = new FormGroup({
password: new FormControl(''),
confirmPassword: new FormControl('', matchValidator('password')),
});
form.patchValue({
password: 'secret123',
confirmPassword: 'different',
});
console.log(form.get('confirmPassword')?.errors); // { match: true }
form.patchValue({
confirmPassword: 'secret123',
});
console.log(form.get('confirmPassword')?.errors); // null
rangeValidator(min: number, max: number)
Valida che un numero sia compreso in un intervallo.
import { rangeValidator } from '@tess-ui-library/core';
const control = new FormControl('', rangeValidator(18, 65));
control.setValue(16);
console.log(control.errors); // { range: { min: 18, max: 65, actual: 16 } }
control.setValue(25);
console.log(control.errors); // null
dateRangeValidator(minDate?: Date, maxDate?: Date)
Valida che una data sia compresa in un intervallo.
import { dateRangeValidator } from '@tess-ui-library/core';
const minDate = new Date('2024-01-01');
const maxDate = new Date('2024-12-31');
const control = new FormControl('', dateRangeValidator(minDate, maxDate));
control.setValue(new Date('2023-06-15'));
console.log(control.errors); // { dateRange: { min: minDate, max: maxDate } }
control.setValue(new Date('2024-06-15'));
console.log(control.errors); // null
fileSizeValidator(maxSizeInBytes: number)
Valida la dimensione massima di un file.
import { fileSizeValidator } from '@tess-ui-library/core';
const control = new FormControl('', fileSizeValidator(1024 * 1024)); // 1MB
// In un file input change handler
onFileChange(event: Event) {
const file = (event.target as HTMLInputElement).files?.[0];
if (file) {
this.control.setValue(file);
}
}
fileTypeValidator(allowedTypes: string[])
Valida il tipo MIME di un file.
import { fileTypeValidator } from '@tess-ui-library/core';
const control = new FormControl('',
fileTypeValidator(['image/png', 'image/jpeg', 'image/gif'])
);
Validatori Compositi
composeValidators(...validators: ValidatorFn[])
Compone più validatori in uno solo.
import { composeValidators, emailValidator, urlValidator } from '@tess-ui-library/core';
import { Validators } from '@angular/forms';
const control = new FormControl('',
composeValidators(
Validators.required,
Validators.minLength(5),
emailValidator
)
);
Validatori Condizionali
conditionalValidator(condition: () => boolean, validator: ValidatorFn)
Applica un validatore solo quando una condizione è vera.
import { conditionalValidator } from '@tess-ui-library/core';
import { Validators } from '@angular/forms';
const form = new FormGroup({
requiresDetails: new FormControl(false),
details: new FormControl('',
conditionalValidator(
() => form.get('requiresDetails')?.value === true,
Validators.required
)
),
});
Validatori Cross-Field
passwordMatchValidator
Validatore per FormGroup che verifica che password e confirmPassword coincidano.
import { passwordMatchValidator } from '@tess-ui-library/core';
import { FormGroup, FormControl } from '@angular/forms';
const form = new FormGroup({
password: new FormControl(''),
confirmPassword: new FormControl(''),
}, { validators: passwordMatchValidator });
form.patchValue({
password: 'secret123',
confirmPassword: 'different',
});
console.log(form.errors); // { passwordMismatch: true }
form.patchValue({
confirmPassword: 'secret123',
});
console.log(form.errors); // null
dateRangeGroupValidator(startDateKey: string, endDateKey: string)
Valida che una data di inizio sia precedente a una data di fine.
import { dateRangeGroupValidator } from '@tess-ui-library/core';
import { FormGroup, FormControl } from '@angular/forms';
const form = new FormGroup({
startDate: new FormControl(new Date('2024-06-01')),
endDate: new FormControl(new Date('2024-05-01')),
}, { validators: dateRangeGroupValidator('startDate', 'endDate') });
console.log(form.errors); // { dateRangeInvalid: true }
Uso con AutoForm
I validatori possono essere usati direttamente nei modelli AutoForm:
import { FormModel } from '@tess-ui-library/core';
const formModel: FormModel = {
id: 'user-form',
fields: [
{
key: 'email',
type: 'email',
label: 'Email',
validation: {
required: true,
custom: emailValidator, // Usa validatore custom
},
},
{
key: 'phone',
type: 'text',
label: 'Telefono',
validation: {
custom: phoneValidator,
},
},
{
key: 'age',
type: 'number',
label: 'Età',
validation: {
custom: rangeValidator(18, 100),
},
},
],
};
Creazione Validatori Personalizzati
Validatore Sincrono
import { AbstractControl, ValidatorFn, ValidationErrors } from '@angular/forms';
export function customValidator(param: string): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const value = control.value;
if (!value) {
return null; // Non validare se vuoto (usa 'required' per questo)
}
// La tua logica di validazione
const isValid = value.includes(param);
return isValid ? null : {
customError: {
requiredValue: param,
actualValue: value,
},
};
};
}
Validatore Asincrono
import { AbstractControl, AsyncValidatorFn, ValidationErrors } from '@angular/forms';
import { Observable, of, delay, map } from 'rxjs';
export function asyncCustomValidator(
checkFn: (value: any) => Observable<boolean>
): AsyncValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors | null> => {
if (!control.value) {
return of(null);
}
return checkFn(control.value).pipe(
map(exists => (exists ? { asyncError: true } : null))
);
};
}
Best Practices
- Riutilizza validatori: Crea validatori riutilizzabili per logiche comuni
- Messaggi chiari: Fornisci messaggi di errore descrittivi
- Validazione incrementale: Usa validatori sincroni prima di quelli asincroni
- Performance: Usa
updateOn: 'blur'per validatori costosi - Composizione: Usa
composeValidatorsper combinare più validatori - Type-safety: Definisci interfacce TypeScript per i tuoi dati di form