jQuery serializeArray() key value pairs
JquerySerializationJquery Problem Overview
I'm having a bit of trouble serializing a form
<form>
<input type="text" name="name1" value="value1"/>
<input type="text" name="name2" value="value2"/>
</form>
$(form).serializeArray()
Will return [{name:"name1",value:"value1"},{name:"name2",value:"value2"}]
pairs.
Is it possible to get output in the form
{name1:value1,name2:value2}
So that they are easier to handle?
Jquery Solutions
Solution 1 - Jquery
var result = { };
$.each($('form').serializeArray(), function() {
result[this.name] = this.value;
});
// at this stage the result object will look as expected so you could use it
alert('name1 = ' + result.name1 + ', name2 = ' + result.name2);
Solution 2 - Jquery
$.fn.serializeObject = function () {
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
Solution 3 - Jquery
The accepted answer works great if your form doesn't have checkboxes or radio buttons. Since groups of those all have the same name attribute, you need to create an array value inside the object. So for html like:
<input type="checkbox" value="1" name="the-checkbox">
<input type="checkbox" value="2" name="the-checkbox">
<input type="checkbox" value="3" name="the-checkbox">
You'll get:
{the-checkbox:['1', '2', '3']}
This bit of code handles everything nicely.
/*!
* jQuery serializeObject - v0.2 - 1/20/2010
* http://benalman.com/projects/jquery-misc-plugins/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
// Whereas .serializeArray() serializes a form into an array, .serializeObject()
// serializes a form into an (arguably more useful) object.
(function($,undefined){
'$:nomunge'; // Used by YUI compressor.
$.fn.serializeObject = function(){
var obj = {};
$.each( this.serializeArray(), function(i,o){
var n = o.name,
v = o.value;
obj[n] = obj[n] === undefined ? v
: $.isArray( obj[n] ) ? obj[n].concat( v )
: [ obj[n], v ];
});
return obj;
};
})(jQuery);
Usage
$(form).serializeObject();
Solution 4 - Jquery
new_obj = {}
$.each($(form).serializeArray(), function(i, obj) { new_obj[obj.name] = obj.value })
your data is in new_obj
Solution 5 - Jquery
You can do this quite simply using .reduce()
and destructuring assignment:
const arr = $('form').serializeArray(); // get the array
const data = arr.reduce((acc, {name, value}) => ({...acc, [name]: value}),{}); // form the object
Example:
$('form').on('submit', function(e) {
e.preventDefault(); // only used for example (so you can see output in console);
const arr = $(this).serializeArray(); // get the array
const data = arr.reduce((acc, {name, value}) => ({...acc, [name]: value}),{}); // form the object
console.log(data);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<input type="text" placeholder="username" name="username"/>
<input type="email" placeholder="email" name="email"/>
<input type="submit" />
</form>
Or even easier with Object.fromEntries()
and .map()
if you can support it:
Example:
$('form').on('submit', function(e) {
e.preventDefault(); // only used for example (so you can see output in console);
const arr = $(this).serializeArray(); // get the array
const data = Object.fromEntries(arr.map(({name, value}) => [name, value]));
console.log(data);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<input type="text" placeholder="username" name="username"/>
<input type="email" placeholder="email" name="email"/>
<input type="submit" />
</form>
Solution 6 - Jquery
You can make a custom function.
var complex = $(form).serialize(); // name1=value1&name2=value2
var json = toSimpleJson(complex); // {"name1":"value1", "name2":"value2"}
function toSimpleJson(serializedData) {
var ar1 = serializedData.split("&");
var json = "{";
for (var i = 0; i<ar1.length; i++) {
var ar2 = ar1[i].split("=");
json += i > 0 ? ", " : "";
json += "\"" + ar2[0] + "\" : ";
json += "\"" + (ar2.length < 2 ? "" : ar2[1]) + "\"";
}
json += "}";
return json;
}
Solution 7 - Jquery
Here is some modernization of Hollister's code.
(function($,undefined){
'$:nomunge'; // Used by YUI compressor.
$.fn.serializeObject = function(){
var obj = {},
names = {};
$.each( this.serializeArray(), function(i,o){
var n = o.name,
v = o.value;
if ( n.includes( '[]' ) ) {
names.n = !names.n ? 1 : names.n+1;
var indx = names.n - 1;
n = n.replace( '[]', '[' + indx + ']' );
}
obj[n] = obj[n] === undefined ? v
: $.isArray( obj[n] ) ? obj[n].concat( v )
: [ obj[n], v ];
});
return obj;
};
})(jQuery);
In case you need field names as myvar[]
for checkboxes.
Solution 8 - Jquery
Here is my solution which supports radio buttons and multi-select.
var data = $('#my_form').serializeArray().reduce(function (newData, item) {
// Treat Arrays
if (item.name.substring(item.name.length - 2) === '[]') {
var key = item.name.substring(0, item.name.length);
if(typeof(newData[key]) === 'undefined') {
newData[key] = [];
}
newData[key].push(item.value);
} else {
newData[item.name] = item.value;
}
return newData;
}, {});
console.log(data);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="my_form">
<select name="muli_select[]" multiple="multiple">
<option value="1" selected>Value 1</option>
<option value="2" selected>Value 2</option>
<option value="3">Value 3 Not selected</option>
</select>
<br>
<input name="my_text" type="hidden" value="Hidden Text"/>
<input name="my_text2" type="text" value="Shown Text"/>
<br>
<input type="radio" name="gender" value="male" checked> Male<br>
<input type="radio" name="gender" value="female"> Female
</form>
Solution 9 - Jquery
Give your form an id(form-id)
var jsoNform = $("#form-id").serializeObject();
jQuery.fn.serializeObject = function () {
var formData = {};
var formArray = this.serializeArray();
for (var i = 0, n = formArray.length; i < n; ++i)
formData[formArray[i].name] = formArray[i].value;
return formData;
};
Solution 10 - Jquery
To get only form inputs where has a value...
var criteria = $(this).find('input, select').filter(function () {
return ((!!this.value) && (!!this.name));
}).serializeArray();
criteria: {name: "LastName", value: "smith"}
Solution 11 - Jquery
I'll add something as well using Nick Parsons' snipped:
(function($,undefined){
$.fn.serializeObject = function(){
return this.serializeArray()
.reduce((acc, {name, value}) => ({...acc, [name]: value}),{});
};
})(jQuery);
Other examples did not allow for overwriting fields with the same name. "serializeArray" takes care of that, Nick's snipped made it work even better.