Flutter_form_builder: How to clear errors when value is changed to valid

Created on 20 Feb 2020  路  4Comments  路  Source: danvick/flutter_form_builder

Question

I want to clear message while value has been changed to valid. For now it cleared when we hit submit button.

duplicate

Most helpful comment

"The problem with that method is that validation will run even before any input is done by the user, that's a Flutter issue and not necessarily an issue with this package."

I just faced this issue
It's definitely wrong UX
As a user I want to validate field either after I make some changes or focus the field

I came up with this solution
Maybe I'm wrong, maybe I don't, but I've got desired behavior
As I can see from
@danvick please, take a look and tell if it's possible to implement this

class TextField extends StatefulWidget {

  @override
  _FTextFieldState createState() => _FTextFieldState();
}

class _TextFieldState extends State<TextField> {
  bool pristine = true;

  void activate() {
    setState(() {
      pristine = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return FormBuilderTextField(
        attribute: 'login',
        autovalidate: !pristine,
        maxLines: 1,
        onChanged: (value) => activate(),
        decoration: InputDecoration(labelText: 'Login'),
        validators: [
          FormBuilderValidators.required()
        ]
    );
  }
}

Update:
I believe it's possible and requires couple changes in in FormBuilderTextField:

  • add bool _isPristine = true to state;
  • modify autovalidate: widget.autovalidate ? !_isPristine : false in build;
  • modify onChanged logic a bit
_effectiveController.addListener(() {
    if (widget.onChanged != null) {
        widget.onChanged(_effectiveController.text);

        if (widget.autovalidate == true && _isPristine == true) {
            setState(() {
                _isPristine = false;
            });
         }
    }
});

All 4 comments

You can set autovalidate to true on either the whole form or the field.

The problem with that method is that validation will run even before any input is done by the user, that's a Flutter issue and not necessarily an issue with this package.

"The problem with that method is that validation will run even before any input is done by the user, that's a Flutter issue and not necessarily an issue with this package."

I just faced this issue
It's definitely wrong UX
As a user I want to validate field either after I make some changes or focus the field

I came up with this solution
Maybe I'm wrong, maybe I don't, but I've got desired behavior
As I can see from
@danvick please, take a look and tell if it's possible to implement this

class TextField extends StatefulWidget {

  @override
  _FTextFieldState createState() => _FTextFieldState();
}

class _TextFieldState extends State<TextField> {
  bool pristine = true;

  void activate() {
    setState(() {
      pristine = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return FormBuilderTextField(
        attribute: 'login',
        autovalidate: !pristine,
        maxLines: 1,
        onChanged: (value) => activate(),
        decoration: InputDecoration(labelText: 'Login'),
        validators: [
          FormBuilderValidators.required()
        ]
    );
  }
}

Update:
I believe it's possible and requires couple changes in in FormBuilderTextField:

  • add bool _isPristine = true to state;
  • modify autovalidate: widget.autovalidate ? !_isPristine : false in build;
  • modify onChanged logic a bit
_effectiveController.addListener(() {
    if (widget.onChanged != null) {
        widget.onChanged(_effectiveController.text);

        if (widget.autovalidate == true && _isPristine == true) {
            setState(() {
                _isPristine = false;
            });
         }
    }
});

Duplicate of #29.

FormBuilderTextField(
                    attribute: "firstName",
                    decoration: _inputDecoration('First Name'),
                    maxLength: 50,
                    validators: [
                      FormBuilderValidators.required(
                          errorText: 'This field cannot be empty.'),
                    ],
                    onChanged: (value) {
                      _fbKey.currentState.fields['firstName'].currentState
                          .validate();
                    },
                  ),
FormBuilderTextField(
                    attribute: "lastName",
                    decoration: _inputDecoration('Last Name'),
                    maxLength: 50,
                    validators: [
                      FormBuilderValidators.required(
                          errorText: 'This field cannot be empty.'),
                    ],
                    onChanged: (value) {
                      _fbKey.currentState.fields['lastName'].currentState
                          .validate();
                    },
                  )
Was this page helpful?
0 / 5 - 0 ratings