I want to change the borderColor of the TextFormField
to a green color on successfull validation. The color should not fade on losing focus though. Is there something like successBorder
similar to error/focusedBorder.
class FormLayout extends StatelessWidget {
FormLayout({Key? key}) : super(key: key);
final _nameController = TextEditingController();
final _ageController = TextEditingController();
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(15.0),
child: Form(
key: _formKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: Column(
children: [
TextFormField(
validator: validateName,
controller: _nameController,
decoration: InputDecoration(
filled: true,
fillColor: const Color.fromARGB(0, 255, 255, 255),
labelText: "Name",
labelStyle:
const TextStyle(color: Color.fromARGB(255, 90, 98, 104)),
contentPadding: const EdgeInsets.only(left: 10),
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(8),
),
),
errorBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.red),
borderRadius: BorderRadius.circular(12),
),
),
),
const SizedBox(height: 10),
TextFormField(
validator: validateAge,
controller: _ageController,
keyboardType: TextInputType.number,
decoration: InputDecoration(
filled: true,
fillColor: const Color.fromARGB(0, 255, 255, 255),
labelText: "Age",
labelStyle:
const TextStyle(color: Color.fromARGB(255, 90, 98, 104)),
contentPadding: const EdgeInsets.only(left: 10),
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(8),
),
),
errorBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.red),
borderRadius: BorderRadius.circular(12),
),
),
),
const SizedBox(height: 10),
ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.deepPurple[700]),
minimumSize: MaterialStateProperty.all(
const Size.fromHeight(30),
),
),
onPressed: () {
//createRecord();
},
child: const Padding(
padding: EdgeInsets.symmetric(vertical: 15, horizontal: 25),
child: Text(
"Add",
style: TextStyle(fontWeight: FontWeight.bold),
),
)),
const SizedBox(height: 10),
],
),
),
);
String? validateName(String? name) {
if (name == null || name.isEmpty) {
return "*required";
} else if (name.length > 10) {
return "Name should not be longer than 10 characters";
}
return null;
}
String? validateAge(String? age) {
if (age == null || age.isEmpty) {
return "*required";
} else if (age.length > 3) {
return "Invalid age";
}
return null;
}
}
Thanks to the answers by @Timur and kashif
Here's what i did to change the borderColor of the TextFormField
after validation :
1 - Create a
Stateful widget
2 - Declare varibles for each
TextFormField
to hold the Validation state
3 - Create a formKey to track the formState and set
autovalidateMode: AutovalidateMode.onUserInteraction
4 - Use validator to validate
TextFormFields
5 - Use onChanged to update the state of each
TextFormField
by validation variables declared earlier
6 - Set the border color based on the value of the validation variable
working code:
class FormLayout extends StatefulWidget {
const FormLayout({Key? key}) : super(key: key);
@override
State<FormLayout> createState() => _FormLayoutState();
}
class _FormLayoutState extends State<FormLayout> {
final _nameController = TextEditingController();
final _ageController = TextEditingController();
final _formKey = GlobalKey<FormState>();
bool _isNameValidated = false;
bool _isAgeValidated = false;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(15.0),
child: Form(
key: _formKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: Column(
children: [
TextFormField(
validator: validateName,
onChanged: (val) {
setState(() {
_isNameValidated = true;
});
},
controller: _nameController,
decoration: InputDecoration(
filled: true,
fillColor: const Color.fromARGB(0, 255, 255, 255),
labelText: "Name",
labelStyle:
const TextStyle(color: Color.fromARGB(255, 90, 98, 104)),
contentPadding: const EdgeInsets.only(left: 10),
border: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.amber),
borderRadius: BorderRadius.all(
Radius.circular(8),
),
),
errorBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.red),
borderRadius: BorderRadius.circular(12),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
borderSide: BorderSide(
color: _isNameValidated ? Colors.green : Colors.amber),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
borderSide: BorderSide(
color: _isNameValidated ? Colors.green : Colors.grey),
),
),
),
const SizedBox(height: 10),
TextFormField(
validator: validateAge,
onChanged: (val) {
setState(() {
_isAgeValidated = true;
});
},
controller: _ageController,
keyboardType: TextInputType.number,
decoration: InputDecoration(
filled: true,
fillColor: const Color.fromARGB(0, 255, 255, 255),
labelText: "Age",
labelStyle:
const TextStyle(color: Color.fromARGB(255, 90, 98, 104)),
contentPadding: const EdgeInsets.only(left: 10),
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(8),
),
),
errorBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.red),
borderRadius: BorderRadius.circular(12),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
borderSide: BorderSide(
color: _isNameValidated ? Colors.green : Colors.amber),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: _isAgeValidated ? Colors.green : Colors.grey),
borderRadius: BorderRadius.circular(12),
),
),
),
const SizedBox(height: 10),
ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.deepPurple[700]),
minimumSize: MaterialStateProperty.all(
const Size.fromHeight(30),
),
),
onPressed: () {
//createRecord();
},
child: const Padding(
padding: EdgeInsets.symmetric(vertical: 15, horizontal: 25),
child: Text(
"Add",
style: TextStyle(fontWeight: FontWeight.bold),
),
)),
const SizedBox(height: 10),
],
),
),
);
}
//Validator Functions
String? validateName(String? name) {
if (name == null || name.isEmpty) {
return "*required";
} else if (name.length > 10) {
return "Name should not be longer than 10 characters";
}
return null;
}
String? validateAge(String? age) {
if (age == null || age.isEmpty) {
return "*required";
} else if (age.length > 3) {
return "Invalid age";
}
return null;
}