Open Beiri22 opened 1 year ago
The default behavior of use:enhance
is to reset the field to be in conformance with how full page reloads would work (they also clear the fields). In your case however, you're re-setting the content through the binding, which works on a full page reload but not when using use:enhance
because it empties it, not knowing about the two-way binding.
I'm not sure if there's a good way to solve this case, but in the meantime you can use the reset
option to not reset the form:
<form method="POST" use:enhance={() => {
return ({ update }) => update({ reset: false });
}}>
</form>
So this is the most efficient way to implement form resets that bind values?
<script lang="ts">
export let formData = { name: '' };
</script>
<form method="POST" use:enhance={() => {
return ({ update }) => {
formData.name = '';
update({ reset: false });
}
}}>
<input
type="text"
name="name"
placeholder="Your name here"
bind:value={formData.name}
/>
</form>
I am finding that this completely wipes my input values, which is puzzling. Note there is no binding.
<script lang="ts">
export let formData = { weight: 0 };
</script>
<form method="POST" use:enhance>
<input
type="number"
name="weight"
value={formData.weight}
/>
</form>
Even this leads to completely blank input fields on submit for numbers and dates. Note the value is simply passed in.
<form method="POST" use:enhance>
<input
type="number"
name="weight"
value={0}
/>
</form>
So when using enhance on a form with default values it is always necessary to bind all values and manually set them on submit?
The default behavior of
use:enhance
is to reset the field to be in conformance with how full page reloads would work (they also clear the fields). In your case however, you're re-setting the content through the binding, which works on a full page reload but not when usinguse:enhance
because it empties it, not knowing about the two-way binding.
But, when a full page reset applies the data bindings, how can just resetting be in conformance with how full page reloads would work? Seems wrong and unintuitive to me. Couldn't you just outsource the resetting part to something like use:resetOnSubmit
?
how can just resetting be in conformance with how full page reloads would work
He means how native form submits work -- submitting a POST form causes the page to reload and resets the form. In this case, however, Svelte is providing values to the form, but the enhance
action doesn't have any way of knowing that (other than you telling it not to reset the form).
@dummdidumm did you mean to mark this as ready to implement
? I'm not sure there's anything decided on right now (and I can't think of a good decision here).
but the
enhance
action doesn't have any way of knowing that
Is there really no way? Couldn't we use the compile step to add some marker to the form fields, so that enhance could read that information later?
@dummdidumm did you mean to mark this as ready to implement? I'm not sure there's anything decided on right now (and I can't think of a good decision here).
ready to implement
as in "if you find a clever little solution to this problem then go ahead and open a PR"
Sounds similar to https://github.com/sveltejs/kit/issues/8513, only this time with data
instead of form
.
(I don't mean OP's usecase, but the one without bind:
)
Another approach to repopulate the form after submission from freshly load
ed data is to reapply the data to a reactive variable:
<script lang="ts">
import { enhance } from '$app/forms'
export let form
export let data
$: settings = form?.errors ? form.settings : data.settings
</script>
Here we create a settings form. The data.settings
provides the initial data and the data when the form is submitted successfully. The form.settings
are used when the data is invalid, in which cases the form.errors
flag is true and validation info is available in the form
.
Now in the <form>
declaration we can apply it:
<form
method="POST"
use:enhance={() =>
async ({ update }) => {
await update({ reset: false })
settings = form?.errors ? form.settings : data.settings
}}
>
The key is to update the responsive settings
variable which applies the changes to the form fields. Note that we still require reset: false
as the form would be cleared otherwise, leading to a blinking of the data. Creating the value of settings
should be put in its own method for reusability.
The form inputs are always populated from the settings
object:
<input name="name" value={settings.name} />
Describe the bug
I am using a form to save some string into the db. When the form loads, the load function supplies the old string from db. After sending the form (with use:enhance) the textarea is empty.
What else: -> without use:enhance it works as intended -> the variable holds the correct content -> an input type=text showed the same behaviour
Reproduction
Logs
No response
System Info
Severity
serious, but I can work around it
Additional Information
No response