A Form widget helps group input fields together to manage their validation and saving easily. A GlobalKey lets you access the form's state from anywhere in your code.
Form widget and GlobalKey in Flutter
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'), ), ], ), )
The GlobalKey<FormState> uniquely identifies the form and lets you call methods like validate() or save().
The validator function returns a string error message if input is invalid, or null if valid.
final _formKey = GlobalKey<FormState>(); Form( key: _formKey, child: TextFormField( validator: (value) => (value ?? '').isEmpty ? 'Enter text' : null, ), )
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
print('Form is valid');
} else {
print('Form is invalid');
}
},
child: Text('Check'),
)final _formKey = GlobalKey<FormState>(); Form( key: _formKey, child: Column( children: [ TextFormField( validator: (value) => (value ?? '').length < 3 ? 'Too short' : null, ), ElevatedButton( onPressed: () { if (_formKey.currentState!.validate()) { _formKey.currentState!.save(); } }, child: Text('Submit'), ), ], ), )
This app shows a form with one text input for a name. When you press Submit, it checks if the name is empty. If valid, it shows a message greeting the user.
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { final _formKey = GlobalKey<FormState>(); final TextEditingController _controller = TextEditingController(); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('Form and GlobalKey Example')), body: Padding( padding: EdgeInsets.all(16), child: Form( key: _formKey, child: Column( children: [ TextFormField( controller: _controller, decoration: InputDecoration(labelText: 'Enter your name'), validator: (value) { if (value == null || value.isEmpty) { return 'Name cannot be empty'; } return null; }, ), SizedBox(height: 20), ElevatedButton( onPressed: () { if (_formKey.currentState!.validate()) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Hello, ${_controller.text}!')), ); } }, child: Text('Submit'), ), ], ), ), ), ), ); } }
Always assign a GlobalKey<FormState> to your form to control it.
Use _formKey.currentState!.validate() to check all validators at once.
You can call _formKey.currentState!.save() to save form data after validation.
The Form widget groups input fields for easy validation and saving.
A GlobalKey lets you access the form's state anywhere in your code.
Use validators to check input and show error messages automatically.
Practice
Form widget in Flutter?Solution
Step 1: Understand the role of Form widget
The Form widget groups input fields so you can validate and save them together.Step 2: Compare options with Form's purpose
Only To group multiple input fields for validation and saving describes grouping input fields for validation and saving, which is the Form's main use.Final Answer:
To group multiple input fields for validation and saving -> Option AQuick Check:
Form groups inputs = D [OK]
- Thinking Form is for navigation or layout
- Confusing Form with buttons or images
- Assuming Form manages app state globally
GlobalKey for a Form in Flutter?Solution
Step 1: Identify correct GlobalKey type for Form
The GlobalKey must be typed asGlobalKey<FormState>to access the Form's state.Step 2: Check each option's type
final _formKey = GlobalKey<FormState>(); usesGlobalKey<FormState>(), which is correct. Others use wrong or incomplete types.Final Answer:
final _formKey = GlobalKey<FormState>(); -> Option BQuick Check:
GlobalKey typed as FormState = A [OK]
- Using GlobalKey without type parameter
- Using GlobalKey<Form> instead of FormState
- Using GlobalKey<State> which is too generic
final _formKey = GlobalKey<FormState>();
Form(
key: _formKey,
child: TextFormField(
validator: (value) => value!.isEmpty ? 'Enter text' : null,
),
);
// Later in code
if (_formKey.currentState!.validate()) {
print('Valid input');
} else {
print('Invalid input');
}
What will be printed if the TextFormField is empty when validate() is called?Solution
Step 1: Understand validator behavior
The validator returns 'Enter text' if the field is empty, which means validation fails.Step 2: Check validate() result
validate() returns false if any validator returns a non-null string, so the else branch runs.Final Answer:
Invalid input -> Option CQuick Check:
Empty input triggers validator error = B [OK]
- Assuming validate() returns true on empty input
- Confusing validator return null with error
- Thinking validate() throws error on empty input
final _formKey = GlobalKey<FormState>();
Form(
key: _formKey,
child: TextFormField(
validator: (value) {
if (value!.length < 3) return 'Too short';
return null;
},
),
);
// Later
if (_formKey.currentState.validate()) {
print('Valid');
}Solution
Step 1: Check usage of currentState
currentState can be null if Form is not mounted, so calling validate() without null check risks error.Step 2: Review code for null safety
The code calls_formKey.currentState.validate()without ! or ?. which causes a compile error in null-safe Dart.Final Answer:
Calling validate() without null check on currentState -> Option DQuick Check:
currentState may be null, needs ! or ? = A [OK]
- Forgetting to add ! after currentState
- Returning boolean from validator instead of string/null
- Using wrong GlobalKey type
GlobalKey and Form to achieve this?Solution
Step 1: Understand Form and GlobalKey usage
One GlobalKey<FormState> is used to manage the whole Form and validate all fields together.Step 2: Evaluate options for best practice
Declare a GlobalKey<FormState>, assign it to Form's key, use validators on fields, call _formKey.currentState!.validate() on submit correctly uses one GlobalKey<FormState>, assigns it to Form, uses validators, and calls validate() once.Final Answer:
Declare a GlobalKey<FormState>, assign it to Form's key, use validators on fields, call _formKey.currentState!.validate() on submit -> Option AQuick Check:
Single GlobalKey<FormState> for whole Form = C [OK]
- Using multiple GlobalKeys for each field
- Not typing GlobalKey as FormState
- Wrapping each field in separate Form widgets
Ready to prove it?
Pass the test and this pattern moves unknown
