Author: @jenseng
The FormData
class allows developers to create data sets populated from a <form>
element, following the same algorithm used during regular form submission.
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:
- Image Button entries may not be constructed correctly, as in this bug
append()
'ing may place the entry(s) out of tree order, as in this bugset()
'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.
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).
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" }