DEV Community

Valentino Gagliardi
Valentino Gagliardi

Posted on • Edited on • Originally published at valentinog.com

FormData, the new formdata event, and HTML forms

Have you heard about the new formdata event? It's just a new DOM event, but every new addition to the web platform makes me always excited.

What is FormData?

Let's clarify what is FormData before getting into more detail. For those new to web development, HTML forms are able to emit events. This is a feature of almost any HTML element.

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>


Enter fullscreen mode Exit fullscreen mode

To follow along you can create an HTML file, copy over my example. 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 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();
});


Enter fullscreen mode Exit fullscreen mode

Calling preventDefault() prevents a page refresh, convenient when you don't want to send the form fields on the backend.

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, a DOM interface, as a constructor. It needs the form as an argument:



const form = document.forms[0];

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


Enter fullscreen mode Exit fullscreen mode

From now on you can do all sort of things on the FormData object. More on this later. Now let's explore the formdata event.

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(). Now 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);
});


Enter fullscreen mode Exit fullscreen mode

In the first event listener we build a new FormData from the form. This time there's no need to save the result in a variable.

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 grab 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 (making API calls and stuff).

In the next section we'll see how to get data from a FormData object.

Grabbing data from a FormData object

If you want to snitch into a FormData object visit the example HTML form in a browser and place a breakpoint on console.log(event.formData).

Fill and submit the form with the browser's console opened and save the object as a global variable:

formData

You should be able to access the object (temp1) in Chrome:



console.log(temp1)
// FormData {append: ƒ, delete: ƒ, get: ƒ, getAll: ƒ, has: ƒ, …}


Enter fullscreen mode Exit fullscreen mode

As you can see it has a bunch of methods. To extract an array of values run:



const values = [...temp1.values()]
// sample output
// ["Liz", "Trip to London", "Trip to London"]


Enter fullscreen mode Exit fullscreen mode

To extract an array of entries run:



const entries = [...temp1.entries()]


Enter fullscreen mode Exit fullscreen mode

In our example we can get all the data in various shapes from the FormData object:



const form = document.forms[0];

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

form.addEventListener("formdata", event => {
  const data = event.formData;

  // get the data
  const entries = [...data.entries()];
  console.log(entries);

  const values = [...data.values()];
  console.log(values);
});


Enter fullscreen mode Exit fullscreen mode

A word of warning: FormData relies on form fields name attributes to build the mapping between fields and values. That means the following elements won't yield anything:



<!-- bad -->
<input type="text" id="name" required>
<input type="text" id="description" required>


Enter fullscreen mode Exit fullscreen mode

Always provide a name for your fields:



<!-- good -->
<input type="text" id="name" name="name" required>
<input type="text" id="description" name="description" required>


Enter fullscreen mode Exit fullscreen mode

Adding data to a FormData object

It's common practice to have hidden inputs in HTML forms for saving additional data in the submission phase:



<!-- no more hidden fields -->
<input type="hidden" id="someInfo" name="someSecretInfo" value="someSecreteInfo">


Enter fullscreen mode Exit fullscreen mode

Hidden inputs don't show up in the rendered HTML (but are still accessible from the developer console).

In addition to reading form fields from a FormData object, it's also possible to add new key/value pair with append:



// omitted for brevity

form.addEventListener("formdata", event => {
  const data = event.formData;

  // append more fields
  data.append("anHiddenKeyA", "anHiddenValueA");
  data.append("anHiddenKeyB", "anHiddenValueB");

  // get the data
  const entries = [...data.entries()];
  console.log(entries);

  const values = [...data.values()];
  console.log(values);
});


Enter fullscreen mode Exit fullscreen mode

This is convenient for avoiding hidden input fields in HTML forms.

Being a newer addition to the platform the formdata event is not available in older browsers, use it with caution.

Thanks for reading and stay tuned for more!

Resources

FormData objects on MDN

Top comments (4)

Collapse
 
cloudpower97 profile image
Claudio Cortese

Well, actually that's not exactly true that this is a new "addition to the platform".

The first browser to support this event was Chrome 7 in 2010, and most browser rapidly gained supports in the following years.

As of today every browser has supports for it, but this is the case for almost 5 years, if not more. 😜

Collapse
 
valentinogagliardi profile image
Valentino Gagliardi

FormData exists since I can remember. The formdata event instead is quite new: caniuse.com/#feat=mdn-api_formdata...

Collapse
 
cloudpower97 profile image
Claudio Cortese

Missed this one!
Thanks for pointing that out 🤓

Collapse
 
fininhors profile image
Francisco Junior

Very good, good job man.