Skip to content

Instantly share code, notes, and snippets.

@jenseng
Last active January 30, 2023 22:04
Show Gist options
  • Save jenseng/351d09ffcd86508fb19bc18d019318bb to your computer and use it in GitHub Desktop.
Save jenseng/351d09ffcd86508fb19bc18d019318bb to your computer and use it in GitHub Desktop.
FormData submitter explainer

Add optional submitter argument to FormData constructor

Author: @jenseng

Background

The FormData class allows developers to create data sets populated from a <form> element, following the same algorithm used during regular form submission.

Problems

Existing FormData implementations don't provide a mechanism to specify the submitter (i.e. the submit button used to submit the form), meaning any such entries will not be included. As a workaround, website and framework developers can explicitly add entries for the submitter, but this is hard to get right:

  1. Image Button entries may not be constructed correctly, as in this bug
  2. append()'ing may place the entry(s) out of tree order, as in this bug
  3. set()'ing may place the entry(s) out of tree order, and replace other entries of the same name, as in this bug

Depending on how the FormData object is used, this may result in bugs (e.g. if used in an XHR against a server that expects the data set to conform to a conventional form submission).

While it's possible to work around these limitations (e.g. using temporary hidden inputs adjacent to the submitter), first class support would provide a better and more reliable user experience.

Solution

The new optional submitter parameter allows developers to construct a FormData object from a form and submitter that matches the equivalent native form submission (i.e. including submit button entry(s), as appropriate).

Examples

var myform = document.createElement("form");
myform.innerHTML = `
  <input name=foo value=Foo>
  <button id=unnamed>go!</button>
  <button name=named value=GO>go!</button>
  <input type=image id=unnamedImage>
  <input type=image name=namedImage>
  <input name=bar value=BAR>
`;
new FormData(myform, myform.querySelector("#unnamed"));
// ▸ FormData(2) { foo → "Foo", bar → "BAR" }
new FormData(myform, myform.querySelector("[name=named]"));
// ▸ FormData(3) { foo → "Foo", named → "GO", bar → "BAR" }
new FormData(myform, myform.querySelector("#unnamedImage"));
// ▸ FormData(4) { foo → "Foo", x → "0", y → "0", bar → "BAR" }
new FormData(myform, myform.querySelector("[name=namedImage]"));
// ▸ FormData(4) { foo → "Foo", namedImage.x → "0", namedImage.y → "0", bar → "BAR" }

See Also

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment