Validating user input is an essential part of app development. This process makes the app more secure and checks whether the information provided by the user is what we anticipate them to provide so as not to introduce bugs into our application. Flutter comes with a native way of validating user inputs using the Form and TextFormField widget.
In this tutorial I will show you how to validate user inputs in Flutter using:
A validation mixin to contain validation logic.
A Form widget with a GlobalKey.
A TextFormField to collect user input and display validation errors.
A button to validate and submit the form.
To complete this tutorial, you will need:
To download and install Android Studio or Visual Studio Code
To download and install Flutter.
To set up your editor as described here.
Once you have your environment set up for Flutter, you can run the following to create a new application.
$ flutter create form_validation_example
Navigate to the new project directory on your IDE where you will find a demo application that Flutter creates. Replace the demo project with the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void main() {
runApp(MaterialApp(home: FormValidationExample()));
}
class FormValidationExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Form(
child: Column(
children: [
],
),
),
);
}
}
In order to validate the user inputs, we will create a validation mixin to handle the logic as follows:
1
2
3
4
5
6
7
8
9
10
mixin InputValidationMixin {
bool isPasswordValid(String password) => password.length == 6;
bool isEmailValid(String email) {
Pattern pattern =
r '^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
RegExp regex = new RegExp(pattern);
return regex.hasMatch(email);
}
}
Here, the password is valid if its length is 6. A regular expression is used to validate if the email is valid or not.
Add the InputValidationMixin to the FormValidationExample created earlier like this:
1
2
class FormValidationExample extends StatelessWidget with InputValidationMixin {
…
To validate the user input, we need the Form widget. The Form widget serves as a container to validate multiple TextFormFields and needs a GlobalKey to uniquely identify the form. It is also used to get the current state of the form.
final formGlobalKey = GlobalKey<FormState>();
Don’t forget to add this key to the Form widget like this:
1 2
Form( key: formGlobalKey, …
The job of the TextFormField is to render the UI interface for the user to interact with and to display the validation error once the user enters invalid data. The TextFormField has a validator method which is called to validate the input. The validator method returns a string containing the error message when the user input is invalid or null if the user input is valid.
In most cases, you will use a regular expression to check the input. We will use both the isEmailValid and the isPasswordValid methods from the InputValidationMixin mixin to validate the email and the password from the user respectively.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
TextFormField( validator: (email) { if (isEmailValid(email)) return null; else return 'Enter a valid email address'; }, ), TextFormField( obscureText: true, validator: (password) { if (isPasswordValid(password)) return null; else return 'Enter a valid password'; }, ),
The user taps the button to submit the information. Once the button is pressed, we check if the form is valid using the currentState property from the form GlobalKey. If it is valid we use the user information but if not, we display the error message.
1 2 3 4 5
ElevatedButton(onPressed: () { if (formGlobalKey.currentState.validate()) { // use the information provided } }, child: Text("Submit"))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: FormValidationExample(),
));
}
class FormValidationExample extends StatelessWidget with InputValidationMixin {
final formGlobalKey = GlobalKey < FormState > ();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Form validation example'),
),
body:
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Form(
key: formGlobalKey,
child: Column(
children: [
const SizedBox(height: 50),
TextFormField(
decoration: InputDecoration(
labelText: "Email"
),
validator: (email) {
if (isEmailValid(email)) return null;
else
return 'Enter a valid email address';
},
),
const SizedBox(height: 24),
TextFormField(
decoration: InputDecoration(
labelText: "Password",
),
maxLength: 6,
obscureText: true,
validator: (password) {
if (isPasswordValid(password)) return null;
else
return 'Enter a valid password';
},
),
const SizedBox(height: 50),
ElevatedButton(
onPressed: () {
if (formGlobalKey.currentState.validate()) {
formGlobalKey.currentState.save();
// use the email provided here
}
},
child: Text("Submit"))
],
),
),
));
}
}
mixin InputValidationMixin {
bool isPasswordValid(String password) => password.length == 6;
bool isEmailValid(String email) {
Pattern pattern =
r '^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
RegExp regex = new RegExp(pattern);
return regex.hasMatch(email);
}
}
Github gist: https://gist.github.com/De-Morgan/7c85c63b0c72f8c242815cf1f6a36976
Dart pad link: https://dartpad.dev/7c85c63b0c72f8c242815cf1f6a36976?
CHECK OUT TOPCODER FLUTTER FREELANCE GIGS