How to Create Form in Flutter: Simple Guide with Example
To create a form in Flutter, use the
Form widget combined with TextFormField widgets for input fields. Wrap your input fields inside a Form and use a GlobalKey to manage validation and submission.Syntax
The basic syntax to create a form in Flutter involves using the Form widget with a GlobalKey<FormState> to manage the form state. Inside the form, use TextFormField widgets for user inputs. Each TextFormField can have a validator function to check input validity.
- Form: Container for form fields.
- GlobalKey<FormState>: Controls form state and validation.
- TextFormField: Input field with validation support.
- validator: Function to validate input.
dart
final _formKey = GlobalKey<FormState>();
Form(
key: _formKey,
child: Column(
children: [
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter some text';
}
return null;
},
),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
// Process data
}
},
child: Text('Submit'),
),
],
),
)Example
This example shows a simple Flutter app with a form containing a single text input. It validates that the input is not empty and shows a message when the form is submitted successfully.
dart
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('Flutter Form Example')), body: Padding( padding: EdgeInsets.all(16), child: MyCustomForm(), ), ), ); } } class MyCustomForm extends StatefulWidget { @override _MyCustomFormState createState() => _MyCustomFormState(); } class _MyCustomFormState extends State<MyCustomForm> { final _formKey = GlobalKey<FormState>(); @override Widget build(BuildContext context) { return Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TextFormField( decoration: InputDecoration(labelText: 'Enter your name'), validator: (value) { if (value == null || value.isEmpty) { return 'Please enter some text'; } return null; }, ), Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: ElevatedButton( onPressed: () { if (_formKey.currentState!.validate()) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Processing Data')), ); } }, child: Text('Submit'), ), ), ], ), ); } }
Output
A screen with an AppBar titled 'Flutter Form Example', a text input labeled 'Enter your name', and a Submit button. If the input is empty and Submit is pressed, an error message appears below the input. If valid, a snackbar with 'Processing Data' shows.
Common Pitfalls
- Not assigning a
GlobalKey<FormState>to theFormwidget, so validation cannot be triggered. - Forgetting to call
_formKey.currentState!.validate()before processing data. - Not returning
nullfrom the validator when input is valid, which causes validation to fail. - Using
TextFieldinstead ofTextFormFieldwhen validation is needed.
dart
/* Wrong way: No GlobalKey and no validation call */ Form( child: TextFormField( validator: (value) => value!.isEmpty ? 'Enter text' : null, ), ); /* Right way: Use GlobalKey and validate on submit */ final _formKey = GlobalKey<FormState>(); Form( key: _formKey, child: Column( children: [ TextFormField( validator: (value) => value!.isEmpty ? 'Enter text' : null, ), ElevatedButton( onPressed: () { if (_formKey.currentState!.validate()) { // proceed } }, child: Text('Submit'), ), ], ), );
Quick Reference
- Form: Wraps input fields to group them.
- GlobalKey<FormState>: Controls form state and validation.
- TextFormField: Input field with built-in validation support.
- validator: Function returning error string or null.
- _formKey.currentState!.validate(): Checks all validators and returns true if all valid.
Key Takeaways
Use a GlobalKey to manage and validate your form.
Wrap input fields inside a Form widget to group them logically.
Use TextFormField with a validator function for input validation.
Call _formKey.currentState!.validate() to trigger validation before submission.
Return null from validator when input is valid to avoid errors.