Select Elements Don't Update When Value Changes #14751
Copy link
Copy link
Closed
Labels
formsStuff relating to forms and form actionsStuff relating to forms and form actions
Description
Describe the bug
I have a query which loads some data that is then used as defaults for a form.
import { form, query } from '$app/server';
import { type } from 'arktype';
export const getFormDefaults = query(() => ({
colour: 'green',
opacity: 0.5
}));
const TestFormSchema = type({
colour: '"red" | "green" | "blue"',
opacity: 'number'
});
export const testForm = form(TestFormSchema, async (data) => {
console.log('Your favourite colour is:', data.colour);
console.log('Your chosen opacity is:', data.opacity);
});When I have a select element, whenever I attempt to change the selected value, it updates the value for the form fields, but the select element itself does not update the displayed value.
<script lang="ts">
import { getFormDefaults, testForm } from '$lib/test.remote';
const formDefaults = $derived(await getFormDefaults());
</script>
<h1>Test</h1>
<main>
<form {...testForm}>
<label for="favourite-colour-selector">Favourite Colour</label>
<select
id="favourite-colour-selector"
{...testForm.fields.colour.as('select')}
value={formDefaults.colour}
>
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</select>
<label for="opacity-input">Opacity</label>
<input
id="opacity-input"
{...testForm.fields.opacity.as('number')}
defaultValue={formDefaults.opacity}
value={formDefaults.opacity}
/>
<p>Your favourite colour is {testForm.fields.colour.value() ?? 'N/A'}</p>
<p>Your chosen opacity is {testForm.fields.opacity.value() ?? 'N/A'}</p>
<button type="submit">Submit</button>
</form>
</main>Reproduction
- Clone https://github.com/abdelfattahradwan/sveltekit-select-bug
- Run the
devscript. (e.g.npm run dev) - Open
localhost:5173 - Try changing the value of the "Favourite Colour".
Logs
N/ASystem Info
System:
OS: Windows 11 10.0.26200
CPU: (28) x64 Intel(R) Core(TM) i7-14700K
Memory: 35.58 GB / 63.70 GB
Binaries:
Node: 22.20.0 - C:\Program Files\nodejs\node.EXE
npm: 11.6.1 - C:\Users\Abdo\AppData\Roaming\npm\npm.CMD
bun: 1.3.0 - C:\Users\Abdo\.bun\bin\bun.EXE
Deno: 2.5.4 - C:\Program Files\deno\deno.EXE
Browsers:
Chrome: 141.0.7390.108
Edge: Chromium (140.0.3485.81)
Firefox: 144.0 - C:\Program Files\Mozilla Firefox\firefox.exe
Internet Explorer: 11.0.26100.1882
npmPackages:
@sveltejs/adapter-auto: ^7.0.0 => 7.0.0
@sveltejs/kit: ^2.47.1 => 2.47.1
@sveltejs/vite-plugin-svelte: ^6.2.1 => 6.2.1
svelte: ^5.40.2 => 5.40.2
vite: ^7.1.10 => 7.1.10Severity
annoyance
Additional Information
No response
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
formsStuff relating to forms and form actionsStuff relating to forms and form actions
Activity
sillvva commentedon Oct 17, 2025
You should set default values in the script block with
form.fields.set({ ... }). Assigning values like that overrides the remote form field behavior.Docs: https://svelte.dev/docs/kit/remote-functions#form-Getting-setting-inputs
Example: https://stackblitz.com/edit/svetekit-template-nxhl9tqut?file=src%2Froutes%2F%2Bpage.svelte,src%2Froutes%2Ftest.remote.ts
abdelfattahradwan commentedon Oct 17, 2025
The example I included above (and in the reproduction repository) specifically has a remote query because it is intended to mimic an "edit existing entity" form.
If I do this:
I get a warning saying
This reference only captures the initial value of `formDefaults`. Did you mean to reference it inside a closure instead? https://svelte.dev/e/state_referenced_locallysvelte(state_referenced_locally)sillvva commentedon Oct 17, 2025
Unless you're intending to refresh the default values, you don't need the
$derived().abdelfattahradwan commentedon Oct 17, 2025
I do intend to refresh them. After editing the form values and submitting, the new values are supposed to override the defaults.
For example, I am on an "Edit Post" page, and I use a remote query to get the current post details. When I change, say, the post title and submit, the form refreshes the remote query value, and the new title should show up instead of the current one.
sillvva commentedon Oct 17, 2025
Here's an example setting initial values and then updating them when the query refreshes:
https://stackblitz.com/edit/svetekit-template-nxhl9tqut?file=src%2Froutes%2F%2Bpage.svelte,src%2Froutes%2Ftest.remote.ts
abdelfattahradwan commentedon Oct 17, 2025
Thanks for the example 🙏🏻 I used an
$effectinitially as well, but since$effectsaren't run during SSR, I don't think they will work with JS disabled. I have to support no-JS users in this particular case.abdelfattahradwan commentedon Oct 17, 2025
Also, I wonder why the
numberinput works just fine, while theselectdoesn't? It seems odd to me.sillvva commentedon Oct 17, 2025
Honestly, I'm not sure what the difference is caused by.
If your users don't have JS, then
$derived()shouldn't matter in that case either. I only support JS-enabled environments in my app, so I've not tested this use case. But I believe in a no JS environment, the form would act like a normal HTML form and reload the page when submitted. Then the initial.set()should rerun at that time.sillvva commentedon Oct 17, 2025
As a workaround, try this:
abdelfattahradwan commentedon Oct 17, 2025
When a no-JS users visit the app, they get an SSR'd page with everything rendered correctly. When they submit the form, since there is no JS, the page is basically reloaded, and the form gets re-rendered correctly with the updated values.
The issue actually impacts JS users. Without the
$derived, when I submit the form, nothing refreshes, and the old values remain. Also, being unable to see the changes made to the select is, well, bad for the UX to say the least 😅abdelfattahradwan commentedon Oct 17, 2025
Oh, I completely forgot about bind getters/setters! That works!
sillvva commentedon Oct 17, 2025
My second Stackblitz example should actually work for both cases as the
$effectwould only apply to JS users. Non-JS users would still have the page reload. Both users should see the updated values.abdelfattahradwan commentedon Oct 17, 2025
Now that I think about it, it would work, yeah.
I will stick with the custom getter/setter, though. I try to avoid
$effectas much as possible for simple things like this.Thank you so much for the help 🙏🏼
sillvva commentedon Oct 18, 2025
Just as an aside, here's a version that doesn't use
$effect(). I feel like this is a lot simpler.https://stackblitz.com/edit/svetekit-template-nxhl9tqut-dnw5pnez?file=src%2Froutes%2F%2Bpage.svelte
abdelfattahradwan commentedon Jun 18, 2026
I haven't been able to reproduce this particular issue for quite some time now.
selectelements' values seem to update correctly when I make a selection now. I assume that means the issue has been fixed.