Sunday, September 2, 2018

Flutter - Form Validation in Flutter.

Flutter is a mobile UI open source framework to build high-quality native interfaces for iOS and Android apps with the unified codebase. Flutter has its own UI components, along with an engine to render them on both the Android and iOS platforms. You can compose your whole application UI with widgets that contain other widgets.

In this post, we going to discuss form widget. We can use the form to design sign-up and login screen of Application. The best thing about the form is that we can validate each field in the same field. If we creating sign-up and login form of mobile application. Then form validation is an essential part of the app. It saves server computing time because we can validate param at the client side. We can ask the user to a enter valid phone number and we can smartly validate the entered mobile number and other data itself.

If we talk about the native app of Android and Ios. The form validation is time-consuming and we have to write more code for each field. On the native platform, we have to get references of the fields, finding out their values, validating them and manually displaying and hiding errors. 
With form widget, validation is much more enjoyable to work with. Let’s take a look at why.


To validate the value of text fields, we have to use Form widget that can contain multiple TextFormField widgets. To apply validation, we need to do something like this:
Form  Widget
final formKey = GlobalKey<FormState>(); String username;
//Form widget that you have to use in widget hierarchy
Form( key: formKey, child: TextFormField( decoration: InputDecoration(labelText: 'Username'), validator: (val) => val.isEmpty? 'Username can\'t be empty.' : null, onSaved: (val) => _username = val, ), );
As you can see above, we have used validator and onSaved parameters of form widget. Let's try to understand properties of TextFormField.
  • validator is a method that receives the current value of the field when validate is called. It returns either an error string or null, depending on whether the field is valid or not.
  • onSaved parameter receives the current value of the field when onSave is called. This value should be saved somewhere, usually in an instance field of our state, like in the example above.
  • Keys could probably be a topic on their own, but to put it simply, think of them as unique identifiers that we can use to get a reference to our widgets.

As you can see, we use one TextFormField to apply validation. If you using more then one TextFormField. So, you have to apply different validation on each field accordingly.

At last, when we need to validate and submit our form, we have to call the following method of the form.

Form Widget validation event
final form = formKey.currentState; if (form.validate()) { form.save(); // Form is saved, perform the login now. }
Once you call form.validate(). It will call every TextFormField widget contained in our Form and calls the validator methods on each of them. If there are any errors, they’re displayed accordingly in the UI. 
To understand it deeply, let create a simple sign-up form and observe it. How form validation works in Flutter application. We'll create a simple form with three fields Name, Mobile, and Email. We will validate all three input data on validate button click. The final screen of form will look like below.



Creating a new Project
1. Create a new project from File ⇒ New Flutter Project with your development IDE.

2. Open main.dart file and edit it. As we have set our theme and change debug banner property of Application.
main.dart
import 'package:flutter/material.dart'; import 'package:flutter_google_map_route/map_screen.dart'; import 'package:map_view/map_view.dart'; void main() { runApp(new MaterialApp( debugShowCheckedModeBanner: false, theme: new ThemeData( primaryColor: const Color(0xFF02BB9F), primaryColorDark: const Color(0xFF167F67), accentColor: const Color(0xFF167F67), ), home: new SignUpForm(), )); }
3. After that create another dart file and name it sign_up_form.dart. Here, we'll design UI and implement validation. 

Let’s Get Started and create fields of the screen.
sign_up_form.dart
//Fields GlobalKey<FormState> _key = new GlobalKey(); bool _validate = false; String name, email, mobile;
 4. Now edit build method of widget. Here, we have created app bar and calling a method in the form widget that'll return a hierarchy TextFormWidget widgets.
sign_up_form.dart
@override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text('Form Validation', style: new TextStyle( color: Colors.white ), ), ), body: new SingleChildScrollView( child: new Container( margin: new EdgeInsets.all(15.0), child: new Form( key: _key, autovalidate: _validate, child: getFormUI(), ), ), ), ); }
5. We have created Full Name, Mobile Number, and Email Id TextFormFiled widgets in the getFormUI method and a validate method that we have put in a root culumn widget.
sign_up_form.dart
Widget getFormUI() { return new Column( children: <Widget>[ new TextFormField( decoration: new InputDecoration(hintText: 'Full Name'), maxLength: 32, validator: validateName, onSaved: (String val) { name = val; }, ), new TextFormField( decoration: new InputDecoration(hintText: 'Mobile Number'), keyboardType: TextInputType.phone, maxLength: 10, validator: validateMobile, onSaved: (String val) { mobile = val; }), new TextFormField( decoration: new InputDecoration(hintText: 'Email ID'), keyboardType: TextInputType.emailAddress, maxLength: 32, validator: validateEmail, onSaved: (String val) { email = val; }), new SizedBox(height: 15.0), new RaisedButton( onPressed: _submit, child: new Text('Submit'), ) ], ); } 
6. As you can see above, we have a parameter validation of TextFormField which is used to validate that particular Field. We will add that named parameter validation to all of the TextFormField. So, that we can validate our form easily.  We have added vaidator methods validateName, validateMobile, and validateEmail with each TextFormField. It'll check validation of form on every check event occur from form validate method.
sign_up_form.dart
//Here you can see that we are returning “Name must be more than 2 character” if input text length is less than 3 else we are returning null. String validateName(String value) { String patttern = r'(^[a-zA-Z ]*$)'; RegExp regExp = new RegExp(patttern); if (value.length == 0) { return "Name is Required"; } else if (!regExp.hasMatch(value)) { return "Name must be a-z and A-Z"; } return null; } //Here, We have set 10 digits validation on mobile number. String validateMobile(String value) { String patttern = r'(^[0-9]*$)'; RegExp regExp = new RegExp(patttern); if (value.length == 0) { return "Mobile is Required"; } else if(value.length != 10){ return "Mobile number must 10 digits"; }else if (!regExp.hasMatch(value)) { return "Mobile Number must be digits"; } return null; } //For Email Verification we using RegEx. String validateEmail(String value) { String 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 regExp = new RegExp(pattern); if (value.length == 0) { return "Email is Required"; } else if(!regExp.hasMatch(value)){ return "Invalid Email"; }else { return null; } }
 7. Here, we have final method of sign_up_form.dart. It will validate the whole form.
