Pandiyan Mani
7 min readOct 26, 2022

Complete Register Page with All Types Of Input Fields in Flutter

Lets design an register page which has all format of inputs like date selection, keypad shows only digits for phone number, password validation, terms and condition with checkbox and toast for displaying temporary error message.

Lets see how our design look alike

In the above you can see register page design look like lets see each field in detail

Since it is register form i am designing in the Form widget

Form(key:,child:)

So inside the key i am passing the GlobalKey<FormState>() . For StatefulWidgets, global keys also provide access to State. And the key should be unique across the entire app.

final _formkey = GlobalKey<FormState>();

And inside the child I am creating an Scaffold as you know Scaffold → contain some inbuild material design such as appbar, Navigationbar, BottomNvaigation and so on.

return Form(
key: _formkey,
child: Scaffold()
)

So inside Scaffold body we have SafeArea → which avoids overlap of text with appbar and it start from the start pointing of the screen

return Form(
key: _formkey,
child: Scaffold(
body: SafeArea(
child: Container()
)
)

And then we have SingleChildScrollView → to make our widgets scroll in case if its bigger thenn screen size.

For vertical arrangement we use Column → and inside Column we have children array where we add our childs view.

mainAxisAlignment: MainAxisAlignment.center,

To place views to center of screen we use mainAxisAlignment: MainAxisAlignment.center,

To Leave space between two widgets we use SizedBox of height 20.

SizedBox(
height: 20,
)

For designing Text widget we use Text along with style

Text("Welcome To Register Page",
style: TextStyle(
fontSize: 30,
fontStyle: FontStyle.italic,
color: Colors.red))

And for input field we use TextFormField which has validator for checking input field is empty or not and so many validation as per requirement. So we have controller which holds the values of the field it will be useful when you need to validate result on final submit. errorStyle → for designing the error Text widget

TextFormField(
controller: _username,
validator: (value) {
if (value == null || value.isEmpty) {
return "Enter User Name";
}
return null;
},
style: const TextStyle(
fontSize: 20,
fontStyle: FontStyle.italic,
color: Colors.black),
decoration: InputDecoration(
errorStyle: const TextStyle(
fontSize: 10,
fontStyle: FontStyle.italic,
color: Colors.red),
labelText: "Enter User Name",
labelStyle: const TextStyle(
fontSize: 20,
fontStyle: FontStyle.italic,
color: Colors.black),
enabledBorder: OutlineInputBorder(
borderSide:
const BorderSide(color: Colors.black, width: 1),
borderRadius: BorderRadius.circular(10)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10))),
),

And for selecting Date Of Birth i am creating a TextButton in the child of Container

Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
borderRadius:
const BorderRadius.all(Radius.circular(10))),
width: size.width,
height: 50,
child: TextButton(
onPressed: () {
_selectDate(context);
},
style: const ButtonStyle(
alignment: Alignment.centerLeft,
backgroundColor:
MaterialStatePropertyAll(Colors.transparent)),
child: Text(_selectedDOB,
style: const TextStyle(
fontSize: 20,
fontStyle: FontStyle.italic,
color: Colors.black)),
),
)

So on press of Date Of Birth button we will display date dialog where the user select the date below is the code for showing Date Picker

DateTime selectedDate = DateTime.now();

Future<void> _selectDate(BuildContext context) async {
final DateTime? picked = await showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(2015, 8),
lastDate: DateTime(2101));
if (picked != null && picked != selectedDate) {
setState(() {
selectedDate = picked;
String formatDate = DateFormat("MMMM dd, yyyy").format(selectedDate);
_selectedDOB = formatDate;
});
}
}

For creating toast we need toast dependencies and for converting date format we need intl: dependencies

dependencies:
flutter:
sdk: flutter


# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
fluttertoast: ^8.1.1
intl:

Sample of toast message

Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);

I am just pasting the entire code of register page below which might be useful for you. So i just created a RegisterPage.dart under lib folder

import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:intl/intl.dart'; // for date format


