Support the submitter
parameter to the FormData constructor in older browsers.
npm install --save formdata-submitter-polyfill
Then import it early in your client entrypoint .js file, e.g.
import "formdata-submitter-polyfill";
Now you can reliably create FormData
objects populated from both a form and a submitter
. A common scenario for this is in form submission handlers, e.g.
var myform = document.createElement("form");
myform.innerHTML = `
<input name=foo value=FOO>
<button name=go value=GO>go!</button>
<input type=image>
<input name=bar value=BAR>
`;
myform.addEventListener("submit", (event) => {
event.preventDefault();
const formData = new FormData(event.target, event.submitter);
// If the button is the submitter:
// ▸ FormData(3) { foo → "FOO", go → "GO", bar → "BAR" }
// If the image button is the submitter:
// ▸ FormData(4) { foo → "FOO", x → "0", y → "0", bar → "BAR" }
// ... do something with formData ...
});
These FormData
objects are equivalent to the form data sets constructed by equivalent native form submissions.
If you also need to polyfill the submitter
property of the SubmitEvent
, consider using the event-submitter-polyfill
package alongside this one.
The latest TypeScript DOM types support the submitter
parameter. If you are using older DOM types (e.g. the ones that shipped with your version of TypeScript), you can get the latest by running:
npm install @typescript/lib-dom@npm:@types/web --save-dev
If for some reason you can't upgrade yet, in the meantime you can add a // @ts-expect-error
comment to make TypeScript happy 🙈.
If you want more control over how/when the polyfill is activated, you can use the exports provided by formdata-submitter-polyfill/impl
. For example:
import {
FormData,
polyfillFormDataIfNecessary,
} from "formdata-submitter-polyfill/impl";
// this will replace window.FormData with the polyfill if necessary
polyfillFormDataIfNecessary(FormData);
By default, the polyfill fully supports the form entry list construction algorithm, i.e. ensuring that image button and named button submitters are encoded in tree order. It accomplishes this by temporarily tweaking the form during submission to get the right entries.
While this performs well, you can get faster (but less compliant) behavior by doing:
import "formdata-submitter-polyfill/lite";
This will instead create a submitter
-less FormData
object and then append submitter
entries (as appropriate) to the end of the list, e.g.
const formData = new FormData(event.target, event.submitter);
// If the button is the submitter:
// ▸ FormData(3) { foo → "FOO", bar → "BAR", go → "GO" }
// If the image button is the submitter:
// ▸ FormData(4) { foo → "FOO", bar → "BAR", x → "0", y → "0" }
-
If the entry order matters for consumers, this may lead to bugs (i.e. the order will differ from one created from a vanilla form submission).
-
Older versions of Safari will include
submitter
entries twice, due to this bug.
The default polyfill mode does not have these issues.