svelte-forms icon indicating copy to clipboard operation
svelte-forms copied to clipboard

[REQUEST] Enable new defaults after submit

Open m1212e opened this issue 1 year ago • 1 comments

It would be great to be able to set new default values for each field, maybe even set them automatically when that option is enabled and the form gets submitted.

In my case, I have an option to enable form editing. When done, the inputs get enabled and the user can enter the data. The default values are fetched from the server. When the user clicks submit everything is fine and the new values of the fields simply are what the user entered. When resetting, the values get reset to their default. This all works fine, as long as the user only submits the form once. In the second iteration, the default values still are the ones from the FIRST fetch. When the user now cancels editing, the field values are not reset to what the user submitted previously, but to what was fetched from the server in the first place.

m1212e avatar Nov 30 '23 19:11 m1212e

I also had the same problem, when trying to use the enhanced forms feature from svelte-kit. I couldn't get it to work through default configurations but I found a workaround that I use as a pattern, when I use svelte-forms, maybe you can incorporate this in your project:

My form definition is only slightly longer in a function like so:

<script lang="ts">
export let data;
...
function createEditProfileForm() {
		const firstName = field('firstName', data.userProfile?.first_name, [required()]);
		const lastName = field('lastName', data.userProfile?.last_name, [required()]);
		const zipCode = field('zipCode', data.userProfile?.zip_code, [required()]);
		const city = field('city', data.userProfile?.city, [required()]);
		const address = field('address', data.userProfile?.address, [required()]);
		const editProfileForm = svelteForm(zipCode, city, address, firstName, lastName);
		return { firstName, lastName, zipCode, city, address, editProfileForm };
}
function resetEditProfileForm() {
                ({ firstName, lastName, zipCode, city, address, editProfileForm } = createEditProfileForm());
}
let { firstName, lastName, zipCode, city, address, editProfileForm } = createEditProfileForm();
...
</script>

And the markup is like this:

...
<form action="/?someAction" use:enhance={() => {
   return async ({ update }) => {
     // this causes the server load function to run again without resetting the 
     // form. The default reset unfortunately completely clears my forms, so I
     // needed to manually reset it, but with fresh values from the server.
     await update({ reset: false, invalidateAll: true });  
    // after the update Promise resolves the PageData is refreshed, 
    // so I fully recreate the form. This has the additional advantage that the form is not dirty again, 
    // so something like disabling buttons when the user didn't do anything yet just works.
     resetEditProfileForm();  
   };
}>
   <input bind:value={$firstName.value} />
   ...
   <button type="submit">Update Profile</button>
....
</form>
...

Either I missed something in the official docs or it's really missing, but I initially tried to find some Event, that tells me that the load functions are done executing after invalidation. Unfortunately I couldn't find something so I had to customize my enhance action. But overall I'm very satisfied with my workaround since it only minimally affects my personal DX.

kasokz avatar Nov 30 '23 21:11 kasokz