class RegisterPage extends StatefulWidget {
const RegisterPage({Key? key}) : super(key: key);

@override
State<RegisterPage> createState() => _RegisterPageState();
}

class _RegisterPageState extends State<RegisterPage> {
bool _isChecked = false;
String _selectedDOB = "Choose Date Of Birth";
final _formkey = GlobalKey<FormState>();
TextEditingController _password = TextEditingController();
TextEditingController _cpassword = TextEditingController();
TextEditingController _username = TextEditingController();
TextEditingController _emailid = TextEditingController();
TextEditingController _mobileno = TextEditingController();

bool validateEmail(String value) {
bool emailValid = RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+")
.hasMatch(value);
return emailValid;
}

void toastMessage(String message) {
Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
}

DateTime selectedDate = DateTime.now();

Future<void> _selectDate(BuildContext context) async {
final DateTime? picked = await showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(2015, 8),
lastDate: DateTime(2101));
if (picked != null && picked != selectedDate) {
setState(() {
selectedDate = picked;
String formatDate = DateFormat("MMMM dd, yyyy").format(selectedDate);
_selectedDOB = formatDate;
});
}
}

@override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return Form(
key: _formkey,
child: Scaffold(
body: SafeArea(
child: Container(
padding: EdgeInsets.fromLTRB(40, 0, 40, 0),
child: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
height: 20,
),
const Text("Welcome To Register Page",
style: TextStyle(
fontSize: 30,
fontStyle: FontStyle.italic,
color: Colors.red)),
SizedBox(
height: 20,
),
const Text("Enter User Personal Details",
style: TextStyle(
fontSize: 20,
fontStyle: FontStyle.italic,
color: Colors.black)),
SizedBox(
height: 20,
),
TextFormField(
controller: _username,
validator: (value) {
if (value == null || value.isEmpty) {
return "Enter User Name";
}
return null;
},
style: const TextStyle(
fontSize: 20,
fontStyle: FontStyle.italic,
color: Colors.black),
decoration: InputDecoration(
errorStyle: const TextStyle(
fontSize: 10,
fontStyle: FontStyle.italic,
color: Colors.red),
labelText: "Enter User Name",
labelStyle: const TextStyle(
fontSize: 20,
fontStyle: FontStyle.italic,
color: Colors.black),
enabledBorder: OutlineInputBorder(
borderSide:
const BorderSide(color: Colors.black, width: 1),
borderRadius: BorderRadius.circular(10)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10))),
),
const SizedBox(
height: 20,
),
TextFormField(
controller: _emailid,
validator: (value) {
if (value == null || value.isEmpty) {
return "Enter User Email ID";
} else if (!validateEmail(value)) {
return "Invalid Email ID";
}
return null;
},
style: const TextStyle(
fontSize: 20,
fontStyle: FontStyle.italic,
color: Colors.black),
decoration: InputDecoration(
errorStyle: const TextStyle(
fontSize: 10,
fontStyle: FontStyle.italic,
color: Colors.red),
labelText: "Enter User Email ID",
labelStyle: const TextStyle(
fontSize: 20,
fontStyle: FontStyle.italic,
color: Colors.black),
enabledBorder: OutlineInputBorder(
borderSide:
const BorderSide(color: Colors.black, width: 1),
borderRadius: BorderRadius.circular(10)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10))),
),
const SizedBox(
height: 20,
),
TextFormField(
controller: _mobileno,
keyboardType: TextInputType.phone,
validator: (value) {
if (value == null || value.isEmpty) {
return "Enter User Mobile Number";
}
return null;
},
style: const TextStyle(
fontSize: 20,
fontStyle: FontStyle.italic,
color: Colors.black),
decoration: InputDecoration(
errorStyle: const TextStyle(
fontSize: 10,
fontStyle: FontStyle.italic,
color: Colors.red),
labelText: "Enter User Mobile Number",
labelStyle: const TextStyle(
fontSize: 20,
fontStyle: FontStyle.italic,
color: Colors.black),
enabledBorder: OutlineInputBorder(
borderSide:
const BorderSide(color: Colors.black, width: 1),
borderRadius: BorderRadius.circular(10)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10))),
),
const SizedBox(
height: 20,
),
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
borderRadius:
const BorderRadius.all(Radius.circular(10))),
width: size.width,
height: 50,
child: TextButton(
onPressed: () {
_selectDate(context);
},
style: const ButtonStyle(
alignment: Alignment.centerLeft,
backgroundColor:
MaterialStatePropertyAll(Colors.transparent)),
child: Text(_selectedDOB,
style: const TextStyle(
fontSize: 20,
fontStyle: FontStyle.italic,
color: Colors.black)),
),
),
SizedBox(
height: 20,
),
TextFormField(
obscureText: true,
controller: _password,
validator: (value) {
if (value == null || value.isEmpty) {
return "Enter User Password";
} else if (value.length < 6) {
return "Password should be greater then 5 digit";
}
return null;
},
style: const TextStyle(
fontSize: 20,
fontStyle: FontStyle.italic,
color: Colors.black),
decoration: InputDecoration(
errorStyle: const TextStyle(
fontSize: 10,
fontStyle: FontStyle.italic,
color: Colors.red),
labelText: "Enter Password",
labelStyle: const TextStyle(
fontSize: 20,
fontStyle: FontStyle.italic,
color: Colors.black),
enabledBorder: OutlineInputBorder(
borderSide:
const BorderSide(color: Colors.black, width: 1),
borderRadius: BorderRadius.circular(10)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10))),
),
SizedBox(
height: 20,
),
TextFormField(
controller: _cpassword,
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty) {
return "Enter Confirm Password";
} else if (value.length < 6) {
return "Password should be greater then 5 digit";
} else if (value != _password.text) {
return "Confirm Password not matches with Password";
}
return null;
},
style: const TextStyle(
fontSize: 20,
fontStyle: FontStyle.italic,
color: Colors.black),
decoration: InputDecoration(
errorStyle: const TextStyle(
fontSize: 10,
fontStyle: FontStyle.italic,
color: Colors.red),
labelText: "Enter Confirm Password",
labelStyle: const TextStyle(
fontSize: 20,
fontStyle: FontStyle.italic,
color: Colors.black),
enabledBorder: OutlineInputBorder(
borderSide:
const BorderSide(color: Colors.black, width: 1),
borderRadius: BorderRadius.circular(10)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10))),
),
SizedBox(
height: 20,
),
Row(
children: [
Checkbox(
activeColor: Colors.blue,
value: _isChecked,
onChanged: (val) {
setState(() {
_isChecked = !_isChecked;
});
}),
const Text("I Read and Agree to ",
style: TextStyle(
fontStyle: FontStyle.italic,
fontSize: 18,
color: Colors.black)),
Container(
decoration: const BoxDecoration(
border: Border(
bottom:
BorderSide(color: Colors.black, width: 1.0))),
child: InkWell(
onTap: () {
toastMessage("Clicked on Terms & Condition");
},
child: const Text("Terms & Conditions.",
style: TextStyle(
fontStyle: FontStyle.italic,
fontSize: 18,
color: Colors.red)),
),
)
],
),
const SizedBox(
height: 20,
),
Container(
width: size.width,
height: 40,
child: ElevatedButton(
onPressed: () {
if (_formkey.currentState!.validate()) {
if (_selectedDOB == "Choose Date Of Birth") {
toastMessage("Choose Date Of Birth");
} else if (!_isChecked) {
toastMessage("Please accept Terms & Conditions");
} else {}
}
},
style:
ElevatedButton.styleFrom(backgroundColor: Colors.red),
child: const Text("SIGN IN",
style: TextStyle(
fontSize: 20,
fontStyle: FontStyle.italic,
color: Colors.black)),
),
),
SizedBox(
height: 20,
),
],
)))),
)),
);
}
}

And from main.dart you call register page as below

import 'package:flutter/material.dart';

import 'RegisterPage.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});

// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: const RegisterPage(),
);
}
}

Thanks happy Coding !!!