sveltekit-superforms
sveltekit-superforms copied to clipboard
Validation is not triggered with `oninput` and `value` props in Svelte 5
- [x] Before posting an issue, read the FAQ and search the previous issues.
Description
While it does work when using bind:value in an input tag, validation is not triggered when manually mutating the value via an oninput handler (oninput={e => $form.field = e.currentTarget.value }).
If applicable, a MRE
I've made a minimal reproduction repo. When inputting values in text fields with oninput + value props, the validation is not triggered, but it works when using the text fields with bind:value.
https://sveltelab.dev/github.com/rayrw/svelte5-superforms-proxy-field (right click to open in a new tab)
Since the validation is triggered on blur the first time, you need an extra event handler for validating it manually. Something like:
onblur={() => validate('email')}
(validate is available on the superForm object)
Thank you for answering! I looked into this again and found that when using on:input, it works as expected for my use case, and I wondered why. It turns out that there seems to be a race condition when it is with oninput.
When it's with oninput, the input event listener registered here get called before the Form store's setter function which sets the tainted state and the paths to NextChange. This affects the comparison inside the focusout event listener.
However, when it's with on:input, the opposite happened. The Form store and NextChange get updated before the input event listener which then makes the focusout event listener correctly compare between NextChange_paths() and lastInputChange.
Sorry I'm not quite sure how to explain this. As a workaround, I would go for using oninputcapture instead of oninput for now, as it makes the order same as on:input.
<input
value={$form.email}
- oninput={(e) => {
+ oninputcapture={(e) => {
$form.email = e.currentTarget.value;
}}
/>
Thank you, will have to check what can be done about this. But oninputcapture, isn't that React?
Thank you, will have to check what can be done about this. But
oninputcapture, isn't that React?
It it a svelte 5 event handler. https://svelte.dev/tutorial/svelte/capturing