Below textfield is getting rendered in the table. I want to implement input validation for textfield. Let's say if it is required, the validation is being implemented but the problem is, because I don't want the text in error, I have done, errorStyle: TextStyle(color: Colors.transparent, fontSize: 0). Then also whenever the validator is getting called the textfield's bottom border shifts a bit upwards which looks ugly.
class _TableTextInputFieldComponentState
extends ConsumerState<TableTextInputFieldComponent> {
TextEditingController textInputController = TextEditingController();
String columnName = '';
Map<String, dynamic> columnAccess = {};
Map<String, dynamic> columnNumberTypeFieldDetail = {};
bool isrequired = false;
bool isStrikeThrough = false;
bool isEmpty = false;
FocusNode focusNode = FocusNode();
String errorMessage = '';
u/override
void initState() {
// TODO: implement initState
isStrikeThrough = widget.isStrikeThrough;
if (widget.indexOfRow == 0) {
isStrikeThrough = false;
}
columnNumberTypeFieldDetail = widget.column;
columnName = columnNumberTypeFieldDetail['name'];
columnAccess = columnNumberTypeFieldDetail['access'];
if (columnNumberTypeFieldDetail.containsKey('validators')) {
if (columnNumberTypeFieldDetail['validators'].containsKey('required')) {
isrequired = columnNumberTypeFieldDetail['validators']['required'];
}
}
if (widget.value != '' && widget.value != null) {
textInputController.text =
widget.value.toString(); // Convert to string if it's a number
}
// Add the focusNode listener to update the state
focusNode.addListener(() {
updateEmptyState();
});
super.initState();
}
// Extracted method to update the isEmpty state
void updateEmptyState() {
setState(() {
isEmpty = textInputController.text.isEmpty;
});
}
u/override
Widget build(BuildContext context) {
return SizedBox(
//adding height didn't have any effect really.[the textfield is covering all whole datacell, but the moment validator is called, the textfield shrinks and it's bottom border shifts a bit upwards][1]
height: 200,
child: TextFormField(
controller: textInputController,
focusNode: focusNode,
readOnly: widget.readOnly || isStrikeThrough,
style: TextStyle(
decoration: isStrikeThrough
? TextDecoration.lineThrough
: TextDecoration.none,
),
decoration: const InputDecoration(
isCollapsed: true,
contentPadding: EdgeInsets.fromLTRB(5, 20, 5, 13),
errorStyle: TextStyle(color: Colors.transparent, fontSize: 0),
filled: false,
),
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: isrequired
? (value) {
if (value == null || value.isEmpty) {
errorMessage = 'Text is required';
return errorMessage;
}
return null;
}
: null,
onChanged: (value) {
//Handle string input
value = textInputController.text;
widget.onValueChangeInTable(
widget.indexOfRow, value, columnName, columnAccess);
},
),
);
}
}
Try This Code
SizedBox(
child: TextFormField(
controller: controller.textInputController,
readOnly: false,
style: TextStyle(decoration: TextDecoration.none),
decoration: InputDecoration(
isCollapsed: true,
contentPadding: EdgeInsets.zero,
errorStyle: TextStyle(color: Colors.transparent, fontSize: 0),
errorBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.red, width: 2)),
focusedErrorBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.red, width: 2)),
filled: false,
),
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (value) {
if (value == null || value.isEmpty) {
return '';
}
return null;
},
onChanged: (value) {},
),
)