Add a disabled state that locks the field and omits it from the form - #16
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add a disabled state
Why
There is currently no way to render an
advanced_selectthat shows its value but refuses to change it. Host apps work around this by wrapping the field inpointer-events-none opacity-50, which only looks disabled: the field is still focusable, still clearable, and — most importantly — still submitted. An update form that renders a read-only field this way happily writes back a value the user was never allowed to touch.A native
<select disabled>has exactly the semantics we want, and the browser already enforces them. This PR givesadvanced_selectthe same contract.What it does
disabled: truelocks the field. The current selection stays on screen — the point is to show the value, not hide it — but the field cannot be opened, searched, or cleared, and its value is left out of the form.disabledattributedisabledBlocking happens at the element level rather than through CSS, so mouse and keyboard are both handled by the browser. That matters for host apps that supply their own
ClassMap: the gem's.ui-advanced-select-disabledrules never reach them, so anything enforced only in CSS would silently do nothing.Usage
The root element takes the
disabledclass from the class map, so host apps can style the locked state alongside everything else:Toggling at runtime
The state is a Stimulus value, so it can be flipped after render — from another controller, or from a Turbo Stream that rewrites the attribute:
The controller reacts on its own: it disables the hidden inputs, applies the class, hides the clear control, and closes the dropdown if it happens to be open. The same thing is available as a method:
Changes
advanced_select_tag(..., disabled: false)— new keyword, passed through to the partialClassMap::DEFAULTS[:disabled]— newui-advanced-select-disabledentry_select.html.erb—disabledattribute on the trigger and on every hidden input,disabledclass on the root, clear control rendered hiddendisabledvalue,disable()/enable(), adisabledValueChangedcallback, and guards inopen()andclear()Disabled Statesection, TOC entry, and the new keyword in the API referenceAlso in here
record_advanced_select_eventsin the system tests now filters by the field under test. It listened ondocument, so it also picked up the event that the page's eager dependent select broadcasts when it auto-selects on load — which madebroadcasts advanced-select:change with the selected valueintermittently see two events instead of one. Scoping the recorder to a single field name makes the count deterministic no matter what else the example page does.Testing
Six new system tests cover the rendered state, form omission, the hidden clear control, and enabling/disabling at runtime. Full suite: 33 runs, 144 assertions, 0 failures, verified green across several random seeds.
Release
Version bumped to
0.1.10.