Repository navigation
Replies: 2 comments 3 replies
|
import { flushSync } from 'svelte';
const choose = (x) => {
if (x === value) {
open = false;
return;
}
flushSync(() => {
open = false;
value = x;
});
select.dispatchEvent(new Event('input', { bubbles: true }));
select.dispatchEvent(new Event('change', { bubbles: true }));
};Changing I checked a small compiled Svelte 5.57.3 component in jsdom with a real select binding and a parent form handler reading
const form = event.currentTarget;
await tick();
const data = new FormData(form);So you can keep the parent handler synchronous with either approach. The choice is whether |
|
Hi @Tjaitil! Welcome to Svelte! This is a classic challenge when building custom headless form controls. The reason you are seeing stale Here is why your options behave the way they do, followed by the idiomatic solution: Why the Initial Approaches Have Caveats:
Idiomatic Solution 1: Svelte 5's
|
Uh oh!
There was an error while loading. Please reload this page.
Hello,
I'm learning svelte and enjoying the journey so far. I'm working with a custom select component where I'm hidding the native select and building my own UI select. This means I'm changing the state programmatically, and then dispatch the
input/changeevent myself to make it act more like a native form element.However I realised that adding a
onchangeon the form (or any other parent element) would read the previous value when constructingFormDatasince svelte hasn't updated the DOM (i.eSelectelement) yet.Reason for using an onchange could be for instance a filter form.
I've come up with at least 2 options but wondering what is the best approach and most "svelte" idiomatic I guess.
const choose = (x) => { open = false; if (x === value) return; value = x; // Without anything the change would produce a stale value when <form> onchange runs // Option 1 - await tick() - would require async // - Drawback Would make the event.currentTarget = null for callbacks // Option 2 - select.value = value; // - Drawback Duplicate assignment of value // Option 3 - ? // Dispatch the custom events to let the form read it select.dispatchEvent(new Event('input', { bubbles: true })); select.dispatchEvent(new Event('change', { bubbles: true })); }Link to playground
The playground uses a select but this scenario relates to other components where the change happens programmatically.
Again I'm a beginner so any do's and don't would be highly appreciated.
Please don't hesitate to ask question if anything needs clarifying.
Thanks in advance!
All reactions