Skip to content

fix autovalidate in form widget to validate only when value changes#56132

Closed
ashank96 wants to merge 5 commits into
flutter:masterfrom
ashank96:fix_form_autovalidate
Closed

fix autovalidate in form widget to validate only when value changes#56132
ashank96 wants to merge 5 commits into
flutter:masterfrom
ashank96:fix_form_autovalidate

Conversation

@ashank96

@ashank96 ashank96 commented May 1, 2020

Copy link
Copy Markdown

Description

The current form widget runs _validate function on every new build even when the form state is not changed, if widget.autovalidate == true, which as a result runs validations over all the fields in the form and you see errors corresponding each field due to empty field validation logic(if written by the developer), as soon as the user lands on to the screen. The PR modifies the autovalidate feature such that it functions only when the state value for a field is changed at least once.

Related Issues

36154
48876

Tests

I added the following tests:

in flutter_test.dart file added test case under description autovalidate functions only when state value changes at least once

Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I signed the [CLA].
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I updated/added relevant documentation (doc comments with ///).
  • All existing and new tests are passing.
  • The analyzer (flutter analyze --flutter-repo) does not report any problems on my PR.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Did any tests fail when you ran them? Please read [Handling breaking changes].

  • No, no existing tests failed, so this is not a breaking change, except for one test case that checks for a field with error text, in form_test.dart 'Multiple TextFormFields communicate', which I feel is not a breaking change. Did the required modifications to make it work fine with a line change.

@SpajicM

SpajicM commented May 2, 2020

Copy link
Copy Markdown

@ashank96 Related discussion at #48155

cc: @justinmc

@nateshmbhat

nateshmbhat commented May 2, 2020

Copy link
Copy Markdown

@SpajicM @justinmc

This PR is easily the simplest (maybe even best) solution to that particular issue where autovalidate is not supposed to show error when screen is rendered for first time.

The discussion at #48155 is part of a bigger issue and about having more control over validation and an entirely different way of handling it. I'm not fully sure if that is going to be merged anytime soon.

In the meanwhile, this PR serves as the right fix for the initial render error text issue.

@ashank96

ashank96 commented May 2, 2020

Copy link
Copy Markdown
Author

@SpajicM @justinmc
It's very rare to have a scenario where autovalidate would be needed at the initial state itself. Mostly, we would want it only when user has tried to change some value in the field.

Hence, as @nateshmbhat seconds, this issue is quite common across all the firms/developers who are using forms in production, and needs an update on this as soon as possible. This PR can be a small but useful fix to the same.

@SpajicM

SpajicM commented May 2, 2020

Copy link
Copy Markdown

@ashank96 @nateshmbhat I totally agree, I only linked the other PR for informational purposes.

@ashank96

ashank96 commented May 3, 2020

Copy link
Copy Markdown
Author

@justinmc Can you please review the PR ? TIA.

@justinmc

justinmc commented May 6, 2020

Copy link
Copy Markdown
Contributor

Sorry for the delay in taking a look at this and thanks for opening a PR. This is going to be tricky because it skirts the definition of a breaking change (see Flutter's breaking change policy). I have been trying to avoid changing this behavior directly because it seems to me that there could be apps that are relying on this behavior.

I'm going to try to get a conclusion on the discussion of how to fix this long term (started in #48155). If that solution allows for changing this behavior then I can try to check if this change would break anyone's app and figure out a way forward.

I'll try to post back with updates.

@nateshmbhat

nateshmbhat commented May 6, 2020

Copy link
Copy Markdown

If we're concerned about the breaking change, May be we could add an additional optional parameter (say validateOnFirstBuild) which defaults to true for backward compatibility.

But honestly, I feel we need to fix this even if it's a breaking change because this behavior is not something 99% would want.

Adding a flag like that again just for backward compatibility (which was in fact a bug) is like not taking care of the bug in some way.

@fluttergithubbot fluttergithubbot added the framework flutter/packages/flutter repository. See also f: labels. label May 8, 2020

@chunhtai chunhtai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is trying to solve the same thing as this pr #56365

// Only autovalidate if the widget is also enabled
if (widget.autovalidate && widget.enabled)
// Only autovalidate if the widget is also enabled and state value has changed at least once
if (widget.autovalidate && widget.enabled && _isStateDirty)

@chunhtai chunhtai May 8, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also a reset method, it will be called when the the form reset. In that case you might want to reset this state dirty to false

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done the changes

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, this PR tries to achieve the same thing as the other one you are referring to. It's just that this PR was raised pretty earlier than the other one.

@ashank96

ashank96 commented May 9, 2020

Copy link
Copy Markdown
Author

What if a developer wants to validate when the overall form is submitted, and the user submits the form but never focused or changed a field? I think it unexpectedly wouldn't show an error message for the field. That case should be handled.

@justinmc Regarding your concern, before the developer calls formstate.save() for the whole form without changing any value, he will obviously call formstate.validate() which will take care of the full form validations even if the value is not changed or field is not focused.
As following function will be called, which does not take into account the current changed state flag anyways:
bool validate() { setState(() { _validate(); }); return !hasError; }

@chunhtai

Copy link
Copy Markdown
Contributor

Another thing to think about is the form.autovalidate which is doing the same thing except it only validate after the second build.

@justinmc

Copy link
Copy Markdown
Contributor

@ashank96 I'm going to close this PR as it looks like #56365 will achieve the same thing and is closer to being merged. Take a look at that PR and let me know if it meets your needs and if there's anything that this PR covers that that PR does not.

@justinmc justinmc closed this May 29, 2020
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Jul 31, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants