Skip to content

remote form: resetting form does not clear validation errors and does not reset touched state #14754

@WHenderson

Description

@WHenderson

Describe the bug

When invoking a form reset - either from a html form.reset or a html reset button - the form fields reset their values,but validation errors and touched states persist. This results in form which is visually a mix of old and new information.

Expected Behaviour:
Resetting form should:

  • Clear all field inputs to their default state (working)
  • Reset validation state
  • Reset touched/dirty state
  • Reset the form to its initial pristine state

Motivation:
I am using forms within modal dialogs and would like to reuse the same form (e.g. create user). Without a full reset, stale validation messages and interaction states confuse users and degrade UX.

Reproduction

https://www.sveltelab.dev/5mj2374de4h2r1r

// schema.ts
import z4 from "zod/v4";

export const schema = z4.object({
	name: z4.string().min(1, "Name is required"),
	age: z4.int().min(18, "Must be at least 18")
});
// form.remote.js
import { form } from '$app/server';   
import { schema } from './schema';

export const create = form(
	schema,
	async (data, invalid) => {
		console.log('received', data);
		return { success: true }
	}
)
<!-- +page.svelte -->
<script>
	import { schema } from './schema';
	import { create } from './form.remote';

	let { data } = $props();

	let enhanced = create
		.preflight(schema)
		.enhance(async ({ form, data, submit }) => {
			try {
				await submit();
				console.log('success');
			}
			catch (e) {
				console.error('failure', e);
			}
		}) 
</script>

<form onchange={() => create.validate()} {...enhanced} class="flex flex-col gap-4">
	<label class="flex flex-col gap-2">
		Name
		<input {...create.fields.name.as('text')} defaultValue="John">
	</label>
	{#each create.fields.name.issues() as issue}
		<p class="text-red-500">{issue.message}</p>
	{/each}
	
	<label class="flex flex-col gap-2">
		Age
		<input {...create.fields.age.as('number')} >
	</label>
	{#each create.fields.age.issues() as issue}
		<p class="text-red-500">{issue.message}</p>
	{/each}

	
	<div class="flex flex-row gap-4">
		<button type="submit" class="px-4 py-2 bg-gray-500 text-white font-semibold rounded-md shadow-md hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-75">Submit</button>
		<button type="reset" class="px-4 py-2 bg-gray-500 text-white font-semibold rounded-md shadow-md hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-75">Reset</button>
	</div>
	
</form>

Logs

System Info

sveltekit 2.47.1

Severity

annoyance

Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    formsStuff relating to forms and form actions

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions