Flutter's Form
widget is similar to a <form>
tag in HTML: it groups form
fields together to conveniently validate them and to save their content.
Form
widget can contain multipe FormField
widgets, specifically they can be
TextFormField
widgets for text fields.
final key = GlobalKey<FormState>();
String _name;
...
Form(
key: key,
child: TextFormField(
decoration: InputDecoration(labelText: 'Name'),
validator: (value) => value.isEmpty ? '`Name` field cannot be empty.' : null,
onSaved: (value) => _name = value,
),
);
validator
parameter specifies a function that receives the current value of
given field once the #validate
(inherited from FormField
) is invoked. The
function should return null
if the field is valid, and an error string
otherwise.
onSaved
parameter specifies a function that receives the current value of
given field once the #save
(inherited from FormField
) is invoked. The
function is usually used to store form's transient values in variables.
key
is an unique identifier that allows to reference the widget, for example,
to invoke its state #validate
or #save
methods.
RaisedButton(
onPressed: () {
final form = key.currentState;
if (form.validate()) {
form.save();
// ...
}
},
child: Text('Submit Form'),
)
Once #validate
is invoked, Flutter goes through every FormField
widget
contained within the Form
widget referenced by key
and it calls the function
defined in its validator
paramter. The process is identical for the #save
invocation, except that functions defined in onSaved
are invoked.
Full source code:
import 'package:flutter/material.dart';
class FormWithValidation extends StatefulWidget {
@override
_FormWithValidationState createState() => _FormWithValidationState();
}
class _FormWithValidationState extends State<FormWithValidation> {
String name = "";
final key = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Form with Validation"),
),
body: SingleChildScrollView(
child: Form(
key: key,
child: Column(
children: <Widget>[
ListTile(
title: TextFormField(
validator: (value) => value.isEmpty
? "`NAME` field cannot be empty"
: null,
onSaved: (value) => name = value,
decoration: InputDecoration(labelText: 'NAME'),
),
),
ListTile(
title: RaisedButton(
onPressed: () {
final form = key.currentState;
if (form.validate()) {
form.save();
// ...
}
},
child: Text('Submit Form'),
),
)
],
),
),
),
);
}
}