Nowadays, almost every mobile applications use forms for different use-cases.
So, in this blog we are going to explore following things:
- How to implement forms in flutter
- Form Validations
- Form Saving
Implementation
As we know, in flutter everything is widget, just like how everything is Object in Object Oriented Programming Language.
So, in flutter we have widget for form also, termed as form widget.
Form Widget:
It is container for grouping multiple form fields widgets, and helps in validating all these fields before saving the form.
Before writing actual code, let’s go through a terminology called as GlobalKey which you guys will hear frequently, whenever you implement forms in flutter.
What is this GlobalKey ?
GlobalKey use-case in flutter is similar to that of id of the form in html, which is basically used for unique identification of a respective form. And later with the help of this identifier, we validate our form(which we’ll be seeing in later section of this blog).
Now, let’s move further and write code.
class TaskPage extends StatefulWidget {
@override
_TaskPageState createState() => new _TaskPageState();
}
class _TaskPageState extends State<TaskPage> {
// Create a global key that uniquely identifies the Form widget
final _formKey = GlobalKey<FormState>();
Widget build(BuildContext context) {
// Build a Form widget using the _formKey created above.
return Form(
key: this._formKey,
child: new ListView(
children: <Widget>[
// Add TextFormFields and RaisedButton here.
]
)
);
}
}Here, we can see we are using form widget(Form()), which consists of following parts:
- key: this._formKey(which is GlobalKey)
- child: It will be a ListView of multiple widgets like TextFormField, RaisedButton
But, In the form there should be a way by which user can enter text and fill their information. So, that my friend is the job of our TextFormField widget.
TextFormWidget:
The TextFormField in flutter renders a material design text field and can show validations error, whenever the data is invalid.
Ok, So with this we are moving to our next section of our blog ie,
Form Validation:
In all types of form fields widgets(like TextFormField), we have validator() function, which is used to validate the user’s input.
Here, the validator() function, receives the data that the user has entered. It processes the data and if the user’s input is invalid, it returns “error text”, otherwise it returns null.
TextFormField(
// The validator receives the text that the user has entered.
validator: (value) {
if (value.isEmpty) {
return 'Please enter your data';
}
return null;
},
decoration: new InputDecoration(labelText: 'Task Name'),
);You can also provide label text to the TextFormField widget using InputDecoration function as mentioned in the above example.
So, till now we have seen how to create a form, and how to validate its fields in flutter.
And here comes the most interesting part, as how to save forms data ?
Form Saving:
We already have a form with TextFormField, now ideally we should have a button or something like that, which when clicked will save the form data.
So, this is how it will look :
RaisedButton(
onPressed: () {
final form = _formKey.currentState;
// Validate returns true if the form is valid, otherwise false.
if (form.validate()) {
// If the form is valid, display a snackbar.
// In the real world, you'll mostly save data in database.
form.save();
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text('Saving Data')));
}
},
child: Text('Save'),
),Here, whenever user click on Save button(RaisedButton), we are doing following things:
- first, we check whether the form is valid or invalid using form.validate()
- If the form is valid, then only we show SnackBar or save valid form data to database/server depending on our use-cases.
To summarise it, this is what happens behind the scenes after button is pressed:
- For form validation we use _formKey(GlobalKey) method formKey.currentState
- _formKey.currentState gives us the FormState
- This FormState has method called as validate() and we invoke this method
- validate() method runs the validator() function of each and every form fields (like that of TextFormField)
- If any of the form fields contains error(is invalid), validate() method rebuilds the whole form with error message and return false
- Otherwise if form fields doesn’t have any error , validate() returns true and then it successfully executes the code inside condition (in our case showing SnackBar)
Below is the final code with all the changes:
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: TaskPage(),
),
),
);
}
}
class TaskPage extends StatefulWidget {
@override
_TaskPageState createState() => new _TaskPageState();
}
class _TaskPageState extends State<TaskPage> {
GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final _formKey = GlobalKey<FormState>();
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
body: addTaskForm
);
}
Widget get addTaskForm {
return new Container(
padding: new EdgeInsets.all(20.0),
child: new Form(
key: this._formKey,
child: new ListView(
children: <Widget>[
new TextFormField(
decoration: new InputDecoration(labelText: 'Task Name'),
// The validator receives the text that the user has entered.
validator: (val) {
if (val.isEmpty) {
return 'Please enter your task name.';
} else {
return null;
}
},
onChanged: (value) {
print(value);
},
),
new RaisedButton(
onPressed: () {
final form = _formKey.currentState;
// Validate returns true if the form is valid, otherwise false.
if (form.validate()) {
// If the form is valid, display a snackbar.
// In the real world, you'll mostly save data in database by calling server.
form.save();
Scaffold
.of(context)
.showSnackBar(SnackBar(content: Text('Saving Data')));
}
},
child: Text('Save'),
),
],
),
)
);
}
}Hope you liked the blog, for more such blogs stay tuned … 🙂
