Skip to content

Commit 744dc81

Browse files
authored
set form to null before updating it with real values (#9267)
* set `form` to `null` before updating it with real values - fixes #8513 * changeset and test
1 parent 7c8dbf3 commit 744dc81

File tree

5 files changed

+49
-10
lines changed

5 files changed

+49
-10
lines changed

.changeset/thin-readers-speak.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': patch
3+
---
4+
5+
fix: preserve form state when submitting a second time

packages/kit/src/runtime/client/client.js

+10-5
Original file line numberDiff line numberDiff line change
@@ -1410,14 +1410,19 @@ export function create_client(app, target) {
14101410
goto(result.location, { invalidateAll: true }, []);
14111411
} else {
14121412
/** @type {Record<string, any>} */
1413-
const props = {
1414-
form: result.data,
1413+
root.$set({
1414+
// this brings Svelte's view of the world in line with SvelteKit's
1415+
// after use:enhance reset the form....
1416+
form: null,
14151417
page: { ...page, form: result.data, status: result.status }
1416-
};
1417-
root.$set(props);
1418+
});
1419+
1420+
// ...so that setting the `form` prop takes effect and isn't ignored
1421+
await tick();
1422+
root.$set({ form: result.data });
14181423

14191424
if (result.type === 'success') {
1420-
tick().then(reset_focus);
1425+
reset_focus();
14211426
}
14221427
}
14231428
},

packages/kit/test/apps/basics/src/routes/actions/enhance/+page.server.js

+7
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,12 @@ export const actions = {
3232
},
3333
error: () => {
3434
throw error(400, 'error');
35+
},
36+
echo: async ({ request }) => {
37+
const data = await request.formData();
38+
39+
return {
40+
message: data.get('message')
41+
};
3542
}
3643
};

packages/kit/test/apps/basics/src/routes/actions/enhance/+page.svelte

+10-3
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@
1414
<pre class="formdata2">{JSON.stringify($page.form)}</pre>
1515

1616
<form method="post" action="?/login" use:enhance>
17-
<input type=hidden name="action" value="DOM clobbering" />
18-
<input type=hidden name="reset" value="DOM clobbering" />
17+
<input type="hidden" name="action" value="DOM clobbering" />
18+
<input type="hidden" name="reset" value="DOM clobbering" />
1919
<input name="username" type="text" />
2020
<button class="form1">Submit</button>
2121
<button class="form1-register" formAction="?/register">Submit</button>
22-
<button class="form1-submitter" formAction="?/submitter" name="submitter" value="foo">Submit</button>
22+
<button class="form1-submitter" formAction="?/submitter" name="submitter" value="foo">
23+
Submit
24+
</button>
2325
<button class="form1-error" formAction="?/error">Submit</button>
2426
</form>
2527

@@ -35,3 +37,8 @@
3537
>
3638
<button class="form2">Submit</button>
3739
</form>
40+
41+
<form method="post" action="?/echo" use:enhance>
42+
<input name="message" type="text" value={form?.message ?? ''} />
43+
<button class="form3">Submit</button>
44+
</form>

packages/kit/test/apps/basics/test/test.js

+17-2
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,7 @@ test.describe('Actions', () => {
976976
}
977977
});
978978

979-
test('use:enhance button with formAction', async ({ page, app }) => {
979+
test('use:enhance button with formAction', async ({ page }) => {
980980
await page.goto('/actions/enhance');
981981

982982
expect(await page.textContent('pre.formdata1')).toBe(JSON.stringify(null));
@@ -989,7 +989,7 @@ test.describe('Actions', () => {
989989
);
990990
});
991991

992-
test('use:enhance button with name', async ({ page, app }) => {
992+
test('use:enhance button with name', async ({ page }) => {
993993
await page.goto('/actions/enhance');
994994

995995
expect(await page.textContent('pre.formdata1')).toBe(JSON.stringify(null));
@@ -1004,6 +1004,21 @@ test.describe('Actions', () => {
10041004
);
10051005
});
10061006

1007+
test('use:enhance does not clear form on second submit', async ({ page }) => {
1008+
await page.goto('/actions/enhance');
1009+
1010+
await page.locator('input[name="message"]').fill('hello');
1011+
1012+
await page.locator('.form3').click();
1013+
await expect(page.locator('pre.formdata1')).toHaveText(JSON.stringify({ message: 'hello' }));
1014+
await expect(page.locator('pre.formdata2')).toHaveText(JSON.stringify({ message: 'hello' }));
1015+
1016+
await page.locator('.form3').click();
1017+
await page.waitForTimeout(0); // wait for next tick
1018+
await expect(page.locator('pre.formdata1')).toHaveText(JSON.stringify({ message: 'hello' }));
1019+
await expect(page.locator('pre.formdata2')).toHaveText(JSON.stringify({ message: 'hello' }));
1020+
});
1021+
10071022
test('redirect', async ({ page, javaScriptEnabled }) => {
10081023
await page.goto('/actions/redirect');
10091024

0 commit comments

Comments
 (0)