Skip to content
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

HTML5 required validity does not work with OSelect component with a placeholder #921

Open
urkle opened this issue May 2, 2024 · 3 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@urkle
Copy link
Contributor

urkle commented May 2, 2024

Overview of the problem

Oruga version: [0.7.0]
Vuejs version: [3.3.13]
OS/Browser: Firefox 125.0.3 on macOS

Description

When using an OSelect component with a placeholder, the component shows as "valid" when no option has been chosen.

Steps to reproduce

const value = ref(null);
const mySelectRef = ref(null);

<OSelect ref="mySelectRef" v-model="value" placeholder="Select me!">
  <option value="pickme">Pick me</option>
</OSelect>

Expected behavior

mysSelectRef.checkHtml5Validity() === false

Actual behavior

mysSelectRef.checkHtml5Validity() === true

Additional details

Upon inspecting things further the "value" of the select element is the placeholder text "Select me!" instead of being blank. This is due to the option having the :value="null" thus no value attribute is actually set on the option so the browser falls back to the inner text of the option.

This also occurs in the current 0.8.9 and also occurs in Google Chrome. Thus it is not isolated to a specific oruga version nor browser.

Possible solutions

  1. use empty string "" as the not-selected value. This will fix the issue in part as the browser will correctly understand the chosen value. But it messes with the modelValue if the user really wants null to be unselected.
  2. customize checkHtml5Validity() for this component handle this situation explicitly.
@blm768
Copy link
Contributor

blm768 commented May 16, 2024

I wouldn't just customize checkHtml5Validity; we'd also want the underlying <select> to register as an invalid element on the browser's side of things so it blocks form submission. As far as I'm aware, the empty-string-valued option and setCustomValidity are the only viable options there. and the latter has its own issues; for instance, it requires the caller to select a validation error message, which may not match the browser's default.

@mlmoravek mlmoravek added enhancement New feature or request help wanted Extra attention is needed labels May 28, 2024
@mlmoravek
Copy link
Member

I don't know of a good quick fix for this yet. If anyone has an idea, I would be glad to hear it!

@blm768
Copy link
Contributor

blm768 commented May 28, 2024

I'd say the most semantically valid option would be to require the model value of <OSelect> to be a non-nullable string. It would then be the user's responsibility to define a bijective mapping between the string values and the actual domain values from which they want to select. This would be a breaking change, though; I'm sure the use of a null model value (and even the use of objects as the model value!) happens in the wild even though it deviates from the DOM standard (which specifies that <select>/<option> values are strings).

We might be able to add some mapping code such that modelValue is transformed from null to an empty string when interacting with the DOM, but we'd still have to determine how to react when firing update:modelValue events. It would likely be unintuitive for users if passing :modelValue = "null" selects the placeholder, but selecting the placeholder from the user interface emits "" as the model value. Most of the solutions I can think of to that issue are either unreliable or clunky. For instance, if we try to detect that the parent component has ever passed a null modelValue, that doesn't help detect cases where the modelValue is expected to be nullable but started out non-null. If we require an additional prop to signal nullability, we basically might as well just have the parent component handle the logic to map empty strings to/from null.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants