FormData, the new formdata event, and HTML forms
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!