Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(remix-react): fix <Form> submit to not break formMethod functionality #4053

Merged
merged 13 commits into from
Oct 13, 2022
Merged
2 changes: 2 additions & 0 deletions contributors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@
- KenanYusuf
- kentcdodds
- kevinrambaud
- kevlened
- kgregory
- kiancross
- kilian
Expand Down Expand Up @@ -280,6 +281,7 @@
- maxprilutskiy
- mbarto
- mcansh
- mdoury
- medayz
- meetbryce
- mehulmpt
Expand Down
107 changes: 107 additions & 0 deletions integration/form-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,76 @@ test.describe("Forms", () => {
}
`,

"app/routes/submitter-formmethod.jsx": js`
import { useActionData, useLoaderData, Form } from "@remix-run/react";
import { json } from '@remix-run/node'

export function action({ request }) {
return json(request.method)
}

export function loader({ request }) {
return json(request.method)
}

export default function Index() {
let actionData = useActionData();
let loaderData = useLoaderData();
return (
<>
<Form method="post">
<button type="submit" formMethod="get">Submit with GET</button>
</Form>
<Form method="get">
<button type="submit" formMethod="post">Submit with POST</button>
</Form>

<pre>{actionData || loaderData}</pre>
</>
)
}
`,

"app/routes/form-method.jsx": js`
import { Form, useActionData } from "@remix-run/react";
import { json } from "@remix-run/node";

export function action({ request }) {
return json(request.method)
}
export default function() {
let actionData = useActionData();
return (
<>
<Form method="post">
<button type="submit">Submit</button>
</Form>
<pre>{actionData}</pre>
</>
)
}
`,

"app/routes/button-form-method.jsx": js`
import { Form, useActionData } from "@remix-run/react";
import { json } from "@remix-run/node";

export function action({ request }) {
return json(request.method)
}
export default function() {
let actionData = useActionData();
return (
<>
<Form>
<button type="submit" formMethod="post">Submit</button>
</Form>
<pre>{actionData}</pre>
</>
)
}
`,

"app/routes/submitter.jsx": js`
import { useLoaderData, Form } from "@remix-run/react";

Expand Down Expand Up @@ -818,6 +888,43 @@ test.describe("Forms", () => {
});
});

test.describe("with submitter button having `formMethod` attribute", () => {

test.describe("overrides the form `method` attribute with the button `formmethod` attribute", () => {
test("submits with GET instead of POST", async ({ page }) => {
let app = new PlaywrightFixture(appFixture, page);
await app.goto("/submitter-formmethod");
await app.clickElement("text=Submit with GET");
await page.waitForLoadState("load");
expect(await app.getHtml("pre")).toBe("<pre>GET</pre>");
});

test("submits with POST instead of GET", async ({ page }) => {
let app = new PlaywrightFixture(appFixture, page);
await app.goto("/submitter-formmethod");
await app.clickElement("text=Submit with POST");
await page.waitForLoadState("load");
expect(await app.getHtml("pre")).toBe("<pre>POST</pre>");
});
})

test("uses the form `method` attribute", async ({ page }) => {
let app = new PlaywrightFixture(appFixture, page);
await app.goto("/form-method");
await app.clickElement("button");
await page.waitForLoadState("load");
expect(await app.getHtml("pre")).toMatch("POST");
});

test("uses the button `formmethod` attribute", async ({ page }) => {
let app = new PlaywrightFixture(appFixture, page);
await app.goto("/button-form-method");
await app.clickElement("button");
await page.waitForLoadState("load");
expect(await app.getHtml("pre")).toMatch("POST");
});
});

test("<Form> submits the submitter's value appended to the form data", async ({
page,
browserName,
Expand Down
2 changes: 1 addition & 1 deletion packages/remix-react/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -983,7 +983,7 @@ let FormImpl = React.forwardRef<HTMLFormElement, FormImplProps>(
let submitter = (event as unknown as HTMLSubmitEvent)
.nativeEvent.submitter as HTMLFormSubmitter | null;

submit(submitter || event.currentTarget, { method, replace });
submit(submitter || event.currentTarget, { replace });
}
}
{...props}
Expand Down