-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Fix FormField implementation components TextFormField, DropdownButtonFormField, CupertinoTextFormFieldRow. The problem that their onChange() method cannot be executed when the parent Form component calls the reset() method #123108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix FormField implementation components TextFormField, DropdownButtonFormField, CupertinoTextFormFieldRow. The problem that their onChange() method cannot be executed when the parent Form component calls the reset() method #123108
Conversation
…ieldRow widget reset function Fix the implementation of FormField components: TextFormField, DropdownButtonFormField, and CupertinoTextFormFieldRow. Address the issue where their onChange() method does not get executed when the parent Form component calls reset().
|
It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat (don't just cc him here, he won't see it! He's on Discord!). If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
justinmc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! Are you able to add a test for this?
| } | ||
| _cupertinoTextFormFieldRow.onChanged?.call(_effectiveController!.text); | ||
|
|
||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Too many newlines here.
|
justinmc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding the tests! I think the docs failures have to do with macros that don't exist. I commented about that below.
| /// initialize its [TextEditingController.text] with [initialValue]. | ||
| final TextEditingController? controller; | ||
|
|
||
| /// {@macro flutter.material.TextField.onChanged} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This macro doesn't exist, did you mean flutter.material.editableText.onChanged? Or you could create this macro if you want the entire TextField.onChanged docs.
| /// initialize its [TextEditingController.text] with [initialValue]. | ||
| final TextEditingController? controller; | ||
|
|
||
| /// {@macro flutter.material.CupertinoFormRow.onChanged} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This macro also doesn't seem to exist.
| testWidgets('CupertinoTextFormFieldRow onChanged to initialValue when Form reset', (WidgetTester tester) async { | ||
| final GlobalKey<FormFieldState<String>> stateKey = GlobalKey<FormFieldState<String>>(); | ||
| final GlobalKey<FormState> formKey = GlobalKey<FormState>(); | ||
| String value='initialValue'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| String value='initialValue'; | |
| String value = 'initialValue'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And anywhere else you're not spacing this out needs to have spaces too.
Co-authored-by: Justin McCandless <[email protected]>
|
Looks like there are still docs test failures, it mentions |
I used {@macro flutter.widgets.editableText.onChanged} in the comment of the onChanged property of a TextFormFieldRow. However, {@template flutter.widgets.editableText.onChanged} references the onSubmitted property of its own widget (which is indicated in the comment as [onSubmitted]), while my widget does not have an onSubmitted property, so the docs failures |
justinmc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly nits here. Thanks for getting all of the checks to pass.
|
|
||
| /// Called when the user initiates a change to the TextField's | ||
| /// value: when they have inserted or deleted text or form reset. | ||
| final ValueChanged<String>? onChanged; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Add a newline after this.
|
|
||
| /// Called when the user initiates a change to the TextField's | ||
| /// value: when they have inserted or deleted text or form reset. | ||
| final ValueChanged<String>? onChanged; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Newline here too.
| await tester.enterText(find.byType(CupertinoTextField), 'changedValue'); | ||
| expect(stateKey.currentState!.value,'changedValue'); | ||
| expect(value, 'changedValue'); | ||
| // form to reset |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to: "Reset form."
|
|
||
| expect(value, isNull); | ||
| expect(stateKey.currentState!.value, equals('One')); | ||
| //value chang to Two |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Change value to "Two".
| await tester.pumpAndSettle(); | ||
| expect(value, equals('Two')); | ||
| expect(stateKey.currentState!.value, equals('Two')); | ||
| // form to reset |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Reset form.
| await tester.enterText(find.byType(TextField), 'changedValue'); | ||
| expect(stateKey.currentState!.value,'changedValue'); | ||
| expect(value, 'changedValue'); | ||
| // form to reset |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Reset form."
|
|
||
| expect(stateKey.currentState!.value, 'initialValue'); | ||
| expect(value, 'initialValue'); | ||
| //change value to 'changedValue' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Change value to "changedValue".
| _effectiveController!.text = widget.initialValue!; | ||
| }); | ||
| } | ||
| _cupertinoTextFormFieldRow.onChanged?.call(_effectiveController!.text); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the value didn't actually change, should onChanged still be called?
| final DropdownButtonFormField<T> dropdownButtonFormField = widget as DropdownButtonFormField<T>; | ||
| assert(dropdownButtonFormField.onChanged != null); | ||
| dropdownButtonFormField.onChanged!(widget.initialValue); | ||
| super.reset(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In CupertinoTextFormFieldRow, reset calls super on the first line. Should this one also call it on the first line?
| // manipulated, no setState call is needed here. | ||
| _effectiveController.text = widget.initialValue ?? ''; | ||
| _textFormField.onChanged?.call(_effectiveController.text); | ||
| super.reset(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this one calls super on the last line again. Not sure which is right 🤷 .
justinmc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly nits here. Thanks for getting all of the checks to pass.
|
@yeleibo Thanks for the contribution! Will you be able to continue working on this? It's totally fine if not; we can take it over (though it might take longer). I'm just asking because I'm trying to clean out our review queue. |
## Description This PR fixes form fields in order to call the `onChange` callback when the form is reset. This change is based on the work done in #123108. I considered adding the `onChange` callback to the `FormField` superclass but it would break existing code because two of the three subclasses defines the `onChange` callback with `ValueChanged<String>?` type and the third one defines it with `ValueChanged<String?>?`. ## Related Issue Fixes #123009. ## Tests Adds 3 tests.
## Description This PR fixes form fields in order to call the `onChange` callback when the form is reset. This change is based on the work done in flutter#123108. I considered adding the `onChange` callback to the `FormField` superclass but it would break existing code because two of the three subclasses defines the `onChange` callback with `ValueChanged<String>?` type and the third one defines it with `ValueChanged<String?>?`. ## Related Issue Fixes flutter#123009. ## Tests Adds 3 tests.

fixes #123009
code sample
```