The submitter parameter for FormData


Buttons can send values too

In forms, buttons are usually used just to submit the form. Optionally though, a submit button can have a name and, also optionally, a value.

<button name="foo" value="bar" type="submit">Submit</button>

There are two ways to submit a form on the web: either let the default behaviour of HTML handle it, or call event.preventDefault() on the submit event and use JavaScript to send the data. When using the HTML approach, the name and value of the button are sent to the server alongside the rest of the form data automatically.

Multiple submit buttons

If you have multiple buttons in the same form that each have a name, it will only send data for one of those buttons — the one that was actually clicked by the user to submit the form.

<form action="/test-form" method="post">
  <button name="_action" value="delete" type="submit">Delete</button>
  <button name="_action" value="disable" type="submit">Disable</button>
</form>

Sending a form with JavaScript

When using the FormData constructor in JavaScript, unlike a HTML form submission, no button data is included by default.

const form = document.getElementById("form");
form.addEventListener("submit", function (event) {
  event.preventDefault();
  const formdata = new FormData(form);
  console.log(formdata.has("_action")); // logs false

  fetch("/test-form", {
    method: "POST",
    body: formdata,
  });
});

There’s now a way to match the HTML behaviour when using JavaScript. event.submitter has long existed as a way to identify the button that was used to submit the form. By passing it as the second argument to the FormData() constructor, the name and value of the relevant button get included in the FormData object:

const form = document.getElementById("form");
form.addEventListener("submit", function (event) {
  event.preventDefault();

  const formdata = new FormData(form, event.submitter);
  console.log(formdata.has("_action")); // logs true

  fetch("/test-form", {
    method: "POST",
    body: formdata,
  });
});

A live example of the code can be found on StackBlitz.

The submitter parameter for the FormData constructor has been supported since Chrome 112, Firefox 111 and Safari 16.4.