I have implemented SignIn
screen in which I created customTextFormField
cause I need to use it in another screen also but my concern is when someone enter the value in email field it will show error in password field even if nothing has been entered yet. Here’s a image:
SignIn:
<code>class SignIn extends StatefulWidget {
const SignIn({super.key});
@override
State<SignIn> createState() => _SignInState();
}
class _SignInState extends State<SignIn> {
TextEditingController _emailController = TextEditingController();
TextEditingController _passwordController = TextEditingController();
final _sformkey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Sign In',
style: TextStyle(fontSize: 22,fontWeight: FontWeight.w600),
),
SizedBox(height: 10),
Form(
key: _sformkey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: Column(
children: [
//Email field
CustomTextFormField(
controller: _emailController,
hintText: 'Email',
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) {
return "Please enter email address";
} else if (!RegExp(
r'^[w-]+(.[w-]+)*@[w-]+(.[w-]+)+$')
.hasMatch(value)) {
return 'Please enter a valid email address';
}
return null;
},
),
SizedBox(height: 4),
//Password field
CustomTextFormField(
controller: _passwordController,
hintText: 'Password',
keyboardType: TextInputType.visiblePassword,
validator: (value) {
if (value == null || value.isEmpty) {
return 'The email or password you have entered is incorrect.';
}
return null;
},
),
SizedBox(height: 20),
//Sign In Button
GestureDetector(
onTap: () {
if (_sformkey.currentState!.validate()) {
Navigator.pushReplacementNamed(context, '/nextpage');
}
},
child: Container(
//SignIn Button
),
),
],
),
),
],
),
),
),
);
}
}
</code>
<code>class SignIn extends StatefulWidget {
const SignIn({super.key});
@override
State<SignIn> createState() => _SignInState();
}
class _SignInState extends State<SignIn> {
TextEditingController _emailController = TextEditingController();
TextEditingController _passwordController = TextEditingController();
final _sformkey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Sign In',
style: TextStyle(fontSize: 22,fontWeight: FontWeight.w600),
),
SizedBox(height: 10),
Form(
key: _sformkey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: Column(
children: [
//Email field
CustomTextFormField(
controller: _emailController,
hintText: 'Email',
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) {
return "Please enter email address";
} else if (!RegExp(
r'^[w-]+(.[w-]+)*@[w-]+(.[w-]+)+$')
.hasMatch(value)) {
return 'Please enter a valid email address';
}
return null;
},
),
SizedBox(height: 4),
//Password field
CustomTextFormField(
controller: _passwordController,
hintText: 'Password',
keyboardType: TextInputType.visiblePassword,
validator: (value) {
if (value == null || value.isEmpty) {
return 'The email or password you have entered is incorrect.';
}
return null;
},
),
SizedBox(height: 20),
//Sign In Button
GestureDetector(
onTap: () {
if (_sformkey.currentState!.validate()) {
Navigator.pushReplacementNamed(context, '/nextpage');
}
},
child: Container(
//SignIn Button
),
),
],
),
),
],
),
),
),
);
}
}
</code>
class SignIn extends StatefulWidget {
const SignIn({super.key});
@override
State<SignIn> createState() => _SignInState();
}
class _SignInState extends State<SignIn> {
TextEditingController _emailController = TextEditingController();
TextEditingController _passwordController = TextEditingController();
final _sformkey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Sign In',
style: TextStyle(fontSize: 22,fontWeight: FontWeight.w600),
),
SizedBox(height: 10),
Form(
key: _sformkey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: Column(
children: [
//Email field
CustomTextFormField(
controller: _emailController,
hintText: 'Email',
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) {
return "Please enter email address";
} else if (!RegExp(
r'^[w-]+(.[w-]+)*@[w-]+(.[w-]+)+$')
.hasMatch(value)) {
return 'Please enter a valid email address';
}
return null;
},
),
SizedBox(height: 4),
//Password field
CustomTextFormField(
controller: _passwordController,
hintText: 'Password',
keyboardType: TextInputType.visiblePassword,
validator: (value) {
if (value == null || value.isEmpty) {
return 'The email or password you have entered is incorrect.';
}
return null;
},
),
SizedBox(height: 20),
//Sign In Button
GestureDetector(
onTap: () {
if (_sformkey.currentState!.validate()) {
Navigator.pushReplacementNamed(context, '/nextpage');
}
},
child: Container(
//SignIn Button
),
),
],
),
),
],
),
),
),
);
}
}
CustomTextFormField:
<code>class CustomTextFormField extends StatelessWidget {
const CustomTextFormField(
{super.key,
required this.controller,
required this.hintText,
required this.keyboardType,
required this.validator});
final TextEditingController controller;
final String hintText;
final TextInputType keyboardType;
final FormFieldValidator<String> validator;
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width * 0.9,
child: TextFormField(
controller: controller,
validator: validator,
decoration: InputDecoration(
hintText: hintText,
border: OutlineInputBorder(),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey.shade400, width: 1.5),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 2),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red.shade900, width: 2),
),
errorMaxLines: 2,
),
keyboardType: keyboardType,
),
);
}
}
</code>
<code>class CustomTextFormField extends StatelessWidget {
const CustomTextFormField(
{super.key,
required this.controller,
required this.hintText,
required this.keyboardType,
required this.validator});
final TextEditingController controller;
final String hintText;
final TextInputType keyboardType;
final FormFieldValidator<String> validator;
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width * 0.9,
child: TextFormField(
controller: controller,
validator: validator,
decoration: InputDecoration(
hintText: hintText,
border: OutlineInputBorder(),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey.shade400, width: 1.5),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 2),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red.shade900, width: 2),
),
errorMaxLines: 2,
),
keyboardType: keyboardType,
),
);
}
}
</code>
class CustomTextFormField extends StatelessWidget {
const CustomTextFormField(
{super.key,
required this.controller,
required this.hintText,
required this.keyboardType,
required this.validator});
final TextEditingController controller;
final String hintText;
final TextInputType keyboardType;
final FormFieldValidator<String> validator;
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width * 0.9,
child: TextFormField(
controller: controller,
validator: validator,
decoration: InputDecoration(
hintText: hintText,
border: OutlineInputBorder(),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey.shade400, width: 1.5),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 2),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red.shade900, width: 2),
),
errorMaxLines: 2,
),
keyboardType: keyboardType,
),
);
}
}
I have also tried AutovalidateMode.onUserInteraction
to prevent this but I don’t understand what silly mistake I am making. I just want that if someone enter the wrong value in email and password it will show error otherwise it will clear the error message.
1