diff --git a/.changeset/small-pens-love.md b/.changeset/small-pens-love.md new file mode 100644 index 000000000..9c1ad3e1f --- /dev/null +++ b/.changeset/small-pens-love.md @@ -0,0 +1,5 @@ +--- +'svelte-ux': patch +--- + +fix(Form): Only prevent submitting to server if validation fails or no server action/method are defined diff --git a/packages/svelte-ux/src/lib/components/Form.svelte b/packages/svelte-ux/src/lib/components/Form.svelte index 7cd20cb5b..3ff3c4e0c 100644 --- a/packages/svelte-ux/src/lib/components/Form.svelte +++ b/packages/svelte-ux/src/lib/components/Form.svelte @@ -14,6 +14,12 @@ let className: string | undefined = undefined; export { className as class }; + /** Endpoint to submit form data */ + export let action: string | undefined = undefined; + + /** HTTP method to submit form. If action defined, defaults to `post`, else is undefined and will prevent submitted (client-side only)*/ + export let method: 'post' | 'get' | 'dialog' | undefined = action != null ? 'post' : undefined; + const settingsClasses = getComponentClasses('Form'); const [_state, draft, errors] = formStore(initial, { schema }); @@ -24,10 +30,17 @@
{ - draft.commit(); + {action} + {method} + on:submit={(e) => { + const result = draft.commit(); + if (!result || method === undefined) { + // Prevent submitted to server if validation failed, or no server side action/method set + e.preventDefault(); + } }} - on:reset|preventDefault={(e) => { + on:reset={(e) => { + e.preventDefault(); draft.revert(); }} class={cls(settingsClasses.root, className)} diff --git a/packages/svelte-ux/src/lib/stores/formStore.ts b/packages/svelte-ux/src/lib/stores/formStore.ts index 80db64fa5..dda960c2a 100644 --- a/packages/svelte-ux/src/lib/stores/formStore.ts +++ b/packages/svelte-ux/src/lib/stores/formStore.ts @@ -51,6 +51,7 @@ export default function formStore( // Clear errors errorsStore.set({}); // TODO: Consider using `result.data` in case there are defaults, etc? + return true; } else { const errors = {}; for (const issue of result.error.issues) { diff --git a/packages/svelte-ux/src/routes/docs/components/Form/+page.server.ts b/packages/svelte-ux/src/routes/docs/components/Form/+page.server.ts new file mode 100644 index 000000000..65cc61074 --- /dev/null +++ b/packages/svelte-ux/src/routes/docs/components/Form/+page.server.ts @@ -0,0 +1,8 @@ +export const actions = { + default: async (event) => { + console.log('Default action'); + }, + // example: async (event) => { + // console.log('Example action'); + // }, +}; diff --git a/packages/svelte-ux/src/routes/docs/components/Form/+page.svelte b/packages/svelte-ux/src/routes/docs/components/Form/+page.svelte index fa0e99a10..542da79c8 100644 --- a/packages/svelte-ux/src/routes/docs/components/Form/+page.svelte +++ b/packages/svelte-ux/src/routes/docs/components/Form/+page.svelte @@ -75,6 +75,44 @@ +

Form submit with method

+ + +
(data = e.detail)} let:draft let:state> + { + draft.name = e.detail.value; + }} + /> + + +
+
state: {JSON.stringify(state)}
+
+ +
+ + +

zod schema

@@ -112,3 +150,42 @@ + +

zod schema with server submit

+ + +
(schemaData = e.detail)} + let:draft + let:state + let:errors + > +
+ { + draft.firstName = e.detail.value; + }} + error={errors.firstName} + /> + { + draft.lastName = e.detail.value; + }} + error={errors.lastName} + /> +
+ + +
+
state: {JSON.stringify(state)}
+
errors: {JSON.stringify(errors)}
+
+
+