Flutter Tutorial #1 — Form Validation.
By: Samuel Adekunle, Techwithsam
Tags: Google, Flutter, Dart, Programming, Form Validation

Form plays a vital role in any mobile application today. Almost all the app in the world have a form to fill.

Overview of this tutorial.

This app will have 5 text fields consisting of :

→ Full name

→ Email address

→ Phone number

→ Password

→ Confirm Password

and a submit button for validation.

If the user inputs are invalid according to the rules we set, we would simply display a snack bar that contains the error message e.g Invalid email address as shown below.

Let dive into coding now!!!

Creating our UI(user interface).

Create a new flutter project and clear out all generated code in the main.dart file. First, import the material package

import 'package:flutter/material.dart';

Then define the main function like this with a Stateless widget called MyApp:

void main() {

runApp(MyApp());

} class MyApp extends StatelessWidget {

@override

Widget build(BuildContext context) {

return MaterialApp(

title: 'Flutter Beginner Tutorial',

theme: ThemeData(

primarySwatch: Colors.green,

visualDensity: VisualDensity.adaptivePlatformDensity,

),

home: MyHomePage(),

);

}

}

Creating a StatefulWidget for MyHomePage(), it should look like this:

class MyHomePage extends StatefulWidget {

@override

_MyHomePageState createState() => _MyHomePageState();

} class _MyHomePageState extends State<MyHomePage> {

@override

Widget build(BuildContext context) {

return Container();

}

}

So, under _MyHomePageState extends State we’re going to declare a controller for each of our form fields:

TextEditingController _name = TextEditingController();

TextEditingController _email = TextEditingController();

TextEditingController _phn = TextEditingController();

TextEditingController _pass = TextEditingController();

TextEditingController _cpass = TextEditingController();

// we declare a _ScaffoldState here called _formKey because we're going to change the state of the app by showing the snack bar

var _formKey = GlobalKey<ScaffoldState>();

bool hidePass = true; // this is probably for showing and hiding our password

In the build widget instead of returning a Container widget, we’re going to return a Scaffold() widget, full code:

Scaffold(

key: _formKey,

appBar: AppBar(

title: Text('Simple Form Validation'),

centerTitle: true,

elevation: 0,

),

body: Center(

child: SingleChildScrollView(

child: Column(

mainAxisAlignment: MainAxisAlignment.center,

children: <Widget>[

Center(

child: Text(

'Register Page',

style: TextStyle(

fontSize: 24,

fontWeight: FontWeight.w300,

),

),

),

Padding(

padding: EdgeInsets.all(20),

child: Column(

children: <Widget>[

TextFormField(

controller: _name, // the controller we declared at the top

decoration: InputDecoration(

icon: Icon(Icons.person),

labelText: 'Full Name',

),

),

SizedBox(height: 10),

TextFormField(

controller: _email, // the controller we declared at the top

decoration: InputDecoration(

labelText: 'Email Address',

icon: Icon(Icons.mail),

),

),

SizedBox(height: 10),

TextFormField(

controller: _phn, // the controller we declared at the top

keyboardType: TextInputType.number,

decoration: InputDecoration(

labelText: 'Phone Number',

icon: Icon(Icons.call),

),

),

SizedBox(height: 10),

TextFormField(

controller: _pass,

obscureText: hidePass, // the bool we declared earlier

decoration: InputDecoration(

labelText: 'Password',

icon: Icon(Icons.security),

suffixIcon: IconButton(

icon: Icon(Icons.visibility),

onPressed: () {

showandhide(); // we are going to declare a function for showing the password inout call showandhide()

},

),

),

),

SizedBox(height: 10),

TextFormField(

obscureText: hidePass,

controller: _cpass,

decoration: InputDecoration(

labelText: 'Confirm Password',

icon: Icon(Icons.border_color),

suffixIcon: IconButton(

icon: Icon(Icons.visibility),

onPressed: () {

showandhide();

},

),

),

),

SizedBox(height: 15),

SizedBox(

width: 300,

child: MaterialButton(

onPressed: () {

formValidate(

name: _name.text,

email: _email.text,

cpass: _cpass.text,

pass: _pass.text,

phn: _phn.text,

); // formValidate consist of all of our inputs, so we're just going to declare a function to check they all if the user input is valid or otherwise.

},

child: Text(

'Submit Form',

style: TextStyle(color: Colors.white),

),

color: Colors.green,

),

),

],

),

),

],

),

),

),

);

So, we have to collect all our user input and set it inside initState and dispose of it as well.

@override

void initState() {

_name = TextEditingController();

_email = TextEditingController();

_phn = TextEditingController();

_pass = TextEditingController();

_cpass = TextEditingController();

super.initState();

} @override

void dispose() {

_name.dispose();

_email.dispose();

_phn.dispose();

_pass.dispose();

_cpass.dispose();

super.dispose();

}

Show and hide user password:

showandhide() {

setState(() {

hidePass = !hidePass;

//this just means if the eye icon is pressed hidepass is not equal to hidepass so true != true i.e false

});

}

So after all this, we have now got to the form validation itself:

// here we collect every information we need concerning the input

formValidate({String name, email, phn, pass, cpass}) {

if (name.toString().isEmpty) {

_showInSnackBar(message: 'Full name required');

} else if (!email.toString().contains('@')) {

_showInSnackBar(message: 'Invalid email address');

} else if (phn.toString().isEmpty || phn.length != 11) {

_showInSnackBar(message: 'Invalid phone number');

} else if (pass.toString().isEmpty || pass.length != 8) {

_showInSnackBar(message: '8 character required for password');

} else if (cpass.toString() != pass.toString()) {

_showInSnackBar(message: 'Password does not match');

} else {

openDia(name: name);

//so after all the input is valid we want to display a little dialog.

}

}

Our snack bar code:

void _showInSnackBar({String message}) {

_formKey.currentState.showSnackBar(

SnackBar(

content: GestureDetector(

onTap: () {},

child: Text(

message,

style: TextStyle(color: Colors.white, fontWeight: FontWeight.w600),

),

),

duration: (Duration(seconds: 4)),

elevation: 0,

backgroundColor: Colors.black,

),

);

}

and the Dialog code as well:

openDia({String name}) {

showDialog(

context: context,

builder: (BuildContext context) {

return AlertDialog(

content: Text('$name is now a verified account'),

title: Text('Registration Successful'),

actions: <Widget>[

MaterialButton(

onPressed: () {

Navigator.pop(context);

},

child: Text(

'Verified',

style: TextStyle(color: Colors.blue),

),

)

],

);

});

}

If we run our app now we should have something similar to this

Complete source code do well by staring ⭐ the repo:

Congrats, you have finally learned how to validate user input and also learned how to improve user experience by showing a beautiful error message.

If you enjoyed this article as much as I did you can support me by 👏 for this story and leave a comment below if you have any questions.

Follow me online:

Github, Facebook, Twitter, Instagram, Youtube, Medium, LinkedIn, etc @ acctgen1