mirror of
https://github.com/withastro/astro.git
synced 2025-01-06 22:10:10 -05:00
Allow same-page navigations on form posts (#9055)
* Allow same-page navigations on form posts * Add another comment
This commit is contained in:
parent
1bc3319686
commit
f105b1002b
4 changed files with 43 additions and 2 deletions
|
@ -89,7 +89,8 @@ const { fallback = 'animate', handleForms } = Astro.props;
|
|||
|
||||
const form = el as HTMLFormElement;
|
||||
const formData = new FormData(form);
|
||||
let action = form.action;
|
||||
// Use the form action, if defined, otherwise fallback to current path.
|
||||
let action = form.action ?? location.pathname;
|
||||
const options: Options = {};
|
||||
if (form.method === 'get') {
|
||||
const params = new URLSearchParams(formData as any);
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
import Layout from '../components/Layout.astro';
|
||||
|
||||
if(Astro.request.method === 'POST') {
|
||||
const formData = await Astro.request.formData();
|
||||
const name = formData.get('name');
|
||||
return Astro.redirect(`/form-response?name=${name}`);
|
||||
}
|
||||
---
|
||||
<Layout>
|
||||
<h2>Contact Form</h2>
|
||||
<h3>This form does not have an `action` defined</h3>
|
||||
<form method="post">
|
||||
<input type="hidden" name="name" value="Testing">
|
||||
<input type="submit" value="Submit" id="submit">
|
||||
</form>
|
||||
</Layout>
|
|
@ -982,4 +982,26 @@ test.describe('View Transitions', () => {
|
|||
]);
|
||||
expect(reqUrls).toContainEqual('/one');
|
||||
});
|
||||
|
||||
test('form POST with no action handler', async ({ page, astro }) => {
|
||||
const loads = [];
|
||||
page.addListener('load', async (p) => {
|
||||
loads.push(p);
|
||||
});
|
||||
|
||||
await page.goto(astro.resolveUrl('/form-two'));
|
||||
|
||||
let locator = page.locator('h2');
|
||||
await expect(locator, 'should have content').toHaveText('Contact Form');
|
||||
|
||||
// Submit the form
|
||||
await page.click('#submit');
|
||||
const span = page.locator('#contact-name');
|
||||
await expect(span, 'should have content').toHaveText('Testing');
|
||||
|
||||
expect(
|
||||
loads.length,
|
||||
'There should be only 1 page load. No additional loads for the form submission'
|
||||
).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -463,9 +463,10 @@ export function navigate(href: string, options?: Options) {
|
|||
}
|
||||
const toLocation = new URL(href, location.href);
|
||||
// We do not have page transitions on navigations to the same page (intra-page navigation)
|
||||
// *unless* they are form posts which have side-effects and so need to happen
|
||||
// but we want to handle prevent reload on navigation to the same page
|
||||
// Same page means same origin, path and query params (but maybe different hash)
|
||||
if (location.origin === toLocation.origin && samePage(toLocation)) {
|
||||
if (location.origin === toLocation.origin && samePage(toLocation) && !options?.formData) {
|
||||
moveToLocation(toLocation, options?.history === 'replace', true);
|
||||
} else {
|
||||
// different origin will be detected by fetch
|
||||
|
|
Loading…
Reference in a new issue