Open angrytongan opened 1 year ago
As a workaround you can use an action that calls setAttribute
:
const value = (node, param) => node.setAttribute('value', param);
<input use:value={'Default value'} />
Maybe Svelte should set the defaultValue
property in these cases? The action provided by @brunnerh also works with node.defaultValue = param
What I don't understand is why that is needed when the generated code literally uses innerHTML
with the blob of HTML.
What I don't understand is why that is needed when the generated code literally uses innerHTML with the blob of HTML.
Probably an inconsistency in dev mode which doesn't do the innerHTML optimization
could placeholder be an alternative? If you don't strictly need an initial value for those inputs it might even be the right thing to use
Hello,
From what I see, apart from innerHTML optimization (which is not used when using a variable on the template), some specific attributes like value
, checked
are not added to the node's attributes, but directly in the corresponding JavaScript property.
So something like this :
<input type="text" name="{name}" value={value} />
Will generate a code like that :
input = element("input");
attr(input, "type", "text");
attr(input, "name", /*name*/ ctx[0]);
input.value = /*value*/ ctx[1];
I think that Svelte should explicitly add defaultValue in this case :
input = element("input");
attr(input, "type", "text");
attr(input, "name", /*name*/ ctx[0]);
input.value = input.defaultValue = /*value*/ ctx[1];
This apply also to defaultChecked
on checkbox/radio
, and defaultSelected
on option
(and maybe others?)
Another solution would be to use the attributes in all cases :
input = element("input");
attr(input, "type", "text");
attr(input, "name", /*name*/ ctx[0]);
attr(input, "value", /*value*/ ctx[1]);
But I don't know why Svelte treats these attributes differently, so I dont' know what the best solution.
Just wanted to point out that the workaround mentioned in https://github.com/sveltejs/svelte/issues/8220#issuecomment-1400483958 won't work for users who don't have access to JavaScript.
I agree with adiguba
that just using the raw attributes would be an excellent solution. (I think it would be the best solution.) As things stand, Svelte doesn't have a way for developers to apply a defaultValue
to their inputs (in the HTML). One reason that this is significant (besides the reset
bug) is that it makes things more difficult for developers who want to track the dirty/clean state of their form fields. Such a check can be done very easily with regular JS by checking input.value !== input.defaultValue
(or the equivalent for checkboxes, select
elements, and the like) while the user interacts with a field. But if Svelte doesn't support default values out of the box, awkward hacks have to be added in -- like calling a function (action
) on every single form control with a default value when the page loads.
If Svelte is truly only going to be a superset of HTML (as it claims to be), then that needs to be 100% true -- especially for important elements like form controls. Even React supports this, and they've done a lot of awkward/abnormal things in their framework. :sweat_smile:
For radio buttons the severity is much more than "annoyance". For example this group of radio buttons:
<form>
<fieldset>
<legend>Please select your preferred contact method:</legend>
<div>
<input type="radio" id="contactChoice1" name="contact" value="email" checked />
<label for="contactChoice1">Email</label>
<input type="radio" id="contactChoice2" name="contact" value="phone" />
<label for="contactChoice2">Phone</label>
<input type="radio" id="contactChoice3" name="contact" value="mail" />
<label for="contactChoice3">Mail</label>
</div>
<div>
<button type="reset">reset</button>
</div>
</fieldset>
</form>
should reset to email
, and the submitted FormData should always contain the contact
key.
But in svelte it would reset to not selected, as a result the FormData won't contain key contact
.
resetting a form with hardcoded value
attributes works in Svelte 5.
We should add tests though to make sure we don't regress.
There's also a conversation to be had about what should happen when the default is dynamic, or when you're using bind:value
in which case you cannot set a default value because the spot is already taken. I explained it more deeply in #10617
Related #9230
Just wanted to point out that the workaround mentioned in #8220 (comment) won't work for users who don't have access to JavaScript.
@ITenthusiasm The workaround can work for users without JavaScript:
<script>
/** @type {import('svelte/action').Action<HTMLElement, string>} */
const setValue = (node, param) => node.setAttribute('value', param);
</script>
<form>
<!-- Important! match setValue={} and value="" -->
<input type="text" use:setValue={'1'} value="1" />
<!-- SSR <input type="text" value="2"> -->
<!-- Without JavaScript: resets to '2' -->
<!-- CSR <input type="text" value="1"> -->
<!-- With JavaScript: resets to '1' -->
<input type="text" use:setValue={'1'} value="2" />
<button type="reset">Reset</button>
</form>
Though using bind:value
, etc. will break stuff in CSR:
<script>
/** @type {import('svelte/action').Action<HTMLElement, string>} */
const setValue = (node, param) => node.setAttribute('value', param);
let val = 2;
$: console.log(val); // 2
</script>
<form>
<!-- SSR <input type="text" value="2"> -->
<!-- CSR <input type="text" value="1"> -->
<!-- With JavaScript: resets to '1', but `val` is not updated -->
<input type="text" use:setValue={'1'} bind:value={val} />
<button type="reset">Reset</button>
</form>
After a <form>
reset in Svelte 4.2.18 / REPL
<input type="text">
value is gone<input type="checkbox">
checked is gone, but the value staysThis is because checkbox values are rendered in the HTML markup:
<input type="text" />
<input type="checkbox" value="a" />
This was the reason why my codebase was working as expected after SvelteKit's default use:enhance
.
I was not using the checked
attributes, so it seemed like it followed the user-agent's behavior.
Describe the bug
Using
<input type="reset" />
on a form with hardcoded values clears the form when it shouldn't.Reproduction
Repl here: https://svelte.dev/repl/fa8b042ada144734b1814685f918f1db?version=3.55.1
Form is reset, but values shouldn't change. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/reset
Logs
No response
System Info
Severity
annoyance