This content originally appeared on Bram.us and was authored by Bramus!
Touched upon in my article “Embrace the Platform” over at CSS-Tricks is this experience by Drew Devault:
My web browser has been perfectly competent at submitting HTML forms for the past 28 years, but for some stupid reason some developer decided to reimplement all of the form semantics in JavaScript, and now I can’t pay my electricity bill without opening up the dev tools.
While the article hints at solving this using Progressive Enhancement, it doesn’t cover the practical side of things. Let’s change that with this post.
~
Enhance!
To apply Progressive Enhancement on HTML forms, there’s this little JavaScript gem named FormData
that one can use:
The
FormData
interface provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using thefetch()
orXMLHttpRequest.send()
method. It uses the same format a form would use if the encoding type were set to"multipart/form-data"
.
To use FormData
, create a new instance of it and pass in a form element as its first argument. It will automagically do its thing.
const form = document.querySelector('form');
const data = new FormData(form); // 👈 Magic!
Leveraging FormData
, applying Progressive Enhancement on forms is easy:
- Build a regular HTML form that submits its data to somewhere
- Make it visually interesting using CSS
- Using JavaScript, hijack the form’s
submit
event and instead send its contents — captured throughFormData
— usingfetch()
to the defined endpoint.
A first iteration of the JavaScript code would look like this:
document.querySelector("form").addEventListener("submit", async (event) => {
event.preventDefault();
const form = event.currentTarget;
const resource = form.action;
const options = {
method: form.method,
body: new FormData(form) // 👈 Magic!
};
const r = await fetch(resource, options);
if (!r.ok) {
// @TODO: Show an error message
return;
}
// @TODO: handle the response by showing a message, redirecting, etc.
});
Congratulations, you’ve just progressively enhanced your form!
~
Dealing with JSON and GET
While this basic approach already works, it doesn’t cover all scenarios:
The
FormData
interface […] uses the same format a form would use if the encoding type were set to"multipart/form-data"
.
So if you want to send the data as JSON, you will need to convert the formData
to it yourself. Thankfully, using Modern JavaScript, that’s only a one-liner nowadays. Furthermore the code also doesn’t properly handle GET
requests. To cater for those one doesn’t need to send the formData
using the request body
, but alter the resource
’s query string parameters instead.
Expressed in code, we need these adjustments:
if (options.method === "post") {
if (form.enctype === "multipart/form-data") {
options.body = formData;
} else {
options.body = JSON.stringify(Object.fromEntries(formData));
options.headers['Content-Type'] = 'application/json';
}
} else {
resource.search = new URLSearchParams(formData);
}
~
Demo
Embedded below is a CodePen demo that submits the data to a dummy API and then handles its response:
See the Pen
Progressive Enhancement and <form>: Use FormData by Bramus (@bramus)
on CodePen.
🥳
~
🔥 Like what you see? Want to stay in the loop? Here's how:
This content originally appeared on Bram.us and was authored by Bramus!

Bramus! | Sciencx (2022-04-22T13:11:26+00:00) Progressive Enhancement and HTML Forms: use FormData. Retrieved from https://www.scien.cx/2022/04/22/progressive-enhancement-and-html-forms-use-formdata/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.