Skip to content

Commit

Permalink
Add multiple forms test
Browse files Browse the repository at this point in the history
  • Loading branch information
unlocomqx committed Apr 7, 2024
1 parent 46328cc commit 47846fc
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 3 deletions.
33 changes: 30 additions & 3 deletions src/lib/client/superForm.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable dci-lint/atomic-role-binding */
import type { TaintedFields, SuperFormValidated, SuperValidated } from '$lib/superValidate.js';
import type { ActionResult, Page, SubmitFunction } from '@sveltejs/kit';
import type { ActionResult, BeforeNavigate, Page, SubmitFunction } from '@sveltejs/kit';
import {
derived,
get,
Expand Down Expand Up @@ -383,6 +383,30 @@ try {
// No Storybook
}

const onDestroyCallbacks = new Set<() => void>();
let onDestroyInited = false;
const initOnDestroyHandler = () => {
if (onDestroyInited) return;
onDestroyInited = true;
onDestroy(() => {
for (const callback of onDestroyCallbacks) {
callback();
}
});
};

const beforeNavigateCallbacks = new Set<(nav: BeforeNavigate) => Promise<void>>();
let beforeNavigateInited = false;
const initBeforeNavigateHandler = () => {
if (beforeNavigateInited) return;
beforeNavigateInited = true;
beforeNavigate((nav: BeforeNavigate) => {
for (const callback of beforeNavigateCallbacks) {
callback(nav);
}
});
};

/////////////////////////////////////////////////////////////////////

/**
Expand All @@ -404,6 +428,9 @@ export function superForm<
// To check if a full validator is used when switching options.validators dynamically
let initialValidator: FormOptions<T, M, In>['validators'] | undefined = undefined;

initOnDestroyHandler();
initBeforeNavigateHandler();

{
if (options.legacy ?? LEGACY_MODE) {
if (options.resetForm === undefined) options.resetForm = false;
Expand Down Expand Up @@ -518,7 +545,7 @@ export function superForm<

///// From here, form is properly initialized /////

onDestroy(() => {
onDestroyCallbacks.add(() => {
Unsubscriptions_unsubscribe();
NextChange_clear();
EnhancedForm_destroy();
Expand Down Expand Up @@ -1350,7 +1377,7 @@ export function superForm<
// Tainted check
const defaultMessage = 'Leave page? Changes that you made may not be saved.';
let forceRedirection = false;
beforeNavigate(async (nav) => {
beforeNavigateCallbacks.add(async (nav: BeforeNavigate) => {
if (options.taintedMessage && !Data.submitting && !forceRedirection) {
if (Tainted_isTainted()) {
const { taintedMessage } = options;
Expand Down
1 change: 1 addition & 0 deletions src/routes/(v2)/v2/Navigation.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'issue-337-checkboxes',
'issue-345',
'letters',
'multiple-forms',
'multiple-files',
'multistep-client',
'multistep-server',
Expand Down
42 changes: 42 additions & 0 deletions src/routes/(v2)/v2/multiple-forms/+page.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { zod } from '$lib/adapters/zod.js';
import { superValidate } from '$lib/server/index.js';
import { type Actions } from '@sveltejs/kit';
import { schema } from './schema.js';

const items = [
{
id: 1,
label: 'One'
},
{
id: 2,
label: 'Two'
},
{
id: 3,
label: 'Three'
}
];

export const load = async () => {
const item_forms = await Promise.all(
items.map((item) =>
superValidate(item, zod(schema), {
id: item.id.toString()
})
)
);

return { item_forms };
};

export const actions: Actions = {
async default() {
items.push({
id: items.length + 1,
label: (items.length + 1).toString()
});

return { success: true };
}
};
24 changes: 24 additions & 0 deletions src/routes/(v2)/v2/multiple-forms/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script lang="ts">
import type { PageData } from './$types.js';
import { superForm } from '$lib/client/index.js';
import Form from './Form.svelte';
import { enhance } from '$app/forms';
let {
data
}: {
data: PageData;
} = $props();
const superforms = $derived(data.item_forms.map(item_form => superForm(item_form, {
dataType: 'json'
})));
</script>

{#each superforms as form (form.formId)}
<Form {form} />
{/each}

<form method=post use:enhance>
<button type=submit>Add</button>
</form>
17 changes: 17 additions & 0 deletions src/routes/(v2)/v2/multiple-forms/Form.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script lang="ts">
import type { SuperForm } from '$lib/index.js';
import type { schema } from './schema.js';
import { z } from 'zod';
import SuperDebug from '$lib/client/SuperDebug.svelte';
let { form }: {
form: SuperForm<z.infer<typeof schema>>;
} = $props();
let { form: item, enhance } = form;
</script>

<hr>
<form action="?/save" method="post" use:enhance>
<SuperDebug data={$item} />
</form>
6 changes: 6 additions & 0 deletions src/routes/(v2)/v2/multiple-forms/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { z } from 'zod';

export const schema = z.object({
id: z.number(),
label: z.string()
});

0 comments on commit 47846fc

Please sign in to comment.