Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion packages/fresh/src/runtime/client/partials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,14 @@ document.addEventListener("submit", async (e) => {
// TODO: Looks like constructor type for URLSearchParam is wrong
// deno-lint-ignore no-explicit-any
const qs = new URLSearchParams(new FormData(el, e.submitter) as any);
qs.forEach((value, key) => partialUrl.searchParams.append(key, value));
qs.forEach((value, key) => {
partialUrl.searchParams.append(key, value);
// The address bar has to reflect the submitted values too, the way a
// native GET form navigation does. Without this the page URL keeps
// the bare action and the submitted state is lost on reload, on
// copying the link, or on back/forward.
actionUrl.searchParams.append(key, value);
});
} else {
init = { body: new FormData(el, e.submitter), method: lowerMethod };
}
Expand Down
45 changes: 45 additions & 0 deletions packages/fresh/tests/partials_test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2745,6 +2745,51 @@ Deno.test({
},
});

Deno.test({
name: "partials - form submit puts values into the page url",
fn: async () => {
const app = testApp()
.get("/", (ctx) => {
const name = ctx.url.searchParams.get("name");
return ctx.render(
<Doc>
<div f-client-nav>
<form action="/">
<input type="hidden" name="name" value="foo" />
<button type="submit" class="update">
update
</button>
</form>
<Partial name="foo">
<p class={name === null ? "init" : "done"}>{name ?? "init"}</p>
</Partial>
<SelfCounter />
</div>
</Doc>,
);
});

await withBrowserApp(app, async (page, address) => {
await page.goto(address, { waitUntil: "load" });
await page.locator(".ready").wait();

await page.locator(".increment").click();
await waitForText(page, ".output", "1");

await page.locator(".update").click();
await page.locator(".done").wait();

// Same URL a native GET form navigation would produce.
const rawUrl = await page.evaluate(() => window.location.href);
const url = new URL(rawUrl);
expect(`${url.pathname}${url.search}`).toEqual("/?name=foo");

// Still a partial update, not a full page load.
await waitForText(page, ".output", "1");
});
},
});

Deno.test({
name: "partials - backwards navigation should keep URLs",
fn: async () => {
Expand Down