sign_up_form.dart
_submit() { if (_formKey.currentState.validate()) { // If all data are correct then save data to out variables _formKey.currentState.save(); } else { // If all data are not valid then start auto validation. setState(() { _autoValidate = true; }); }}

8. At the end, merge all above code snippet and you will see final class of sign_up_form.dart look like this:

sign_up_form.dart
import 'package:flutter/material.dart'; class SignUpForm extends StatefulWidget { @override _FormState createState() => _FormState(); } class _FormState extends State<SignUpForm> { GlobalKey<FormState> _key = new GlobalKey(); bool _validate = false; String name, email, mobile; @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text('Form Validation', style: new TextStyle( color: Colors.white ), ), ), body: new SingleChildScrollView( child: new Container( margin: new EdgeInsets.all(15.0), child: new Form( key: _key, autovalidate: _validate, child: getFormUI(), ), ), ), ); } Widget getFormUI() { return new Column( children: <Widget>[ new TextFormField( decoration: new InputDecoration(hintText: 'Full Name'), maxLength: 32, validator: validateName, onSaved: (String val) { name = val; }, ), new TextFormField( decoration: new InputDecoration(hintText: 'Mobile Number'), keyboardType: TextInputType.phone, maxLength: 10, validator: validateMobile, onSaved: (String val) { mobile = val; }), new TextFormField( decoration: new InputDecoration(hintText: 'Email ID'), keyboardType: TextInputType.emailAddress, maxLength: 32, validator: validateEmail, onSaved: (String val) { email = val; }), new SizedBox(height: 15.0), new RaisedButton( onPressed: _submit, child: new Text('Submit'), ) ], ); } String validateName(String value) { String patttern = r'(^[a-zA-Z ]*$)'; RegExp regExp = new RegExp(patttern); if (value.length == 0) { return "Name is Required"; } else if (!regExp.hasMatch(value)) { return "Name must be a-z and A-Z"; } return null; } String validateMobile(String value) { String patttern = r'(^[0-9]*$)'; RegExp regExp = new RegExp(patttern); if (value.length == 0) { return "Mobile is Required"; } else if(value.length != 10){ return "Mobile number must 10 digits"; }else if (!regExp.hasMatch(value)) { return "Mobile Number must be digits"; } return null; } String validateEmail(String value) { String 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 regExp = new RegExp(pattern); if (value.length == 0) { return "Email is Required"; } else if(!regExp.hasMatch(value)){ return "Invalid Email"; }else { return null; } } _submit() { if (_key.currentState.validate()) { // No any error in validation _key.currentState.save(); } else { // validation error setState(() { _validate = true; }); } } }

As you can see above, we have used autovalidate. It'll validate the valus on any charactor update in any TextFormField. We initially set it to false because when user will open the form all the Fields will by default empty and as empty field is invalid. So, when user will open the form we don’t need to show invalid error.

Once user submit the form and if there is any validation error then we will start validating the input automatically by updating autoValidate to true.

If you have followed the article carefully, you can see the app running very smoothly as shown:


As you can see, form widget have excelt feature for validate entered valued. Now you got the idea that how form validation works and you can make a good form which will take only valid input.

If you face any difficulties in writing code. P
lease feel free to ask it from below comment section
              
                                      
Share:

Get it on Google Play

React Native - Start Development with Typescript

React Native is a popular framework for building mobile apps for both Android and iOS. It allows developers to write JavaScript code that ca...