Search code examples
flutterdartflutter-dependencies

I don't want textfield to return any string, instead it should just display red error border without error text in flutter


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);
        },
      ),
    );
  }
}

Solution

  • 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) {},
          ),
        )