Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to clear error message in TextFormField in Flutter

Tags:

In my code I validate phone number. If phone number is incorrect - I show error message. But, when user starts to edit number I want to hide this error message.

I've found the solution with currentState.reset(), but it seems not the good one. I have to handle issues with saving text and cursor position. And I still have one small artifact. Normally when I press and hold backspace - it deletes symbols one by one. If I do it when error message is shown - then error message disappears and only one symbol is deleted.

Does anybody know the right solution for this case?

final TextEditingController controller = TextEditingController();
final RegExp _phoneRegex = RegExp(r"^\+{1}\d{10, 15}\$");
bool isError = false;
TextSelection currentPosition;

return Column(
  children: <Widget>[
    Form(
        key: _textKey,
        child: TextFormField(
          controller: controller,
          validator: (str) {
            isError = true;
            if (str.isEmpty) {
              return err_empty_field;
            } else if (!_phoneRegex.hasMatch(str)) {
              return err_invalid_phone;
            }
            isError = false;
          },
        ),
        onChanged: () {
          if (controller.selection.start < 0 &&
              controller.text.length > 0) {
            TextSelection position =
                controller.text.length > currentPosition.start
                    ? currentPosition
                    : TextSelection.fromPosition(
                        TextPosition(offset: controller.text.length));
            controller.selection = position;
          }
          if (isError) {
            isError = false;
            currentPosition = controller.selection;
            if (currentPosition.start > controller.text.length) {
              currentPosition = TextSelection.fromPosition(
                  TextPosition(offset: controller.text.length));
            }
            String currentText = controller.text;
            _textKey.currentState.reset();
            controller.text = currentText;
            controller.selection = currentPosition;
          }
        },
      ),
    RaisedButton(
      onPressed: () {
        _textKey.currentState.validate();
      },
      child: Text(login),
    )
  ],
);
like image 381
Andrey Turkovsky Avatar asked Apr 23 '19 11:04

Andrey Turkovsky


People also ask

How do I clear a text box in flutter?

clear(); As mentioned above there are various properties of TextEditingController(). One of them is clear(), and we will use it to clear the TextField.

How do you turn off editing in TextFormField flutter?

How do I turn off TextField in Flutter? TextField and TextFormField both have an argument called enabled. You can control it using a boolean variable. enabled=true means it will act as an editing text field whereas enabled=false will Disable the TextField Widget.


1 Answers

here is a suitable solution to this problem.

You don't actually need to use onChanged or any tips causing side-effects, I solved it by creating a class property which is initialized to false:

bool _autovalidate = false;

The Form Widget has a named property autovalidate. You should pass it the previous boolean:

Form(
  key: _textKey,
  autovalidate: _autovalidate,
  ... 
)

And in your Submit button onPressed() method, you should update the _autovalidate boolean to be true if the form is invalid, this will make the form to auto validate the TextFormField on every onChanged call:

RaisedButton(
  onPressed: () {
    if (_textKey.currentState.validate()) {
      print('valid');
    } else {
      print('invalid');
      setState(() => _autoValidate = true);
    }
  },
  child: Text(login),
)

I hope it helped Somebody.

EDIT (Nov 2020)

autovalidate was deprecated after v1.19.0.
Instead use autovalidateMode:

Form(
  autovalidateMode: AutovalidateMode.onUserInteraction`.
  ...
)
like image 70
coolbeatz71 Avatar answered Sep 19 '22 12:09

coolbeatz71