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
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// @jest-environment jsdom

import * as React from 'react';
import * as ReactDOMClient from 'react-dom/client';
import {act} from 'internal-test-utils';

describe('form submitter with input[name="id"]', () => {
let container;

beforeEach(() => {
container = document.createElement('div');
document.body.appendChild(container);
delete window.__SUBMIT_ACTION__;
});

afterEach(() => {
document.body.removeChild(container);
container = null;
delete window.__SUBMIT_ACTION__;
});

it('includes submitter when input[name="id"] exists (button inside form)', async () => {
function App() {
async function action(fd) {
window.__SUBMIT_ACTION__ = fd.get('action');
}
return (
<form id="my-form" action={action}>
<input type="hidden" name="id" value="1" />
<button type="submit" name="action" value="save">
Save
</button>
</form>
);
}

await act(async () => {
const root = ReactDOMClient.createRoot(container);
root.render(<App />);
});

await act(async () => {
container.querySelector('button').click();
});

expect(window.__SUBMIT_ACTION__).toBe('save');
});

it('includes submitter when using external button with form attribute', async () => {
function AppExternal() {
async function action(fd) {
window.__SUBMIT_ACTION__ = fd.get('action');
}
return (
<>
<form id="my-form" action={action}>
<input type="hidden" name="id" value="1" />
</form>
<button type="submit" name="action" value="save" form="my-form">
Save
</button>
</>
);
}

await act(async () => {
const root = ReactDOMClient.createRoot(container);
root.render(<AppExternal />);
});

await act(async () => {
container.querySelector('button').click();
});

expect(window.__SUBMIT_ACTION__).toBe('save');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,16 @@ function createFormDataWithSubmitter(
const temp = submitter.ownerDocument.createElement('input');
temp.name = submitter.name;
temp.value = submitter.value;
if (form.id) {
temp.setAttribute('form', form.id);

// Use the form element's *id attribute*. A named control like <input name="id">
// can clobber the `form.id` property to point to that control instead of the
// element's id attribute.
const formId =
typeof form.getAttribute === 'function' ? form.getAttribute('id') : null;
if (formId) {
temp.setAttribute('form', formId);
}

(submitter.parentNode: any).insertBefore(temp, submitter);
const formData = new FormData(form);
(temp.parentNode: any).removeChild(temp);
Expand Down