4.8 KiB
4.8 KiB
| name | description |
|---|---|
| features-forms-validation | Flutter form validation - Form, FormField, validators, and form handling patterns |
Form Validation
Flutter provides comprehensive form validation capabilities.
Basic Form
final _formKey = GlobalKey<FormState>();
Form(
key: _formKey,
child: Column(
children: [
TextFormField(
decoration: const InputDecoration(labelText: 'Email'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter email';
}
return null;
},
),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
// Form is valid
}
},
child: const Text('Submit'),
),
],
),
)
Email Validation
TextFormField(
decoration: const InputDecoration(labelText: 'Email'),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter email';
}
if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(value)) {
return 'Please enter valid email';
}
return null;
},
)
Password Validation
TextFormField(
decoration: const InputDecoration(labelText: 'Password'),
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter password';
}
if (value.length < 8) {
return 'Password must be at least 8 characters';
}
if (!RegExp(r'[A-Z]').hasMatch(value)) {
return 'Password must contain uppercase letter';
}
if (!RegExp(r'[0-9]').hasMatch(value)) {
return 'Password must contain number';
}
return null;
},
)
Custom Validator
String? validatePhone(String? value) {
if (value == null || value.isEmpty) {
return 'Please enter phone number';
}
if (!RegExp(r'^\+?[1-9]\d{1,14}$').hasMatch(value)) {
return 'Please enter valid phone number';
}
return null;
}
// Usage
TextFormField(
decoration: const InputDecoration(labelText: 'Phone'),
validator: validatePhone,
)
FormField
Custom form field with validation.
FormField<String>(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter value';
}
return null;
},
builder: (field) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextField(
onChanged: field.didChange,
decoration: InputDecoration(
labelText: 'Custom Field',
errorText: field.errorText,
),
),
],
);
},
)
Autovalidate Mode
Form(
autovalidateMode: AutovalidateMode.onUserInteraction,
child: TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Required';
}
return null;
},
),
)
Form State
final _formKey = GlobalKey<FormState>();
// Validate form
if (_formKey.currentState!.validate()) {
// Form is valid
}
// Save form
_formKey.currentState!.save();
// Reset form
_formKey.currentState!.reset();
Multiple Fields
final _formKey = GlobalKey<FormState>();
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
Form(
key: _formKey,
child: Column(
children: [
TextFormField(
controller: _emailController,
decoration: const InputDecoration(labelText: 'Email'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Required';
}
return null;
},
),
TextFormField(
controller: _passwordController,
decoration: const InputDecoration(labelText: 'Password'),
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Required';
}
return null;
},
),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
final email = _emailController.text;
final password = _passwordController.text;
// Process form
}
},
child: const Text('Submit'),
),
],
),
)
Key Points
- Use
Formwidget to wrap form fields - Use
GlobalKey<FormState>to access form state - Use
validatorfunction for field validation - Return
nullfor valid values, error string for invalid - Use
validate()to check form validity - Use
save()to save form values - Use
reset()to reset form - Set
autovalidateModefor real-time validation - Use regex patterns for complex validation