whatwg / html

HTML Standard
https://html.spec.whatwg.org/multipage/
Other
8.16k stars 2.68k forks source link

Provide native validation messages for native validity states on Form Associated Custom Elements #10360

Open KonnorRogers opened 5 months ago

KonnorRogers commented 5 months ago

What problem are you trying to solve?

When using Form Associated Custom Elements, you may want to re-use the browser native messages so you don't need to support translations.

What solutions exist today?

Solutions that exist today involve programmatically creating an invalid form control and grabbing its validationMessage property.

However, there is 1 edge case around maxlength and minlength where you cannot make them invalid without user interaction, so this pattern breaks down for these 2 properties / attributes.

The other solution is to do "mirroring" of a form control in your shadow dom, and mirror host attributes onto the shadow dom form control and then grab its validationMessage, however, your FACE may not cleanly map to a formControl.

for example, a multi-select editable combobox, a contenteditable field in your shadow dom etc.

So in FACE components that need a maxlength or minlength and do not cleanly map to a native form control in their shadow DOM, they have no way to grab the native validation messages.

How would you solve it?

Well, this is a 2 part problem.

1.) maxlength and minlength should have a way to programmatically trigger their validations to run, even if the value property was set programmatically.

For example:

<input minlength="10" value="Hi">
input.checkValidity()
// => true

// input is always valid because of how minlength / maxlength work with defaultValue and with programmatically set values.

input.forceCheckValidity() or similar. I don't know the right answer. This is less of a concern to me.

2.) Some way to grab native validation strings.

We could overwrite setValidity() so if you pass null as a second argument, it can perform the native validation message lookup. For example:

<my-custom-element value="Hi" minlength="10"></my-custom-element>
myCustomElement.internals.setValidity({ tooShort: true }, null)

myCustomElement.internals.validationMessage 
// => "Please lengthen this text to 10 characters. (You are currently using 2 characters.)

TLDR: I would love a way to provide native translation strings for native error states like tooShort, tooLong, stepMismatch, etc.

Anything else?

My final goal is to be able to have native validation strings on Form Associated Custom Elements. I'm open to other suggestions and not tied to any particular suggestion here. Thank you for your time and help!

annevk commented 1 week ago

I don't really understand this. Is the problem that you are displaying the validation messages yourself and not rely on the browser UI for them?

KonnorRogers commented 1 week ago

I don't really understand this. Is the problem that you are displaying the validation messages yourself and not rely on the browser UI for them?

Not necessarily. Imagine I have a contenteditable wrapped by a form associated custom element and wanted to display validation messages for it. I would need to ship my own custom translations.

you can kind of hack around it with required by making a required input element and grabbing its validationMessage and attaching that to the internals.setValidity call, but you can't do the same for minlength and maxlength because those require actual interaction.

annevk commented 1 week ago

Oh I see, the problem is the dirty value flag guard. That seems very similar to what we probably need for #9639. Would be nice if both could be tackled by the same API.

cc @Emilio @smaug---- @nt1m @josepharhar