Valider un formulaire avec Flutter
Sommaire
- 1- Objectif
- 2- Présentation
- 3- Méthodes de validation de
TextFormFields
avec Flutter - 3.1- 1. **Validation au moment de la soumission (on submission)** :
- 3.2- 2. **Validation dès le rendu** :
- 3.3- 3. **Validation lors d'un changement** :
- 3.4- 4. **Désactiver la validation** :
- 3.5- 5. **Validation avec des expressions régulières (regex)** :
- 3.6- 6. **Valider des champs dépendants** :
- 3.7- 7. **Erreurs de validation asynchrone** :
- 3.8- 8. **Personnaliser l'apparence des champs de texte** :
- 4- Étapes de validation du formulaire avec Flutter
- 4.1- Étape 1- Créer un formulaire avec un GlobalKey<FormState>.
- 4.2- Étape 2- Ajoutez du TextFormField avec la validation requise.
- 4.3- Étape 3- Créez un bouton où vous vérifiez la validation du formulaire flutter et soumettez-le.
- 5- Réalisation
- 5.1.1- Étape 1 : Créer un formulaire avec une
GlobalKey
. - 5.1.2- Étape 2 : Ajouter un TextFormField avec une logique de validation
- 6- Application
- 6.1.1- Cours Flutter
Valider un formulaire avec Flutter
-
Objectif
- Dans ce tutoriel, découvrez comment ajouter une validation à un formulaire
-
Présentation
- Un Form flutter est un composant essentiel du développement d’applications Fluter. Lorsque nous créons un formulaire, nous devons implémenter la validation, la soumission, etc. du formulaire. Dans ce tutoriel, vous apprendrez à créer, valider et utiliser un formulaire dans Flutter.
- La page de soumission de formulaire est utilisée pour soumettre les données saisies par l’utilisateur à partir du formulaire, et cela peut être fait de plusieurs façons en un clin d’œil.
- Les données du formulaire seront validées, et si la validation réussit, il soumettra les données. Si la validation échoue, un simple message d’erreur s’affichera pour nous informer de l’erreur.
- La création et la validation d’un formulaire comprennent les étapes suivantes :
- 1- Page de construction
- 2. Ajouter des validations
- 3. Ajouter une action pour valider le formulaire
-
Méthodes de validation de
TextFormFields
avec Flutter - Flutter offre plusieurs méthodes de validation pour les TextFormField qui vous permettent de valider les données saisies par l’utilisateur.
- Les méthodes de validation les plus couramment utilisées incluent :
-
1. **Validation au moment de la soumission (on submission)** :
- Vous pouvez utiliser une ‘
formKey
‘ assignée au widget ‘Form
‘ pour déclencher la validation lorsque le formulaire est soumis. - Cela se révèle utile lorsque vous souhaitez effectuer une validation au moment où l’utilisateur appuie sur le bouton de soumission (‘
onPressed
‘ du bouton de soumission). -
2. **Validation dès le rendu** :
- Pour déclencher une validation dès que le formulaire ou le champ est visible, utilisez `
AutovalidateMode.always
`. -
3. **Validation lors d’un changement** :
- Pour déclencher une validation lorsqu’un champ est modifié, utilisez `
AutovalidateMode.onUserInteraction
`. -
4. **Désactiver la validation** :
- Si vous voulez désactiver la validation, utilisez `
AutovalidateMode.disabled
`. -
5. **Validation avec des expressions régulières (regex)** :
- L’expression
RegExp(r'[a-z]')
est une expression régulière en Dart qui est utilisée pour rechercher une correspondance avec n’importe quelle lettre minuscule de l’alphabet anglais, c’est-à-dire une lettre comprise entre « a » et « z ». Voici ce que signifient les composants de cette expression régulière : RegExp
est la classe en Dart utilisée pour représenter une expression régulière.r
devant la chaîne de caractères signifie que c’est une chaîne brute (raw string) où les caractères d’échappement ne sont pas interprétés. Cela permet de définir plus facilement des expressions régulières.[a-z]
est une partie de l’expression régulière qui définit une plage de caractères autorisés. Dans ce cas, [a-z] signifie « n’importe quelle lettre minuscule de l’alphabet anglais », de « a » à « z ». La notation [a-z] est utilisée pour définir un ensemble de caractères autorisés. Si la chaîne de caractères contient au moins une lettre minuscule, alors la correspondance est vérifiée.- Utilisez une expression régulière pour valider une valeur. Par exemple, pour valider une adresse e-mail :
- L’expression régulière `
RegExp(r'^\S+@\S+$')
` est couramment utilisée pour valider si une chaîne de caractères correspond à un format d’adresse e-mail simple. Voici ce que signifient les composants de cette expression régulière : - `
RegExp
` est la classe en Dart utilisée pour représenter une expression régulière. - `
r
` devant la chaîne de caractères signifie que c’est une chaîne brute (raw string) où les caractères d’échappement ne sont pas interprétés. - L’expression régulière elle-même est composée de trois parties principales :
- 1. `
^
` : C’est un ancrage qui signifie « début de la chaîne ». L’expression commence par le début de la chaîne. - 2. `
\S+
` : Cela correspond à un ou plusieurs caractères non-blancs. `\S
` représente n’importe quel caractère qui n’est pas un espace blanc, et `+
` signifie « un ou plusieurs ». Donc, `\S+
` correspond à une séquence d’au moins un caractère non-blanc. - 3. `
@
` : C’est simplement le caractère «at
» (arobase) qui doit être présent dans une adresse e-mail valide. - 4. `
\S+
` : Tout comme la première occurrence, cela correspond à une séquence d’au moins un caractère non-blanc. - 5. `
$
` : C’est un ancrage qui signifie « fin de la chaîne ». L’expression se termine par la fin de la chaîne. -
6. **Valider des champs dépendants** :
-
7. **Erreurs de validation asynchrone** :
-
8. **Personnaliser l’apparence des champs de texte** :
-
Étapes de validation du formulaire avec Flutter
-
Étape 1- Créer un formulaire avec un GlobalKey<FormState>.
- Utilisez d’abord le Widget
Form
, cela fonctionnera en groupe et vous aidera à gérer facilement la validation de plusieurs champs de texte de formulaires flutter. - Ensuite, après avoir créé un formulaire en flutter, fournissez-lui
GlobalKey<FormState>
, cela vous aidera à permettre à la validation de se former dans le bon ordre et très facilement. -
Étape 2- Ajoutez du TextFormField avec la validation requise.
- Le widget TextFormField provient de la conception matérielle et peut également afficher erreur de validation , chaque fois qu’un utilisateur ne remplit pas l’exigence TextFormField,
- nous pouvons le faire en appliquant des règles de validation à un champ de texte flutter particulier en lui fournissant des règles de propriétés de validation.
- Si l’utilisateur saisit une entrée non valide, la fonction
Validator
dans Flutter la détectera et renverra un message d’erreur approprié au bas de TextField. -
Étape 3- Créez un bouton où vous vérifiez la validation du formulaire flutter et soumettez-le.
- La création d’un bouton devrait être à l’intérieur de Widget
Form
, à l’aide duquel l’utilisateur peut soumettre le formulaire rempli d’informations. - Lorsqu’un utilisateur tente de soumettre le formulaire onPressed, nous vérifierons si le champ du formulaire flutetr par l’utilisateur est conforme à la validation requise, puis si le formulaire est valide, envoyez toutes les informations de données au serveur de base de données pour être enregistrées, sinon si le formulaire est invalid alors afficher un message d’erreur approprié à l’utilisateur sous le champ de texte flutter où la validation n’est pas autorisée.
-
Réalisation
- Nous allons donc créer un formulaire d’ inscription avec quelques champs :
- Prénom
- Nom de famille
- Mot de passe
- Confirmez le mot de passe
- et un bouton d’inscription .
-
Étape 1 : Créer un formulaire avec une
GlobalKey
. - La clé globale (
GlobalKey
) est utilisée pour identifier de manière unique le formulaire et permet la validation du formulaire lors d’une étape ultérieure. GlobalKey
, il s’agit d’une clé unique sur l’ensemble de l’application. Grâce à cette clé, on peut trouver et accéder au Élément en question et récupérer sesState
et Widget.final _formKey = GlobalKey<FormState>();
- Pour créer un formulaire, vous devez d’abord définir une clé globale (
GlobalKey
). Dans notre exemple, nous avons défini a _formKey comme une clé globale. - Une clé globale ou
GlobalKey
est une clé qui, lorsqu’elle est transmise en tant que clé dans un widget, peut différencier le widget de tous les widgets d’une arborescence de widgets. - Tout d’abord, nous allons créer un formulaire. Le widget de formulaire agira comme un conteneur pour regrouper et valider plusieurs champs de formulaire.
- Pour identifier le formulaire de manière unique, nous devons fournir une
GlobalKey
lors de la création du formulaire. -
Étape 2 : Ajouter un TextFormField avec une logique de validation
- L’étape suivante consiste à ajouter TextFormField. Ce widget affiche un champ de texte de conception de matériau et peut afficher les erreurs de validation lorsqu’elles se produisent.
- L’entrée est validée en fournissant une fonction validator() au TextFormField. Si la valeur saisie par l’utilisateur n’est pas valide, la fonction de validation renverra un message d’erreur. S’il n’y a pas d’erreurs, le validateur renverra un null.
- Dans cet exemple, nous créons un validateur qui garantit que TextFormField n’est pas vide. S’il est vide, il renverra un message d’erreur personnalisé.
-
Application
- Création d’une Application Flutter de Formulaire d’Inscription
- Dans ce travail, vous apprendrez à créer une application Flutter de formulaire d’inscription avec deux champs de texte dans la même ligne, un champ d’e-mail avec validation, un champ de mot de passe sécurisé, et une confirmation de mot de passe.
- Prérequis
- Avant de commencer, assurez-vous que Flutter est correctement installé sur votre ordinateur et que vous avez configuré votre environnement de développement.
- Étape 1 : Créez un nouveau projet Flutter
- Créez un nouveau projet Flutter dans votre environnement de développement, nommez votre projet et utilisez la commande Flutter appropriée pour le créer.
- Étape 2 : Configurez l’Interface Utilisateur
- Dans cette étape, nous allons concevoir l’interface utilisateur de l’application en utilisant une image de référence comme modèle visuel. Vous devez créer l’interface utilisateur pour le formulaire d’inscription en vous basant sur cette image.
- Image de Référence :
- L’image ci-dessus c’est une image de référence qui représente l’interface utilisateur souhaitée pour le formulaire d’inscription.
- Cette image servira de guide visuel pour créer la disposition et l’apparence de l’interface utilisateur.
- Conception de l’Interface Utilisateur :
- Utilisez l’image de référence pour créer les éléments de l’interface utilisateur, y compris les champs de texte pour le prénom, le nom, l’e-mail, le mot de passe, la confirmation de mot de passe, et le bouton de soumission.
- Respectez la disposition et le style présentés dans l’image.
- Structure du Formulaire :
- Assurez-vous que les champs de texte Prénom et Nom sont alignés côte à côte sur la même ligne.
- Les éléments du formulaire doivent être organisés de manière à correspondre à l’image de référence.
- Décorations des Champs de Texte :
- Appliquez les décorations appropriées aux champs de texte pour afficher les libellés et les styles conformément à l’image de référence.
- Validation :
- Assurez-vous d’ajouter la validation des champs de texte conformément aux critères précédemment mentionnés.
- Bouton de Soumission :
- Intégrez le bouton de soumission dans l’interface utilisateur conformément à l’image de référence.
- Test Visuel :
- Une fois la conception terminée, comparez votre interface utilisateur à l’image de référence pour vous assurer que tous les éléments correspondent visuellement.
- Étape 3 : Créez les Champs de Texte
- Ajoutez deux champs de texte (Prénom et Nom) sur la même ligne dans le formulaire en utilisant la classe TextFormField. Ajoutez des décorations aux champs de texte pour afficher des libellés.
- Étape 4 : Ajoutez la Validation des Champs de Texte
- Ajoutez une validation aux champs de texte pour vous assurer qu’ils ne sont pas vides. Assurez-vous que la validation fonctionne lorsque l’utilisateur commence à écrire.
- Étape 5 : Ajoutez un Champ d’E-mail
- Ajoutez un champ d’e-mail avec une validation spécifique en utilisant une expression régulière pour valider l’e-mail.
- Étape 6 : Ajoutez un Champ de Mot de Passe
- Ajoutez un champ de mot de passe sécurisé avec une validation spécifique. Assurez-vous que le mot de passe respecte les critères de validation (longueur, majuscules, minuscules, chiffres, caractères spéciaux).
- Étape 7 : Ajoutez une Confirmation de Mot de Passe
- Ajoutez un champ pour confirmer le mot de passe. Assurez-vous que la confirmation de mot de passe correspond au mot de passe saisi précédemment.
- Étape 8 : Gérez la Soumission du Formulaire
- Ajoutez un bouton de soumission au formulaire et gérez l’action lorsque le bouton est pressé. Vérifiez si le formulaire est valide avant de le soumettre.
- Étape 9 : Affichez les Données Saisies
- Affichez les données saisies par l’utilisateur dans la console lorsque le formulaire est soumis avec succès.
- Étape 10 : Testez l’Application
- Exécutez l’application Flutter pour la tester. Confirmez que les validations fonctionnent comme prévu en saisissant différentes données.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyForm(),
);
}
}
class MyForm extends StatefulWidget {
@override
_MyFormState createState() => _MyFormState();
}
class _MyFormState extends State<MyForm> {
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Formulaire de Validation'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Veuillez entrer du texte.';
}
return null;
},
decoration: InputDecoration(
labelText: 'Entrez votre nom d’utilisateur',
),
),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
// Si toutes les données sont correctes, enregistrez les données et traitez-les
// Vous pouvez ajouter votre logique de traitement ici
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Formulaire soumis avec succès'),
),
);
}
},
child: Text('Soumettre'),
),
],
),
),
),
);
}
}
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyForm(),
);
}
}
class MyForm extends StatefulWidget {
@override
_MyFormState createState() => _MyFormState();
}
class _MyFormState extends State<MyForm> {
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Formulaire de Validation'),
),
body: Form(
key: _formKey,
autovalidateMode: AutovalidateMode.always, // Déclenche la validation dès le rendu
child: Column(
children: [
TextFormField(
validator: (value) {
if (value == null || value.isEmpty || value.length<12) {
return 'Veuillez entrer du texte.';
}
return null;
},
decoration: InputDecoration(
labelText: 'Entrez votre nom d’utilisateur',
),
),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
// Si toutes les données sont correctes, enregistrez les données et traitez-les
// Vous pouvez ajouter votre logique de traitement ici
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Formulaire soumis avec succès'),
),
);
}
},
child: Text('Soumettre'),
),
],
),
),
);
}
}
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyForm(),
);
}
}
class MyForm extends StatefulWidget {
@override
_MyFormState createState() => _MyFormState();
}
class _MyFormState extends State<MyForm> {
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Formulaire de Validation'),
),
body: Form(
key: _formKey,
autovalidateMode: AutovalidateMode.onUserInteraction, // Déclenche la validation lorsqu'un champ est modifié
child: Column(
children: [
TextFormField(
validator: (value) {
if (value == null || value.isEmpty|| value.length<12) {
return 'Veuillez entrer du texte.';
}
return null;
},
decoration: InputDecoration(
labelText: 'Entrez votre nom d’utilisateur',
),
),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
// Si toutes les données sont correctes, enregistrez les données et traitez-les
// Vous pouvez ajouter votre logique de traitement ici
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Formulaire soumis avec succès'),
),
);
}
},
child: Text('Soumettre'),
),
],
),
),
);
}
}
TextFormField(
autovalidateMode: AutovalidateMode.disabled,
),
```
RegExp _emailRegex = RegExp(r'^\S+@\S+$');
TextFormField(
validator: (value) {
if (!_emailRegex.hasMatch(value!)) {
return 'Adresse e-mail invalide';
}
return null;
},
),
```
Pour valider des champs dépendants l’un de l’autre, utilisez une variable d’état. Exemple avec un mot de passe et sa confirmation :
String? password;
TextFormField(
onChanged: (value) {
setState(() {
password = value;
});
},
),
TextFormField(
validator: (value) {
if (value != password) {
return 'Les mots de passe ne correspondent pas';
}
return null;
},
),
```
Parfois, vous voudrez peut-être valider des champs en faisant un appel API. Dans ce cas, il faudra gérer les erreurs retournées par l’API et les afficher sous le champ concerné.
bool isEmailAlreadyRegistered = false;
ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
// Appel API
if (/*email déjà enregistré*/) {
setState(() {
isEmailAlreadyRegistered = true;
});
}
}
},
),
TextFormField(
onChanged: (value) {
if (isEmailAlreadyRegistered) {
setState(() {
isEmailAlreadyRegistered = false;
});
}
},
decoration: InputDecoration(
errorText: isEmailAlreadyRegistered ? 'E-mail déjà enregistré' : null,
),
),
```
Si vous ne souhaitez pas utiliser l’apparence Material pour vos champs, vous pouvez toujours utiliser `TextFormField` et le personnaliser avec la propriété `decoration`.
TextFormField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Votre texte',
),
),
```
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
// Construire un widget Formulaire (Form) en utilisant le _formKey créé ci-dessus.
return Form(
key: _formKey,
child: Column(
children: <Widget>[
// Ajouter des TextFormFields et ElevatedButton ici.
]
)
);
}
TextFormField(
// Le validateur reçoit le texte que l'utilisateur a saisi.
validator: (value) {
if (value.isEmpty) {
return 'Veuillez saisir du texte';
}
return null;
},
);
child: ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
// If the form is valid, display a Snackbar.
//Scaffold.of(context).showSnackBar(SnackBar(content: Text('Data is in processing.')));
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text(
"Saisissez ici quelque chose à afficher sur le snack-bar")));
}
},
child: const Text('Submit'),
)),
Solution
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(debugShowCheckedModeBanner: false,
home: MyForm(),
);
}
}
class MyForm extends StatefulWidget {
@override
_MyFormState createState() => _MyFormState();
}
class _MyFormState extends State<MyForm> {
final _formKey = GlobalKey<FormState>();
String _firstName = '';
String _lastName = '';
String _email = '';
String _password = '';
String _confirmPassword = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Formulaire d\'inscription'),
),
body: Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Row(
children: [
Expanded(
child: TextFormField(
decoration: InputDecoration(labelText: 'Prénom'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Veuillez entrer votre prénom.';
}
return null;
},
onChanged: (value) {
setState(() {
_firstName = value;
});
},
),
),
SizedBox(width: 16),
Expanded(
child: TextFormField(
decoration: InputDecoration(labelText: 'Nom'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Veuillez entrer votre nom.';
}
return null;
},
onChanged: (value) {
setState(() {
_lastName = value;
});
},
),
),
],
),
TextFormField(
decoration: InputDecoration(labelText: 'E-mail'),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Veuillez entrer votre adresse e-mail.';
} else if (!value.contains('@')) {
return 'Adresse e-mail invalide.';
}
return null;
},
onChanged: (value) {
setState(() {
_email = value;
});
},
),
TextFormField(
decoration: InputDecoration(labelText: 'Mot de passe'),
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Veuillez entrer un mot de passe.';
}
if (value.length < 8 || value.length > 12) {
return 'Le mot de passe doit contenir entre 8 et 12 caractères.';
}
if (!value.contains(RegExp(r'[a-z]'))) {
return 'Le mot de passe doit contenir au moins une lettre minuscule.';
}
if (!value.contains(RegExp(r'[A-Z]'))) {
return 'Le mot de passe doit contenir au moins une lettre majuscule.';
}
if (!value.contains(RegExp(r'[0-9]'))) {
return 'Le mot de passe doit contenir au moins un chiffre.';
}
if (!value.contains(RegExp(r'[!@#$%^&*(),.?":{}|<>]'))) {
return 'Le mot de passe doit contenir au moins un caractère spécial.';
}
return null;
},
onChanged: (value) {
setState(() {
_password = value;
});
},
),
TextFormField(
decoration: InputDecoration(labelText: 'Confirmer le mot de passe'),
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Veuillez confirmer votre mot de passe.';
} else if (value != _password) {
return 'Les mots de passe ne correspondent pas.';
}
return null;
},
onChanged: (value) {
setState(() {
_confirmPassword = value;
});
},
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
print('Prénom : $_firstName');
print('Nom : $_lastName');
print('E-mail : $_email');
print('Mot de passe : $_password');
}
},
child: Text('Soumettre'),
),
],
),
),
),
);
}
}