Validazione
Introduzione
Nylo Website v7 fornisce un sistema di validazione costruito attorno alla classe FormValidator. Puoi validare i dati all'interno delle pagine utilizzando il metodo check(), o usare FormValidator direttamente per la validazione standalone e a livello di campo.
// Validate data in a NyPage/NyState using check()
check((validate) {
validate.that('user@example.com').email();
validate.that('Anthony')
.capitalized()
.maxLength(50);
}, onSuccess: () {
print("All validations passed!");
});
// FormValidator with form fields
Field.text("Email", validator: FormValidator.email())
Validare i Dati con check()
All'interno di qualsiasi NyPage, usa il metodo check() per validare i dati. Accetta una callback che riceve una lista di validatori. Usa .that() per aggiungere dati e concatenare regole:
class _RegisterPageState extends NyPage<RegisterPage> {
void handleForm() {
check((validate) {
validate.that(_emailController.text, label: "Email").email();
validate.that(_passwordController.text, label: "Password")
.notEmpty()
.password(strength: 2);
}, onSuccess: () {
// Tutte le validazioni superate
_submitForm();
}, onValidationError: (FormValidationResponseBag bag) {
// Validazione fallita
print(bag.firstErrorMessage);
});
}
}
Come Funziona check()
check()crea unaList<FormValidator>vuota- La tua callback usa
.that(data)per aggiungere un nuovoFormValidatorcon dati alla lista - Ogni
.that()restituisce unFormValidatorsu cui puoi concatenare regole - Dopo la callback, ogni validatore nella lista viene controllato
- I risultati vengono raccolti in un
FormValidationResponseBag
Validare Campi Multipli
check((validate) {
validate.that(_nameController.text, label: "Name").notEmpty().capitalized();
validate.that(_emailController.text, label: "Email").email();
validate.that(_phoneController.text, label: "Phone").phoneNumberUs();
validate.that(_ageController.text, label: "Age").numeric().minValue(18);
}, onSuccess: () {
_submitForm();
});
Il parametro opzionale label imposta un nome leggibile utilizzato nei messaggi di errore (es. "The Email must be a valid email address.").
Risultati della Validazione
Il metodo check() restituisce un FormValidationResponseBag (una List<FormValidationResult>), che puoi anche ispezionare direttamente:
FormValidationResponseBag bag = check((validate) {
validate.that(_emailController.text, label: "Email").email();
validate.that(_passwordController.text, label: "Password")
.password(strength: 1);
});
if (bag.isValid) {
print("All valid!");
} else {
// Ottieni il primo messaggio di errore
String? error = bag.firstErrorMessage;
print(error);
// Ottieni tutti i risultati falliti
List<FormValidationResult> errors = bag.validationErrors;
// Ottieni tutti i risultati riusciti
List<FormValidationResult> successes = bag.validationSuccess;
}
FormValidationResult
Ogni FormValidationResult rappresenta il risultato della validazione di un singolo valore:
FormValidator validator = FormValidator(data: "test@email.com")
.email()
.maxLength(50);
FormValidationResult result = validator.check();
if (result.isValid) {
print("Valid!");
} else {
// Primo messaggio di errore
String? message = result.getFirstErrorMessage();
// Tutti i messaggi di errore
List<String> messages = result.errorMessages();
// Risposte di errore
List<FormValidationError> errors = result.errorResponses;
}
Utilizzare FormValidator
FormValidator puo' essere utilizzato standalone o con i campi del form.
Utilizzo Standalone
// Utilizzando un costruttore nominato
FormValidator validator = FormValidator.email();
FormValidationResult result = validator.check("user@example.com");
if (result.isValid) {
print("Email is valid");
} else {
String? errorMessage = result.getFirstErrorMessage();
print("Error: $errorMessage");
}
Con Dati nel Costruttore
FormValidator validator = FormValidator(data: "user@example.com", attribute: "Email")
.email()
.maxLength(50);
FormValidationResult result = validator.check();
print(result.isValid); // true
Costruttori Nominati di FormValidator
Nylo Website v7 fornisce costruttori nominati per le validazioni comuni:
// Validazione email
FormValidator.email(message: "Please enter a valid email")
// Validazione password (forza 1 o 2)
FormValidator.password(strength: 1)
FormValidator.password(strength: 2, message: "Password too weak")
// Numeri di telefono
FormValidator.phoneNumberUk()
FormValidator.phoneNumberUs()
// Validazione URL
FormValidator.url()
// Vincoli di lunghezza
FormValidator.minLength(5, message: "Too short")
FormValidator.maxLength(100, message: "Too long")
// Vincoli di valore
FormValidator.minValue(18, message: "Must be 18+")
FormValidator.maxValue(100)
// Vincoli di dimensione (per liste/stringhe)
FormValidator.minSize(2, message: "Select at least 2")
FormValidator.maxSize(5)
// Non vuoto
FormValidator.notEmpty(message: "This field is required")
// Contiene valori
FormValidator.contains(['option1', 'option2'])
// Inizia/finisce con
FormValidator.beginsWith("https://")
FormValidator.endsWith(".com")
// Controlli booleani
FormValidator.booleanTrue(message: "Must accept terms")
FormValidator.booleanFalse()
// Numerico
FormValidator.numeric()
// Validazioni di data
FormValidator.date()
FormValidator.dateInPast()
FormValidator.dateInFuture()
FormValidator.dateAgeIsOlder(18, message: "Must be 18+")
FormValidator.dateAgeIsYounger(65)
// Maiuscole/minuscole
FormValidator.uppercase()
FormValidator.lowercase()
FormValidator.capitalized()
// Formati di localizzazione
FormValidator.zipcodeUs()
FormValidator.postcodeUk()
// Pattern regex
FormValidator.regex(r'^[A-Z]{3}\d{4}$', message: "Invalid format")
// Validazione personalizzata
FormValidator.custom(
message: "Invalid value",
validate: (data) => data != null,
)
Concatenare Regole di Validazione
Concatena piu' regole in modo fluente utilizzando i metodi di istanza. Ogni metodo restituisce il FormValidator, permettendoti di costruire le regole:
FormValidator validator = FormValidator()
.notEmpty()
.email()
.maxLength(50);
FormValidationResult result = validator.check("user@example.com");
if (!result.isValid) {
List<String> errors = result.errorMessages();
print(errors);
}
Tutti i costruttori nominati hanno metodi di istanza concatenabili corrispondenti:
FormValidator()
.notEmpty(message: "Required")
.email(message: "Invalid email")
.minLength(5, message: "Too short")
.maxLength(100, message: "Too long")
.beginsWith("user", message: "Must start with 'user'")
.lowercase(message: "Must be lowercase")
Validazione Personalizzata
Regola Personalizzata (Inline)
Usa .custom() per aggiungere logica di validazione inline:
FormValidator.custom(
message: "Username already taken",
validate: (data) {
// Restituisci true se valido, false se non valido
return !_takenUsernames.contains(data);
},
)
Oppure concatenala con altre regole:
FormValidator()
.notEmpty()
.custom(
message: "Must start with a letter",
validate: (data) => RegExp(r'^[a-zA-Z]').hasMatch(data.toString()),
)
Validazione di Uguaglianza
Verifica se un valore corrisponde a un altro:
FormValidator()
.notEmpty()
.equals(
_passwordController.text,
message: "Passwords must match",
)
Utilizzare FormValidator con i Campi
FormValidator si integra con i widget Field nei form. Passa un validatore al parametro validator:
class RegisterForm extends NyFormData {
RegisterForm({String? name}) : super(name ?? "register");
@override
fields() => [
Field.text(
"Name",
autofocus: true,
validator: FormValidator.notEmpty(),
),
Field.email("Email", validator: FormValidator.email()),
Field.password(
"Password",
validator: FormValidator.password(strength: 1),
),
];
}
Puoi anche usare validatori concatenati con i campi:
Field.text(
"Username",
validator: FormValidator()
.notEmpty(message: "Username is required")
.minLength(3, message: "At least 3 characters")
.maxLength(20, message: "At most 20 characters"),
)
Field.slider(
"Rating",
validator: FormValidator.minValue(4, message: "Rating must be at least 4"),
)
Regole di Validazione Disponibili
Tutte le regole disponibili per FormValidator, sia come costruttori nominati che come metodi concatenabili:
| Regola | Costruttore Nominato | Metodo Concatenabile | Descrizione |
|---|---|---|---|
FormValidator.email() |
.email() |
Valida il formato email | |
| Password | FormValidator.password(strength: 1) |
.password(strength: 1) |
Forza 1: 8+ caratteri, 1 maiuscola, 1 cifra. Forza 2: + 1 carattere speciale |
| Non Vuoto | FormValidator.notEmpty() |
.notEmpty() |
Non puo' essere vuoto |
| Lunghezza Min | FormValidator.minLength(5) |
.minLength(5) |
Lunghezza minima della stringa |
| Lunghezza Max | FormValidator.maxLength(100) |
.maxLength(100) |
Lunghezza massima della stringa |
| Valore Min | FormValidator.minValue(18) |
.minValue(18) |
Valore numerico minimo (funziona anche su lunghezza stringa, lunghezza lista, lunghezza mappa) |
| Valore Max | FormValidator.maxValue(100) |
.maxValue(100) |
Valore numerico massimo |
| Dimensione Min | FormValidator.minSize(2) |
.minSize(2) |
Dimensione minima per liste/stringhe |
| Dimensione Max | FormValidator.maxSize(5) |
.maxSize(5) |
Dimensione massima per liste/stringhe |
| Contiene | FormValidator.contains(['a', 'b']) |
.contains(['a', 'b']) |
Il valore deve contenere uno dei valori dati |
| Inizia Con | FormValidator.beginsWith("https://") |
.beginsWith("https://") |
La stringa deve iniziare con il prefisso |
| Finisce Con | FormValidator.endsWith(".com") |
.endsWith(".com") |
La stringa deve finire con il suffisso |
| URL | FormValidator.url() |
.url() |
Valida il formato URL |
| Numerico | FormValidator.numeric() |
.numeric() |
Deve essere un numero |
| Booleano Vero | FormValidator.booleanTrue() |
.booleanTrue() |
Deve essere true |
| Booleano Falso | FormValidator.booleanFalse() |
.booleanFalse() |
Deve essere false |
| Data | FormValidator.date() |
.date() |
Deve essere una data valida |
| Data nel Passato | FormValidator.dateInPast() |
.dateInPast() |
La data deve essere nel passato |
| Data nel Futuro | FormValidator.dateInFuture() |
.dateInFuture() |
La data deve essere nel futuro |
| Eta' Maggiore | FormValidator.dateAgeIsOlder(18) |
.dateAgeIsOlder(18) |
L'eta' deve essere maggiore di N |
| Eta' Minore | FormValidator.dateAgeIsYounger(65) |
.dateAgeIsYounger(65) |
L'eta' deve essere minore di N |
| Capitalizzato | FormValidator.capitalized() |
.capitalized() |
La prima lettera deve essere maiuscola |
| Minuscolo | FormValidator.lowercase() |
.lowercase() |
Tutti i caratteri devono essere minuscoli |
| Maiuscolo | FormValidator.uppercase() |
.uppercase() |
Tutti i caratteri devono essere maiuscoli |
| Telefono US | FormValidator.phoneNumberUs() |
.phoneNumberUs() |
Formato numero di telefono US |
| Telefono UK | FormValidator.phoneNumberUk() |
.phoneNumberUk() |
Formato numero di telefono UK |
| Zipcode US | FormValidator.zipcodeUs() |
.zipcodeUs() |
Formato zipcode US |
| Postcode UK | FormValidator.postcodeUk() |
.postcodeUk() |
Formato postcode UK |
| Regex | FormValidator.regex(r'pattern') |
.regex(r'pattern') |
Deve corrispondere al pattern regex |
| Uguale | -- | .equals(otherValue) |
Deve essere uguale a un altro valore |
| Personalizzato | FormValidator.custom(validate: fn) |
.custom(validate: fn) |
Funzione di validazione personalizzata |
Tutte le regole accettano un parametro opzionale message per personalizzare il messaggio di errore.
Creare Regole di Validazione Personalizzate
Per creare una regola di validazione riutilizzabile, estendi la classe FormRule:
class FormRuleUsername extends FormRule {
@override
String? rule = "username";
@override
String? message = "The {{attribute}} must be a valid username.";
FormRuleUsername({String? message}) {
if (message != null) {
this.message = message;
}
}
@override
bool validate(data) {
if (data is! String) return false;
// Username: alfanumerico, underscore, 3-20 caratteri
return RegExp(r'^[a-zA-Z0-9_]{3,20}$').hasMatch(data);
}
}
Usa {{attribute}} come segnaposto nel message -- verra' sostituito con l'etichetta del campo a runtime.
Utilizzare un FormRule Personalizzato
Aggiungi la tua regola personalizzata a un FormValidator utilizzando FormValidator.rule():
FormValidator validator = FormValidator.rule([
FormRuleNotEmpty(),
FormRuleUsername(),
]);
FormValidationResult result = validator.check("my_username");
Oppure usa il metodo .custom() per regole una tantum senza creare una classe:
FormValidator()
.notEmpty()
.custom(
message: "Username must start with a letter",
validate: (data) => RegExp(r'^[a-zA-Z]').hasMatch(data.toString()),
)