Skip to content

Make DropdownMenu TextField reactive to label changes #162062

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

Conversation

ahmedrasar
Copy link
Contributor

@ahmedrasar ahmedrasar commented Jan 23, 2025

Description

The current behavior of Flutter regarding DropdownMenu text field is very basic: DropdownMenu updates the text field once a selection has been made with its coordinating label, and nothing more.

If the selection's label changes, the text field will still show the old value, although the menu buttons have been updated.

This not only results in the need to write a lot of boilerplate code to match the label to the current selection, but it's also counterintuitive. The DropdownMenu should handle rematching by itself.

Issue #155660, touched on this, and a solution was introduced in #155757. It was later reverted due to it restricting some use cases. That issue & solution, however, only address initialSelection. If another selection was made and its corresponding label was changed, the text field would still show the old value, bringing us back to square one.

This PR should not conflict with any previous behavior of DropdownMenu: any new value provided by initialSelection or via controller would not be overwritten by rematching. However, entries with the same value will be mapped to a single label (the first matched entry's label).

Related Issues

Tests

Added 3 tests.

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • I followed the [breaking change policy] and added [Data Driven Fixes] where supported.
  • All existing and new tests are passing.

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. labels Jan 23, 2025
@ahmedrasar ahmedrasar force-pushed the feature_dropdown_menu_automatic_rematching branch 6 times, most recently from 492f6e4 to 2ad98b7 Compare January 26, 2025 00:00
@Piinks Piinks requested a review from QuncCccccc January 29, 2025 19:12
@ahmedrasar ahmedrasar force-pushed the feature_dropdown_menu_automatic_rematching branch from 2ad98b7 to c589b11 Compare February 3, 2025 17:39
@QuncCccccc
Copy link
Contributor

Sorry for the late response! I will take a look at this change asap!

@ahmedrasar
Copy link
Contributor Author

@QuncCccccc Is this PR still on the radar?

@QuncCccccc
Copy link
Contributor

Yes! Will take a look this week! Really appreciate your patience!

Copy link
Contributor

@QuncCccccc QuncCccccc left a comment

Choose a reason for hiding this comment

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

Really appreciated your patience and thanks so much for helping add the fix. I just added my thoughts and comments below:)

expect(controller.text, 'Updated label 1');
});

