What I want to do is disable the elevated button until the text form field is valid. And then once the data is valid the elevated button should be enabled. I have reviewed several SO threads and a few articles on Google about how to disable a button until the text form field is validated. They all focused on whether or not the text form field was empty or not which is not what I am asking about here. I'm using regex to determine if the user has entered a valid email address. Only when the data entered is a valid email is the data considered valid. That is when I want the button to become enabled. If I try to call setState with a boolean in the validateEmail method I get the error:
setState() or markNeedsBuild() called during build.
Any help will be appreciated. Thank you.
class ResetPasswordForm extends StatefulWidget {
const ResetPasswordForm({Key? key}) : super(key: key);
@override
_ResetPasswordFormState createState() => _ResetPasswordFormState();
}
class _ResetPasswordFormState extends State<ResetPasswordForm> {
final _formKey = GlobalKey<FormState>();
final TextEditingController _emailController = TextEditingController();
String? validateEmail(String? value) {
String pattern = ValidatorRegex.emailAddress;
RegExp regex = RegExp(pattern);
if (value == null || value.isEmpty || !regex.hasMatch(value)) {
return ValidatorString.enterValidEmail;
} else {
return null;
}
}
@override
void dispose() {
_emailController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Form(
key: _formKey,
child: TextFormField(
controller: _emailController,
validator: (value) => validateEmail(value),
),
),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
Auth().resetPassword(
context,
_emailController.text.trim(),
);
}
},
child: const Text('Reset Password'),
),
],
);
}
}