Validation
Introduction
Nylo Website v7 fournit un systeme de validation construit autour de la classe FormValidator. Vous pouvez valider des donnees dans les pages en utilisant la methode check(), ou utiliser FormValidator directement pour la validation autonome et au niveau des champs.
// 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())
Valider des donnees avec check()
Dans n'importe quel NyPage, utilisez la methode check() pour valider des donnees. Elle accepte un callback qui recoit une liste de validateurs. Utilisez .that() pour ajouter des donnees et chainer les regles :
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: () {
// All validations passed
_submitForm();
}, onValidationError: (FormValidationResponseBag bag) {
// Validation failed
print(bag.firstErrorMessage);
});
}
}
Fonctionnement de check()
check()cree uneList<FormValidator>vide- Votre callback utilise
.that(data)pour ajouter un nouveauFormValidatoravec des donnees a la liste - Chaque
.that()retourne unFormValidatorsur lequel vous pouvez chainer des regles - Apres le callback, chaque validateur de la liste est verifie
- Les resultats sont collectes dans un
FormValidationResponseBag
Valider plusieurs champs
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();
});
Le parametre optionnel label definit un nom lisible utilise dans les messages d'erreur (par exemple, "The Email must be a valid email address.").
Resultats de validation
La methode check() retourne un FormValidationResponseBag (une List<FormValidationResult>), que vous pouvez aussi inspecter directement :
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 {
// Get the first error message
String? error = bag.firstErrorMessage;
print(error);
// Get all failed results
List<FormValidationResult> errors = bag.validationErrors;
// Get all successful results
List<FormValidationResult> successes = bag.validationSuccess;
}
FormValidationResult
Chaque FormValidationResult represente le resultat de la validation d'une seule valeur :
FormValidator validator = FormValidator(data: "test@email.com")
.email()
.maxLength(50);
FormValidationResult result = validator.check();
if (result.isValid) {
print("Valid!");
} else {
// First error message
String? message = result.getFirstErrorMessage();
// All error messages
List<String> messages = result.errorMessages();
// Error responses
List<FormValidationError> errors = result.errorResponses;
}
Utiliser FormValidator
FormValidator peut etre utilise de maniere autonome ou avec des champs de formulaire.
Utilisation autonome
// Using a named constructor
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");
}
Avec des donnees dans le constructeur
FormValidator validator = FormValidator(data: "user@example.com", attribute: "Email")
.email()
.maxLength(50);
FormValidationResult result = validator.check();
print(result.isValid); // true
Constructeurs nommes de FormValidator
Nylo Website v7 fournit des constructeurs nommes pour les validations courantes :
// Email validation
FormValidator.email(message: "Please enter a valid email")
// Password validation (strength 1 or 2)
FormValidator.password(strength: 1)
FormValidator.password(strength: 2, message: "Password too weak")
// Phone numbers
FormValidator.phoneNumberUk()
FormValidator.phoneNumberUs()
// URL validation
FormValidator.url()
// Length constraints
FormValidator.minLength(5, message: "Too short")
FormValidator.maxLength(100, message: "Too long")
// Value constraints
FormValidator.minValue(18, message: "Must be 18+")
FormValidator.maxValue(100)
// Size constraints (for lists/strings)
FormValidator.minSize(2, message: "Select at least 2")
FormValidator.maxSize(5)
// Not empty
FormValidator.notEmpty(message: "This field is required")
// Contains values
FormValidator.contains(['option1', 'option2'])
// Starts/ends with
FormValidator.beginsWith("https://")
FormValidator.endsWith(".com")
// Boolean checks
FormValidator.booleanTrue(message: "Must accept terms")
FormValidator.booleanFalse()
// Numeric
FormValidator.numeric()
// Date validations
FormValidator.date()
FormValidator.dateInPast()
FormValidator.dateInFuture()
FormValidator.dateAgeIsOlder(18, message: "Must be 18+")
FormValidator.dateAgeIsYounger(65)
// Text case
FormValidator.uppercase()
FormValidator.lowercase()
FormValidator.capitalized()
// Location formats
FormValidator.zipcodeUs()
FormValidator.postcodeUk()
// Regex pattern
FormValidator.regex(r'^[A-Z]{3}\d{4}$', message: "Invalid format")
// Custom validation
FormValidator.custom(
message: "Invalid value",
validate: (data) => data != null,
)
Chainer les regles de validation
Chainez plusieurs regles de maniere fluide en utilisant les methodes d'instance. Chaque methode retourne le FormValidator, vous permettant d'accumuler les regles :
FormValidator validator = FormValidator()
.notEmpty()
.email()
.maxLength(50);
FormValidationResult result = validator.check("user@example.com");
if (!result.isValid) {
List<String> errors = result.errorMessages();
print(errors);
}
Tous les constructeurs nommes ont des methodes d'instance chainables correspondantes :
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")
Validation personnalisee
Regle personnalisee (en ligne)
Utilisez .custom() pour ajouter une logique de validation en ligne :
FormValidator.custom(
message: "Username already taken",
validate: (data) {
// Return true if valid, false if invalid
return !_takenUsernames.contains(data);
},
)
Ou chainez-la avec d'autres regles :
FormValidator()
.notEmpty()
.custom(
message: "Must start with a letter",
validate: (data) => RegExp(r'^[a-zA-Z]').hasMatch(data.toString()),
)
Validation d'egalite
Verifiez si une valeur correspond a une autre :
FormValidator()
.notEmpty()
.equals(
_passwordController.text,
message: "Passwords must match",
)
Utiliser FormValidator avec les champs
FormValidator s'integre avec les widgets Field dans les formulaires. Passez un validateur au parametre 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),
),
];
}
Vous pouvez egalement utiliser des validateurs chaines avec les champs :
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"),
)
Regles de validation disponibles
Toutes les regles disponibles pour FormValidator, a la fois en tant que constructeurs nommes et methodes chainables :
| Regle | Constructeur nomme | Methode chainable | Description |
|---|---|---|---|
FormValidator.email() |
.email() |
Valide le format d'email | |
| Password | FormValidator.password(strength: 1) |
.password(strength: 1) |
Force 1 : 8+ caracteres, 1 majuscule, 1 chiffre. Force 2 : + 1 caractere special |
| Not Empty | FormValidator.notEmpty() |
.notEmpty() |
Ne peut pas etre vide |
| Min Length | FormValidator.minLength(5) |
.minLength(5) |
Longueur minimale de la chaine |
| Max Length | FormValidator.maxLength(100) |
.maxLength(100) |
Longueur maximale de la chaine |
| Min Value | FormValidator.minValue(18) |
.minValue(18) |
Valeur numerique minimale (fonctionne aussi sur la longueur des chaines, listes, maps) |
| Max Value | FormValidator.maxValue(100) |
.maxValue(100) |
Valeur numerique maximale |
| Min Size | FormValidator.minSize(2) |
.minSize(2) |
Taille minimale pour les listes/chaines |
| Max Size | FormValidator.maxSize(5) |
.maxSize(5) |
Taille maximale pour les listes/chaines |
| Contains | FormValidator.contains(['a', 'b']) |
.contains(['a', 'b']) |
La valeur doit contenir l'une des valeurs donnees |
| Begins With | FormValidator.beginsWith("https://") |
.beginsWith("https://") |
La chaine doit commencer par le prefixe |
| Ends With | FormValidator.endsWith(".com") |
.endsWith(".com") |
La chaine doit se terminer par le suffixe |
| URL | FormValidator.url() |
.url() |
Valide le format d'URL |
| Numeric | FormValidator.numeric() |
.numeric() |
Doit etre un nombre |
| Boolean True | FormValidator.booleanTrue() |
.booleanTrue() |
Doit etre true |
| Boolean False | FormValidator.booleanFalse() |
.booleanFalse() |
Doit etre false |
| Date | FormValidator.date() |
.date() |
Doit etre une date valide |
| Date In Past | FormValidator.dateInPast() |
.dateInPast() |
La date doit etre dans le passe |
| Date In Future | FormValidator.dateInFuture() |
.dateInFuture() |
La date doit etre dans le futur |
| Age Is Older | FormValidator.dateAgeIsOlder(18) |
.dateAgeIsOlder(18) |
L'age doit etre superieur a N |
| Age Is Younger | FormValidator.dateAgeIsYounger(65) |
.dateAgeIsYounger(65) |
L'age doit etre inferieur a N |
| Capitalized | FormValidator.capitalized() |
.capitalized() |
La premiere lettre doit etre en majuscule |
| Lowercase | FormValidator.lowercase() |
.lowercase() |
Tous les caracteres doivent etre en minuscules |
| Uppercase | FormValidator.uppercase() |
.uppercase() |
Tous les caracteres doivent etre en majuscules |
| Phone US | FormValidator.phoneNumberUs() |
.phoneNumberUs() |
Format de numero de telephone americain |
| Phone UK | FormValidator.phoneNumberUk() |
.phoneNumberUk() |
Format de numero de telephone britannique |
| Zipcode US | FormValidator.zipcodeUs() |
.zipcodeUs() |
Format de code postal americain |
| Postcode UK | FormValidator.postcodeUk() |
.postcodeUk() |
Format de code postal britannique |
| Regex | FormValidator.regex(r'pattern') |
.regex(r'pattern') |
Doit correspondre au motif regex |
| Equals | — | .equals(otherValue) |
Doit etre egal a une autre valeur |
| Custom | FormValidator.custom(validate: fn) |
.custom(validate: fn) |
Fonction de validation personnalisee |
Toutes les regles acceptent un parametre optionnel message pour personnaliser le message d'erreur.
Creer des regles de validation personnalisees
Pour creer une regle de validation reutilisable, etendez 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: alphanumeric, underscores, 3-20 chars
return RegExp(r'^[a-zA-Z0-9_]{3,20}$').hasMatch(data);
}
}
Utilisez {{attribute}} comme espace reserve dans le message — il sera remplace par le label du champ au moment de l'execution.
Utiliser un FormRule personnalise
Ajoutez votre regle personnalisee a un FormValidator en utilisant FormValidator.rule() :
FormValidator validator = FormValidator.rule([
FormRuleNotEmpty(),
FormRuleUsername(),
]);
FormValidationResult result = validator.check("my_username");
Ou utilisez la methode .custom() pour des regles ponctuelles sans creer de classe :
FormValidator()
.notEmpty()
.custom(
message: "Username must start with a letter",
validate: (data) => RegExp(r'^[a-zA-Z]').hasMatch(data.toString()),
)