testWidgets('Do not rematch selection if its value maps to multiple entries', (
Copy link
Contributor

Choose a reason for hiding this comment

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

This may happen rarely because I think usually the entry values are unique? We can match the first matching value or do not rematch. I'm okay with either way:)

Copy link
Contributor Author

@ahmedrasar ahmedrasar Mar 12, 2025

Choose a reason for hiding this comment

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

We could match against the first entry only, and it would be the same behavior as initialSelection.

The only downfall would be not being able to show different labels for the same value. It doesn't seem like a big deal because it's not how we normally use 'DropdownMenu` but it may break what some people expect, and some golden tests too.

Edit:

I would opt for rematching the first occurrence of a valid label but keeping the flag and specifying such behavior in its description.

@ahmedrasar ahmedrasar force-pushed the feature_dropdown_menu_automatic_rematching branch from c589b11 to 54a0dc2 Compare March 16, 2025 21:57
@ahmedrasar ahmedrasar changed the title Introduce DropdownMenu automatic matching Make DropdownMenu TextField reactive to label changes Mar 16, 2025
@ahmedrasar ahmedrasar force-pushed the feature_dropdown_menu_automatic_rematching branch from 54a0dc2 to e583b75 Compare March 16, 2025 22:09
@ahmedrasar
Copy link
Contributor Author

ahmedrasar commented Mar 16, 2025

Hello @QuncCccccc, I made changes based on your notes, check 'em out.

@ahmedrasar ahmedrasar force-pushed the feature_dropdown_menu_automatic_rematching branch from e583b75 to 854c11a Compare March 18, 2025 13:08
@dkwingsmt dkwingsmt requested a review from QuncCccccc March 19, 2025 18:30
@ahmedrasar
Copy link
Contributor Author

I filed an issue with explanations, code samples, and videos. #161729 (comment).

As I said in that comment, I'm aware that the same behavior can be done with the help of a controller. However, whenever I come across this, I find it more fitting for the framework to handle it.

And besides that, this PR fixes #155660, which trying to work around it using a controller feels doubly wrong.

@ahmedrasar ahmedrasar force-pushed the feature_dropdown_menu_automatic_rematching branch from 854c11a to 0e479c5 Compare March 28, 2025 07:19
@@ -554,6 +555,7 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
} else {
_localTextEditingController = TextEditingController();
}
_localTextEditingController!.addListener(() => _textFieldSelection = null);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This omits the need for _lastLocalTextingEditingValueObject—such a long name.

@ahmedrasar ahmedrasar force-pushed the feature_dropdown_menu_automatic_rematching branch from 0e479c5 to fa14c28 Compare March 28, 2025 07:35
@ahmedrasar ahmedrasar requested a review from QuncCccccc March 29, 2025 07:24
@ahmedrasar ahmedrasar force-pushed the feature_dropdown_menu_automatic_rematching branch 2 times, most recently from be82163 to 59175ea Compare May 10, 2025 03:30
@ahmedrasar ahmedrasar force-pushed the feature_dropdown_menu_automatic_rematching branch 4 times, most recently from dbdd942 to cc1cc71 Compare May 20, 2025 15:06
@ahmedrasar ahmedrasar requested a review from chunhtai May 20, 2025 16:24
@ahmedrasar ahmedrasar force-pushed the feature_dropdown_menu_automatic_rematching branch from cc1cc71 to 65c8017 Compare May 22, 2025 06:30
Copy link
Contributor

@chunhtai chunhtai left a comment

Choose a reason for hiding this comment

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

LGTM, just one minor comment

@ahmedrasar ahmedrasar force-pushed the feature_dropdown_menu_automatic_rematching branch from 65c8017 to 3985101 Compare June 2, 2025 18:33
@QuncCccccc QuncCccccc requested a review from chunhtai June 4, 2025 20:26
@ahmedrasar ahmedrasar force-pushed the feature_dropdown_menu_automatic_rematching branch 2 times, most recently from 383813f to fe3708b Compare June 8, 2025 17:09
Copy link
Contributor

@chunhtai chunhtai left a comment

Choose a reason for hiding this comment

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

LGTM

@chunhtai
Copy link
Contributor

looks like you need to rebase to fix the ci.yaml

@dkwingsmt dkwingsmt force-pushed the feature_dropdown_menu_automatic_rematching branch from fe3708b to 6a8b76c Compare June 11, 2025 18:30
@chunhtai chunhtai added the autosubmit Merge PR when tree becomes green via auto submit App label Jun 11, 2025
@auto-submit auto-submit bot added this pull request to the merge queue Jun 11, 2025
Merged via the queue into flutter:master with commit 4e0c010 Jun 11, 2025
76 checks passed
@flutter-dashboard flutter-dashboard bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jun 11, 2025
@ahmedrasar ahmedrasar deleted the feature_dropdown_menu_automatic_rematching branch June 12, 2025 08:57
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 12, 2025
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Jun 12, 2025
Roll Flutter from 824868f5d1e6 to f79452e3f4ea (94 revisions)

flutter/flutter@824868f...f79452e

2025-06-12 [email protected] Roll Skia from 38b9f9b0e496 to b41e7017658e (12 revisions) (flutter/flutter#170514)
2025-06-12 [email protected] Fix `Semantics.identifier` on TextField not working on web (flutter/flutter#170395)
2025-06-12 [email protected] Revert "[a11y] Semantics flag refactor step 2: embedder part" (flutter/flutter#170498)
2025-06-12 [email protected] Copy `packages_autoroller` to `dev/packages_autoroller/run`. (flutter/flutter#170495)
2025-06-11 [email protected] Allow the Slider to always show the value indicator. (flutter/flutter#162223)
2025-06-11 [email protected] Update master branch `CHANGELOG.md` for 3.32.3. (flutter/flutter#170492)
2025-06-11 [email protected] Add time to first frame for `Mac_arm64_ios imitation_game_swiftui` (flutter/flutter#167602)
2025-06-11 [email protected] Make `DropdownMenu` TextField reactive to label changes (flutter/flutter#162062)
2025-06-11 [email protected] Roll Dart SDK from b569246d64bc to 9f741ef8a689 (1 revision) (flutter/flutter#170473)
2025-06-11 [email protected] [impellerc] add GLES shader define. (flutter/flutter#170375)
2025-06-11 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Pause UIScene migration (#170457)" (flutter/flutter#170487)
2025-06-11 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Fix DropdownButtonFormField focusing when replacing FocusNode (#166645)" (flutter/flutter#170477)
2025-06-11 [email protected] Pause UIScene migration (flutter/flutter#170457)
2025-06-11 [email protected] iOS tool dylibs do not need entitlements (flutter/flutter#170448)
2025-06-11 [email protected] Adds getters for different formats of build mode name (flutter/flutter#170251)
2025-06-11 [email protected] Remove all code in `conductor/core` that is now unused (flutter/flutter#170454)
2025-06-11 [email protected] Roll Packages from 974f152 to 0b322a2 (9 revisions) (flutter/flutter#170462)
2025-06-11 [email protected] Roll Skia from b78fdc3ba26b to 38b9f9b0e496 (7 revisions) (flutter/flutter#170453)
2025-06-11 [email protected] Fix remaining iconbuttontheme overrides in listtile (flutter/flutter#169029)
2025-06-11 [email protected] Fix DropdownButtonFormField focusing when replacing FocusNode (flutter/flutter#166645)
2025-06-11 [email protected] Add CupertinoRadio widget of the week video (flutter/flutter#170027)
2025-06-11 [email protected] Docs: Update docs for suffix icon interaction behaviour (flutter/flutter#169828)
2025-06-11 [email protected] [ Widget Preview ] Don't try to load previews with compile-time errors (flutter/flutter#170262)
2025-06-11 [email protected] [canvaskit] Manually trigger `input` event in text editing tests for Safari (flutter/flutter#170022)
2025-06-11 [email protected] Tiny clean-up in triage docs (flutter/flutter#170429)
2025-06-11 [email protected] Roll pub packages (flutter/flutter#170444)
2025-06-11 [email protected] [Impeller] Avoid creating paths when rendering arcs (flutter/flutter#170398)
2025-06-11 [email protected] Fix date picker calendar tap targets (portrait mode) (flutter/flutter#169163)
2025-06-11 [email protected] Add SK_SUPPORT_UNSPANNED_APIS staging flag (flutter/flutter#170139)
2025-06-11 [email protected] Roll Dart SDK from 6290dfd1d88a to b569246d64bc (4 revisions) (flutter/flutter#170430)
2025-06-11 [email protected] Roll Skia from 910070084066 to b78fdc3ba26b (33 revisions) (flutter/flutter#170412)
2025-06-11 [email protected] Use pathops module groups (flutter/flutter#169857)
2025-06-10 [email protected] Roll pub packages (flutter/flutter#170399)
2025-06-10 [email protected] Verify old version of Python has the `lib2to3` import available (flutter/flutter#170187)
2025-06-10 [email protected] Use "flutter pub get" to resolve packages when building the docs snippets tool (flutter/flutter#170381)
2025-06-10 [email protected] [engine] Reland: ensure engines spawned from an engine using dynamic rendering selection still use the dynamic surface. (flutter/flutter#170389)
2025-06-10 [email protected] Revert "Add call to Dart_NotifyDestroyed when the flutter view is des… (flutter/flutter#170309)
2025-06-10 [email protected] fix: set versionCodeOverride when split-per-abi is specified (flutter/flutter#169816)
2025-06-10 [email protected] fix: Skip native assets build test (flaky, takes 15m+) (flutter/flutter#170383)
2025-06-10 [email protected] Marks Linux web_benchmarks_ddc to be unflaky (flutter/flutter#167631)
2025-06-10 [email protected] Marks Linux web_benchmarks_ddc_hot_reload to be unflaky (flutter/flutter#168807)
2025-06-10 98614782+auto-submit[bot]@users.noreply.github.com Reverts "[engine] ensure engines spawned from an engine using dynamic rendering selection still use the dynamic surface. (#170313)" (flutter/flutter#170377)
2025-06-10 [email protected] [a11y] Semantics flag refactor step 2: embedder part (flutter/flutter#167738)
2025-06-10 [email protected] Roll Dart SDK from c26e7ca44805 to 6290dfd1d88a (5 revisions) (flutter/flutter#170363)
2025-06-10 [email protected] Remove `pubspec.lock` files for `flutter_tools` and `widget_preview_scaffold`. (flutter/flutter#170364)
2025-06-10 [email protected] [engine] ensure engines spawned from an engine using dynamic rendering selection still use the dynamic surface. (flutter/flutter#170313)
...
feduke-nukem pushed a commit to Yobari-Timeliners/golub that referenced this pull request Jun 13, 2025
Roll Flutter from 824868f5d1e6 to f79452e3f4ea (94 revisions)

flutter/flutter@824868f...f79452e

2025-06-12 [email protected] Roll Skia from 38b9f9b0e496 to b41e7017658e (12 revisions) (flutter/flutter#170514)
2025-06-12 [email protected] Fix `Semantics.identifier` on TextField not working on web (flutter/flutter#170395)
2025-06-12 [email protected] Revert "[a11y] Semantics flag refactor step 2: embedder part" (flutter/flutter#170498)
2025-06-12 [email protected] Copy `packages_autoroller` to `dev/packages_autoroller/run`. (flutter/flutter#170495)
2025-06-11 [email protected] Allow the Slider to always show the value indicator. (flutter/flutter#162223)
2025-06-11 [email protected] Update master branch `CHANGELOG.md` for 3.32.3. (flutter/flutter#170492)
2025-06-11 [email protected] Add time to first frame for `Mac_arm64_ios imitation_game_swiftui` (flutter/flutter#167602)
2025-06-11 [email protected] Make `DropdownMenu` TextField reactive to label changes (flutter/flutter#162062)
2025-06-11 [email protected] Roll Dart SDK from b569246d64bc to 9f741ef8a689 (1 revision) (flutter/flutter#170473)
2025-06-11 [email protected] [impellerc] add GLES shader define. (flutter/flutter#170375)
2025-06-11 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Pause UIScene migration (#170457)" (flutter/flutter#170487)
2025-06-11 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Fix DropdownButtonFormField focusing when replacing FocusNode (#166645)" (flutter/flutter#170477)
2025-06-11 [email protected] Pause UIScene migration (flutter/flutter#170457)
2025-06-11 [email protected] iOS tool dylibs do not need entitlements (flutter/flutter#170448)
2025-06-11 [email protected] Adds getters for different formats of build mode name (flutter/flutter#170251)
2025-06-11 [email protected] Remove all code in `conductor/core` that is now unused (flutter/flutter#170454)
2025-06-11 [email protected] Roll Packages from 974f1522ee03 to 17c02a5 (9 revisions) (flutter/flutter#170462)
2025-06-11 [email protected] Roll Skia from b78fdc3ba26b to 38b9f9b0e496 (7 revisions) (flutter/flutter#170453)
2025-06-11 [email protected] Fix remaining iconbuttontheme overrides in listtile (flutter/flutter#169029)
2025-06-11 [email protected] Fix DropdownButtonFormField focusing when replacing FocusNode (flutter/flutter#166645)
2025-06-11 [email protected] Add CupertinoRadio widget of the week video (flutter/flutter#170027)
2025-06-11 [email protected] Docs: Update docs for suffix icon interaction behaviour (flutter/flutter#169828)
2025-06-11 [email protected] [ Widget Preview ] Don't try to load previews with compile-time errors (flutter/flutter#170262)
2025-06-11 [email protected] [canvaskit] Manually trigger `input` event in text editing tests for Safari (flutter/flutter#170022)
2025-06-11 [email protected] Tiny clean-up in triage docs (flutter/flutter#170429)
2025-06-11 [email protected] Roll pub packages (flutter/flutter#170444)
2025-06-11 [email protected] [Impeller] Avoid creating paths when rendering arcs (flutter/flutter#170398)
2025-06-11 [email protected] Fix date picker calendar tap targets (portrait mode) (flutter/flutter#169163)
2025-06-11 [email protected] Add SK_SUPPORT_UNSPANNED_APIS staging flag (flutter/flutter#170139)
2025-06-11 [email protected] Roll Dart SDK from 6290dfd1d88a to b569246d64bc (4 revisions) (flutter/flutter#170430)
2025-06-11 [email protected] Roll Skia from 910070084066 to b78fdc3ba26b (33 revisions) (flutter/flutter#170412)
2025-06-11 [email protected] Use pathops module groups (flutter/flutter#169857)
2025-06-10 [email protected] Roll pub packages (flutter/flutter#170399)
2025-06-10 [email protected] Verify old version of Python has the `lib2to3` import available (flutter/flutter#170187)
2025-06-10 [email protected] Use "flutter pub get" to resolve packages when building the docs snippets tool (flutter/flutter#170381)
2025-06-10 [email protected] [engine] Reland: ensure engines spawned from an engine using dynamic rendering selection still use the dynamic surface. (flutter/flutter#170389)
2025-06-10 [email protected] Revert "Add call to Dart_NotifyDestroyed when the flutter view is des… (flutter/flutter#170309)
2025-06-10 [email protected] fix: set versionCodeOverride when split-per-abi is specified (flutter/flutter#169816)
2025-06-10 [email protected] fix: Skip native assets build test (flaky, takes 15m+) (flutter/flutter#170383)
2025-06-10 [email protected] Marks Linux web_benchmarks_ddc to be unflaky (flutter/flutter#167631)
2025-06-10 [email protected] Marks Linux web_benchmarks_ddc_hot_reload to be unflaky (flutter/flutter#168807)
2025-06-10 98614782+auto-submit[bot]@users.noreply.github.com Reverts "[engine] ensure engines spawned from an engine using dynamic rendering selection still use the dynamic surface. (#170313)" (flutter/flutter#170377)
2025-06-10 [email protected] [a11y] Semantics flag refactor step 2: embedder part (flutter/flutter#167738)
2025-06-10 [email protected] Roll Dart SDK from c26e7ca44805 to 6290dfd1d88a (5 revisions) (flutter/flutter#170363)
2025-06-10 [email protected] Remove `pubspec.lock` files for `flutter_tools` and `widget_preview_scaffold`. (flutter/flutter#170364)
2025-06-10 [email protected] [engine] ensure engines spawned from an engine using dynamic rendering selection still use the dynamic surface. (flutter/flutter#170313)
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

DropdownMenu.didUpdateWidget should re-match initialSelection when dropdownMenuEntries have changed
5 participants