Last week, we looked at how to serialize form data into an object in vanilla JS. Today, we'll modify that helper function slightly so that it returns a JSON string instead. Let's start with the function from last week:
/**
* Serialize all form data into an object
* @param {HTMLFormElement} form The form to serialize
* @returns {Object} The serialized form data
*/
function serializeObject (form) {
// Create a new FormData object
const formData = new FormData(form);
// Create an object to hold the name/value pairs
const pairs = {};
// Add each name/value pair to the object
for (const [name, value] of formData) {
pairs[name] = value;
}
// Return the object
return pairs;
}
All we need to do is adjust the JSDoc block, rename the function, and add a call to the JSON.stringify()
method at the end:
/**
* Serialize all form data into a JSON string
* @param {HTMLFormElement} form The form to serialize
* @returns {String} The serialized form data
*/
function serializeJSON (form) {
// Create a new FormData object
const formData = new FormData(form);
// Create an object to hold the name/value pairs
const pairs = {};
// Add each name/value pair to the object
for (const [name, value] of formData) {
pairs[name] = value;
}
// Return the JSON string
return JSON.stringify(pairs, null, 2);
}
Because I like my JSON strings to be nicely formatted, I used 2
as the third argument to the JSON.stringify()
method. This means that the JSON string will be indented using two spaces. If you just want a minified JSON string, you can change it to JSON.stringify(pairs)
, omitting the other arguments.
This solution should work in all modern browsers, but not IE. I've made it available under the MIT license: serializeJSON.js.
If you need better backwards compatibility, you can use a modified version of my friend Chris Ferdinandi's serializeObject()
helper function instead:
/**
* Serialize all form data into a JSON string
* (c) 2021 Chris Ferdinandi, MIT License, https://gomakethings.com
* @param {HTMLFormElement} form The form to serialize
* @returns {String} The serialized form data
*/
function serializeJSON (form) {
var obj = {};
Array.prototype.slice.call(form.elements).forEach(function (field) {
if (!field.name || field.disabled || ['file', 'reset', 'submit', 'button'].indexOf(field.type) > -1) return;
if (field.type === 'select-multiple') {
var options = [];
Array.prototype.slice.call(field.options).forEach(function (option) {
if (!option.selected) return;
options.push(option.value);
});
if (options.length) {
obj[field.name] = options;
}
return;
}
if (['checkbox', 'radio'].indexOf(field.type) > -1 && !field.checked) return;
obj[field.name] = field.value;
});
return JSON.stringify(obj, null, 2);
}
This solution should work back to IE9. All I've done is rename the function, change it from a function expression to a function declaration, and return a JSON string instead of an object literal. Otherwise, it's Chris' original code.