Updated 28 April 2023
In this blog, We will design a simple login page, with e-mail and password validation. We will get the final result like the attached image.
Before we start, if you like check our Flutter app development company page.
Step 1:
We make an app entry main class. In this class, we have to define app routes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { final routes = <String, WidgetBuilder>{ LoginPage.tag: (context) => LoginPage(), }; @override Widget build(BuildContext context) { return MaterialApp( title: 'Simple Login Page', debugShowCheckedModeBanner: false, theme: ThemeData( primarySwatch: Colors.lightBlue, fontFamily: 'Nunito', ), home: LoginPage(), routes: routes, ); } } |
How is form input field validation handled in flutter?
Flutter has validation API, you need to use Form with TextFormField.
Form: Form is a container for FormFields (and its descendants) and other widgets. We also have saved, validate, and reset functions. These facilitate easier validation and manipulation of data inputted in one or multiple FormFields.
Properties
GlobalKey: We pass GlobalKey<FormState> _key in Form as the attribute to access form state to save, validate, and reset.
Autovalidate: We pass bool _validate in Form If true, form fields will validate and update their error text immediately after every change. Otherwise, you must call FormState.validate to validate.
TextFormField: A FormField that contains a TextField. This is a convenience widget that wraps a TextField widget in a FormField.
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 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
import 'package:flutter/material.dart'; import 'FormValidator.dart'; import 'LoginRequestData.dart'; class LoginPage extends StatefulWidget { static String tag = 'login-page'; @override State<StatefulWidget> createState() { return new _LoginPageState(); } } class _LoginPageState extends State<LoginPage> { GlobalKey<FormState> _key = new GlobalKey(); bool _validate = false; LoginRequestData _loginData = LoginRequestData(); bool _obscureText = true; @override Widget build(BuildContext context) { return new Scaffold( body: new Center( child: new SingleChildScrollView( child: new Container( margin: new EdgeInsets.all(20.0), child: Center( child: new Form( key: _key, autovalidate: _validate, child: _getFormUI(), ), ), ), ), ), ); } Widget _getFormUI() { return new Column( children: <Widget>[ Icon( Icons.person, color: Colors.lightBlue, size: 100.0, ), new SizedBox(height: 50.0), new TextFormField( keyboardType: TextInputType.emailAddress, autofocus: false, decoration: InputDecoration( hintText: 'Email', contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0), border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)), ), validator: FormValidator().validateEmail, onSaved: (String value) { _loginData.email = value; }, ), new SizedBox(height: 20.0), new TextFormField( autofocus: false, obscureText: _obscureText, keyboardType: TextInputType.text, decoration: InputDecoration( hintText: 'Password', contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0), border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)), suffixIcon: GestureDetector( onTap: () { setState(() { _obscureText = !_obscureText; }); }, child: Icon( _obscureText ? Icons.visibility : Icons.visibility_off, semanticLabel: _obscureText ? 'show password' : 'hide password', ), ), ), validator: FormValidator().validatePassword, onSaved: (String value) { _loginData.password = value; }), new SizedBox(height: 15.0), new Padding( padding: EdgeInsets.symmetric(vertical: 16.0), child: RaisedButton( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(24), ), onPressed: _sendToServer, padding: EdgeInsets.all(12), color: Colors.lightBlueAccent, child: Text('Log In', style: TextStyle(color: Colors.white)), ), ), new FlatButton( child: Text( 'Forgot password?', style: TextStyle(color: Colors.black54), ), onPressed: _showForgotPasswordDialog, ), new FlatButton( onPressed: _sendToRegisterPage, child: Text('Not a member? Sign up now', style: TextStyle(color: Colors.black54)), ), ], ); } _sendToRegisterPage() { ///Go to register page } _sendToServer() { if (_key.currentState.validate()) { /// No any error in validation _key.currentState.save(); print("Email ${_loginData.email}"); print("Password ${_loginData.password}"); } else { ///validation error setState(() { _validate = true; }); } } Future<Null> _showForgotPasswordDialog() async { await showDialog<String>( context: context, builder: (BuildContext context) { return new AlertDialog( title: const Text('Please enter your eEmail'), contentPadding: EdgeInsets.all(5.0), content: new TextField( decoration: new InputDecoration(hintText: "Email"), onChanged: (String value) { _loginData.email = value; }, ), actions: <Widget>[ new FlatButton( child: new Text("Ok"), onPressed: () async { _loginData.email = ""; Navigator.pop(context); }, ), new FlatButton( child: new Text("Cancel"), onPressed: () => Navigator.pop(context), ), ], ); }); } } |
You need to create a data model class for storing input login input data.
1 2 3 4 |
class LoginRequestData { String email = ''; String password = ''; } |
We created a separate helper class for validating Form field data.
In FormValidator class, we have defined methods to validate passwords and email Id.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class FormValidator { static FormValidator _instance; factory FormValidator() => _instance ??= new FormValidator._(); FormValidator._(); String validatePassword(String value) { String patttern = r'(^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{6,}$)'; RegExp regExp = new RegExp(patttern); if (value.isEmpty) { return "Password is Required"; } else if (value.length < 8) { return "Password must minimum eight characters"; } else if (!regExp.hasMatch(value)) { return "Password at least one uppercase letter, one lowercase letter and one number"; } 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,})) |
I hope this blog will help to make the Login page.
Happy Learning 🙂
1 2 3 4 5 6 7 8 9 10 11 |
; RegExp regExp = new RegExp(pattern); if (value.isEmpty) { return "Email is Required"; } else if (!regExp.hasMatch(value)) { return "Invalid Email"; } else { return null; } } } |
I hope this blog will help to make the Login page.
Happy Learning 🙂
If you have more details or questions, you can reply to the received confirmation email.
Back to Home
Be the first to comment.