In Flutter, a form is the best way to handle the validation of all text fields, dropdowns, etc. Otherwise, you would need to manage each text field individually, and if the form is too large, it becomes very difficult to handle. Additionally, you would require multiple if-else
conditions for validation. To make it simple and handling validation of text field and form is properly filled or not we can use Form
Below code is an example how we can use form in flutter:
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.0),
child: MyCustomForm(),
),
),
);
}
}
class MyCustomForm extends StatefulWidget {
@override
_MyCustomFormState createState() => _MyCustomFormState();
}
class _MyCustomFormState extends State<MyCustomForm> {
final _formKey = GlobalKey<FormState>(); // Form key to manage state
String _name = '';
String _roll = '';
int _age = 0;
@override
Widget build(BuildContext context) {
return Form(
key: _formKey, //for uniqueness of Form
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Name Input Field
TextFormField(
decoration: InputDecoration(labelText: 'Name'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your name';
}
return null;
},
onSaved: (value) {
_name = value!;
},
),
SizedBox(height: 16),
// Roll Number Input Field
TextFormField(
decoration: InputDecoration(labelText: 'Roll Number'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your roll number';
}
return null;
},
onSaved: (value) {
_roll = value!;
},
),
SizedBox(height: 16),
// Age Input Field
TextFormField(
decoration: InputDecoration(labelText: 'Age'),
keyboardType: TextInputType.number,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your age';
}
if (int.tryParse(value) == null) {
return 'Please enter a valid number';
}
return null;
},
onSaved: (value) {
_age = int.parse(value!);
},
),
SizedBox(height: 20),
// Submit Button
///Here form will handle smoothly
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save(); // Save form fields
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Hello, $_name! Your roll is $_roll, and you are $_age years old.')),
);
}
},
child: Text('Submit'),
),
],
),
);
}
}
Benefits of Using a Form over Individual Text Fields
- Centralized State Management: Easily handle all text field , otherwise you would need to handle each field separately.
- Simplifies Validation Logic:
- Forms allow validation across multiple fields using a single
validate()
method. - You can ensure all fields are valid at once before submission.
- Forms allow validation across multiple fields using a single
- Ease of Input Handling:
- The
save()
method saves all field values in a single call. Without a form, you’d have to manage each field’s state and save logic individually.
- The
- Error Management:
- A form widget collects errors for all fields, making debugging more straightforward compared to individual text fields where validation is scattered.
- Reusable Code:
- Grouping fields inside a form widget makes the code modular and easier to reuse in different parts of the app.
Why not use Individual TextFormField
Widgets ?
- Complexity in Management:
- Without a form, every text field will require separate controllers and validation logic, increasing code complexity and handling validation become too complex for all text fields.
- Scattered Validation Logic:
- If you have multiple fields without a form, each field will require its own validation function, time consuming and rework on validation.
- Redundant Code:
- Using individual text fields leads to code duplication, especially when dealing with multiple input fields, cannot test all cases and not 100% sure that all validation of text field covered.