FormData, the new formdata event, and HTML forms

Have you heard about the new formdata event?

the formdata DOM event

What is FormData?

As with almost any HTML element, HTML forms are able to emit events.

Consider the following form:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HTML forms and JavaScript</title>
</head>
<body>
<form>
    <label for="name">Name</label>
    <input type="text" id="name" name="name" required>

    <label for="description">Short description</label>
    <input type="text" id="description" name="description" required>

    <label for="task">Task</label>
    <textarea id="task" name="task" required></textarea>

    <button type="submit">Submit</button>
</form>
</body>
<script src="form.js"></script>
</html>

When the form is submitted, that is, when the user fills the fields and clicks the "Submit" button, an event named submit is dispatched.

That means that in our JavaScript code we can listen to the submit event with an event listener:

// form.js
const form = document.forms[0];

form.addEventListener("submit", function(event) {
  event.preventDefault();
});

Calling preventDefault() prevents a page refresh, convenient when you want to send the form fields to the backend with an XHR call.

Now, there are a couple ways to get the actual data from the form. You could inspect event.target.elements which in this case yields all the form elements, or even better you can use FormData. It needs the form as an argument, and in exchange it gives the form data as a FormData object:

const form = document.forms[0];

form.addEventListener("submit", function(event) {
  event.preventDefault();
  const data = new FormData(form);
});

From now on you can do all sort of things on the FormData object. As a newer addition to the platform, we are now able to listen for a formdata event. Let's explore it a bit more.

Getting to know the formdata event

The formdata event is a newer, nice addition to the web platform. As a boost to FormData, the event is fired any time you call new FormData(). Consider the following example:

const form = document.forms[0];

form.addEventListener("submit", function(event) {
  event.preventDefault();
  new FormData(form);
});

form.addEventListener("formdata", event => {
  // event.formData grabs the object
  console.log(event.formData);
});

In the first event listener we build a new FormData from the form.

In response to this call the new object fires up the formdata event, on which we register another listener. In this second listener we can access the actual data from event.formData.

This pattern helps decoupling the first event listeners from any other callback that was supposed to handle the actual form data. This is super useful in a lot of situations.

For example, we might want to add more data to form data after all the initial form data has been gathered:

const form = document.forms[0];

form.addEventListener("submit", function(event) {
  event.preventDefault();
  new FormData(form);
});

form.addEventListener("formdata", event => {
  // add more fields to form data
  const data = event.formData;
  
  data.append('another_field', 'the-value');
  
  // send the data
});

This is useful when we have a piece of code which wants to add more fields to form data, and does not live in the same scope of the code calling new FormData(). Think of it as a post-processing step for form data.

As with any new addition to the platform, the formdata might not be supported by all browsers, so it might need a polyfill.

Thanks for reading and stay tuned!

Resources

Working with the formdata DOM event

FormData objects on MDN

Valentino Gagliardi

Hi! I'm Valentino! I'm a freelance consultant with a wealth of experience in the IT industry. I spent the last years as a frontend consultant, providing advice and help, coaching and training on JavaScript, testing, and software development. Let's get in touch!