How to clear error message in TextFormField in Flutter
here is a suitable solution to this problem.
You don't actually need to use onChanged
or any tips causing side-effects, I solved it by creating a class property which is initialized to false
:
bool _autovalidate = false;
The Form Widget has a named property autovalidate
. You should pass it the previous boolean:
Form(
key: _textKey,
autovalidate: _autovalidate,
...
)
And in your Submit button onPressed()
method, you should update the _autovalidate
boolean to be true
if the form is invalid
, this will make the form to auto validate the TextFormField on every onChanged
call:
RaisedButton(
onPressed: () {
if (_textKey.currentState.validate()) {
print('valid');
} else {
print('invalid');
setState(() => _autoValidate = true);
}
},
child: Text(login),
)
I hope it helped Somebody.
EDIT (Nov 2020)
autovalidate
was deprecated after v1.19.0.
Instead use autovalidateMode
:
Form(
autovalidateMode: AutovalidateMode.onUserInteraction`.
...
)
January 2021
...
AutovalidateMode _autoValidate = AutovalidateMode.disabled;
Form(
key: _textKey,
autovalidateMode: _autovalidate,
...
)
RaisedButton(
onPressed: () {
if (_textKey.currentState.validate()) {
print('valid');
} else {
print('invalid');
setState(() => _autoValidate = AutovalidateMode.always);
}
},
child: Text("login"),
)
The problem here is errorText
is automatically managed by the validator
field of the TextFormField
. At the same time, the simple solution is to handle the errorText
manually.
Step 1: Create
- String field,
_errorText
initialised tonull
. The field will hold the error message that needs to be shown. - Boolean field,
_error
initialised tofalse
. The filed istrue
if there is an error otherwisefalse
.
Step 2:
- Assign
_errorText
toTextFormField
Step 3 (Important):
Make sure that
TextFormField
validator
returns anull
value.Handle the validation here and assign the proper error message to
_errorText
.Update
_error
state correspondingly.
Step 4 (Important):
- Reset
_errorText
and_error
. This will remove the error from field soon as you start editing.
Step 5:
- Trigger field validation in the
onFieldSubmitted
and manage your code flow...
import 'package:flutter/material.dart';
class WorkGround extends StatefulWidget {
@override
_WorkGroundState createState() => _WorkGroundState();
}
class _WorkGroundState extends State<WorkGround> {
final _formKey = GlobalKey<FormState>();
final _usernameFocusNode = FocusNode();
final _phoneNumberFocusNode = FocusNode();
/*
* Step 1.
* */
String _userNameErrorText;
bool _userNameError = false;
String _phoneNumberErrorText;
bool _phoneNumberError = false;
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
TextFormField(
focusNode: _usernameFocusNode,
decoration: InputDecoration(
labelText: 'Username',
/*
* Step 2
* */
errorText: _userNameErrorText, // Handling error manually
),
textInputAction: TextInputAction.next,
/*
* Step 3
* */
validator: (value) {
setState(() {
if(value.isEmpty) {
_userNameError = true;
_userNameErrorText = 'Enter Username';
}
});
return null; // Return null to handle error manually.
},
/*
* Step 4
* */
onChanged: (value) {
setState(() {
_userNameError = false;
_userNameErrorText = null; // Resets the error
});
},
/*
* Step 5
* */
onFieldSubmitted: (value) {
_formKey.currentState.validate(); // Trigger validation
if(!_userNameError) {
FocusScope.of(context).requestFocus(_phoneNumberFocusNode);
}
},
),
TextFormField(
focusNode: _phoneNumberFocusNode,
decoration: InputDecoration(
labelText: 'Phone Number',
/*
* Step 2
* */
errorText: _phoneNumberErrorText, // Handling error manually
),
textInputAction: TextInputAction.done,
/*
* Step 3
* */
validator: (value) {
setState(() {
if(value.isEmpty) {
_phoneNumberError = true;
_phoneNumberErrorText = 'Enter Phone number';
} else if( value.length < 10) {
_phoneNumberError = true;
_phoneNumberErrorText = 'Invalid Phone number';
}
});
return null; // Return null to handle error manually.
},
/*
* Step 4
* */
onChanged: (value) {
setState(() {
_phoneNumberError = false;
_phoneNumberErrorText = null; // Resets the error
});
},
/*
* Step 5
* */
onFieldSubmitted: (value) {
_formKey.currentState.validate(); // Trigger validation
if(!_phoneNumberError) {
// submit form or whatever your code flow is...
}
},
),
],
),
),
);
}
}