admin管理员组文章数量:1406052
I am using a custom form text field widget. Its validation is working fine until i submit the form. but once i submit the form and if there is validation error in the field. then if i update and correct the field data, it remain shows error message and red borders. I have spend a lot of time but I am not able to find a solution please see it. And if someone knows how to fix it then let me know. Thank you
import 'package:flutter/material.dart';
class CustomTextField extends StatefulWidget {
final String label;
final TextEditingController? controller;
final String? initialValue;
final String? Function(String?)? validator;
final void Function(String)? onChanged;
final String inputType; // 'text', 'email', 'phone', etc.
final bool isMandatory;
const CustomTextField({
super.key,
required this.label,
this.controller,
this.initialValue,
this.validator,
this.onChanged,
this.inputType = 'text',
this.isMandatory = false,
});
@override
_CustomTextFieldState createState() => _CustomTextFieldState();
}
class _CustomTextFieldState extends State<CustomTextField> {
bool _isValid = true;
bool _isTouched = false;
late FocusNode _focusNode;
@override
void initState() {
super.initState();
_focusNode = FocusNode();
_focusNode.addListener(_onFocusChange); // Listen for focus change
}
@override
void dispose() {
_focusNode.removeListener(_onFocusChange); // Remove the listener
_focusNode.dispose();
super.dispose();
}
void _onFocusChange() {
if (_focusNode.hasFocus) {
// Reset validation when focus is gained
setState(() {
_isTouched = false;
_isValid = true;
});
} else {
// Validate when focus is lost (field is unfocused)
_validate(widget.controller?.text ?? '');
}
}
void _validate(String value) {
setState(() {
_isTouched = true;
if (widget.isMandatory) {
if (widget.inputType == 'email') {
_isValid = _isValidEmail(value);
} else if (widget.inputType == 'phone') {
_isValid = _isValidPhone(value);
} else if (widget.inputType == 'number') {
_isValid = _isValidNumber(value);
} else {
_isValid = value.isNotEmpty;
}
} else {
_isValid = true;
}
});
}
bool _isValidEmail(String email) {
final regex = RegExp(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$');
return regex.hasMatch(email);
}
bool _isValidPhone(String phone) {
final regex = RegExp(r'^\+?[0-9]{10,15}$');
return regex.hasMatch(phone);
}
bool _isValidNumber(String number) {
final regex = RegExp(r'^\d+(\.\d{1,2})?$');
return regex.hasMatch(number);
}
// Expose the validation state
bool isValid() {
return !_isTouched || _isValid;
}
String? _internalValidator(String? value) {
_validate(value ?? '');
if (!_isValid) {
// Return custom error messages based on input type
if (widget.inputType == 'email') {
return 'Inserisci un indirizzo email valido.';
} else if (widget.inputType == 'phone') {
return 'Inserisci un numero di telefono valido.';
} else if (widget.inputType == 'number') {
return 'Inserisci un numero valido.';
} else {
return 'Il campo è obbligatorio.';
}
}
return null;
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextFormField(
controller: widget.controller,
focusNode: _focusNode,
onChanged: (value) {
// Call _validate to update validation state as the user types
_validate(value);
if (widget.onChanged != null) widget.onChanged!(value); // Call the external onChanged if provided
},
keyboardType: _getKeyboardType(widget.inputType),
decoration: InputDecoration(
labelText: widget.label,
labelStyle: const TextStyle(color: Colors.black),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: Colors.grey.shade300),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color: (widget.isMandatory && !_isValid && _isTouched)
? Colors.red
: Colors.grey.shade300,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color: (widget.isMandatory && !_isValid && _isTouched)
? Colors.red
: Colors.blue,
width: 2,
),
),
contentPadding:
const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
),
// Use the internal validator, and allow external override
validator: (value) {
if (widget.validator != null) {
// If a custom validator is provided, use it
return widget.validator!(value);
}
// Otherwise, use the internal validation logic
return _internalValidator(value);
},
),
const SizedBox(height: 4),
],
);
}
TextInputType _getKeyboardType(String type) {
switch (type) {
case 'email':
return TextInputType.emailAddress;
case 'phone':
return TextInputType.phone;
case 'number':
return TextInputType.number;
default:
return TextInputType.text;
}
}
}
I am using a custom form text field widget. Its validation is working fine until i submit the form. but once i submit the form and if there is validation error in the field. then if i update and correct the field data, it remain shows error message and red borders. I have spend a lot of time but I am not able to find a solution please see it. And if someone knows how to fix it then let me know. Thank you
import 'package:flutter/material.dart';
class CustomTextField extends StatefulWidget {
final String label;
final TextEditingController? controller;
final String? initialValue;
final String? Function(String?)? validator;
final void Function(String)? onChanged;
final String inputType; // 'text', 'email', 'phone', etc.
final bool isMandatory;
const CustomTextField({
super.key,
required this.label,
this.controller,
this.initialValue,
this.validator,
this.onChanged,
this.inputType = 'text',
this.isMandatory = false,
});
@override
_CustomTextFieldState createState() => _CustomTextFieldState();
}
class _CustomTextFieldState extends State<CustomTextField> {
bool _isValid = true;
bool _isTouched = false;
late FocusNode _focusNode;
@override
void initState() {
super.initState();
_focusNode = FocusNode();
_focusNode.addListener(_onFocusChange); // Listen for focus change
}
@override
void dispose() {
_focusNode.removeListener(_onFocusChange); // Remove the listener
_focusNode.dispose();
super.dispose();
}
void _onFocusChange() {
if (_focusNode.hasFocus) {
// Reset validation when focus is gained
setState(() {
_isTouched = false;
_isValid = true;
});
} else {
// Validate when focus is lost (field is unfocused)
_validate(widget.controller?.text ?? '');
}
}
void _validate(String value) {
setState(() {
_isTouched = true;
if (widget.isMandatory) {
if (widget.inputType == 'email') {
_isValid = _isValidEmail(value);
} else if (widget.inputType == 'phone') {
_isValid = _isValidPhone(value);
} else if (widget.inputType == 'number') {
_isValid = _isValidNumber(value);
} else {
_isValid = value.isNotEmpty;
}
} else {
_isValid = true;
}
});
}
bool _isValidEmail(String email) {
final regex = RegExp(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$');
return regex.hasMatch(email);
}
bool _isValidPhone(String phone) {
final regex = RegExp(r'^\+?[0-9]{10,15}$');
return regex.hasMatch(phone);
}
bool _isValidNumber(String number) {
final regex = RegExp(r'^\d+(\.\d{1,2})?$');
return regex.hasMatch(number);
}
// Expose the validation state
bool isValid() {
return !_isTouched || _isValid;
}
String? _internalValidator(String? value) {
_validate(value ?? '');
if (!_isValid) {
// Return custom error messages based on input type
if (widget.inputType == 'email') {
return 'Inserisci un indirizzo email valido.';
} else if (widget.inputType == 'phone') {
return 'Inserisci un numero di telefono valido.';
} else if (widget.inputType == 'number') {
return 'Inserisci un numero valido.';
} else {
return 'Il campo è obbligatorio.';
}
}
return null;
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextFormField(
controller: widget.controller,
focusNode: _focusNode,
onChanged: (value) {
// Call _validate to update validation state as the user types
_validate(value);
if (widget.onChanged != null) widget.onChanged!(value); // Call the external onChanged if provided
},
keyboardType: _getKeyboardType(widget.inputType),
decoration: InputDecoration(
labelText: widget.label,
labelStyle: const TextStyle(color: Colors.black),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: Colors.grey.shade300),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color: (widget.isMandatory && !_isValid && _isTouched)
? Colors.red
: Colors.grey.shade300,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color: (widget.isMandatory && !_isValid && _isTouched)
? Colors.red
: Colors.blue,
width: 2,
),
),
contentPadding:
const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
),
// Use the internal validator, and allow external override
validator: (value) {
if (widget.validator != null) {
// If a custom validator is provided, use it
return widget.validator!(value);
}
// Otherwise, use the internal validation logic
return _internalValidator(value);
},
),
const SizedBox(height: 4),
],
);
}
TextInputType _getKeyboardType(String type) {
switch (type) {
case 'email':
return TextInputType.emailAddress;
case 'phone':
return TextInputType.phone;
case 'number':
return TextInputType.number;
default:
return TextInputType.text;
}
}
}
Share
Improve this question
asked Mar 6 at 17:11
saisai
535 bronze badges
2
- Why don't you use form widget to rap the whole list of text form field and call validate() method – Nnamani Daniel Commented Mar 7 at 2:20
- @NnamaniDaniel I am doing it – sai Commented Mar 7 at 8:47
1 Answer
Reset to default 2onChanged: (value) {
_validate(value);
if (widget.onChanged != null) {
widget.onChanged!(value);
}
FormFieldState? fieldState = Form.of(context)?.fields[widget.key];
fieldState?.validate();
},
if above solution not works then use below
onChanged: (value) {
_validate(value);
if (widget.onChanged != null) {
widget.onChanged!(value);
}
// Trigger form validation
Form.of(context)?.validate();
},
Modify your onChanged
method inside TextFormField
:
本文标签: form validation is not updating once the form is submitted in FlutterStack Overflow
版权声明:本文标题:form validation is not updating once the form is submitted in Flutter - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744959769a2634582.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论