I have a form on my site like this:
<form id="myform" action="" method="">
<input type="text" name="name[1][first]">
<input type="text" name="name[2][first]">
<input type="text" name="name[3][first]">
</form>
I want to simply grab all the data and send it to a webservice so have this js:
$fields = $('#myform').serializeArray();
Problem is, it creates the json with all the brackets shown in the input names so I get a parse error.
How can I use serializeArray and get proper json?
The resulting format that I would like to see is something like this:
{
"name": {
"1": {
"first": "val1"
},
"2": {
"first": "val2"
},
"3": {
"first": "val3"
}
}
}
Thanks!
jQuery serializeArray() Method The serializeArray() method creates an array of objects (name and value) by serializing form values. You can select one or more form elements (like input and/or text area), or the form element itself.
To get value from serialized array, use th serializeArray( ) method. The serializeArray( ) method serializes all forms and form elements like the . serialize() method but returns a JSON data structure for you to work with.
Answer: Use the jQuery submit() Method.
You can do this: var frm = $(document. myform); var data = JSON. stringify(frm.
I made a recursive function/plugin to do exactly this:
$.fn.serializeControls = function() {
var data = {};
function buildInputObject(arr, val) {
if (arr.length < 1)
return val;
var objkey = arr[0];
if (objkey.slice(-1) == "]") {
objkey = objkey.slice(0,-1);
}
var result = {};
if (arr.length == 1){
result[objkey] = val;
} else {
arr.shift();
var nestedVal = buildInputObject(arr,val);
result[objkey] = nestedVal;
}
return result;
}
$.each(this.serializeArray(), function() {
var val = this.value;
var c = this.name.split("[");
var a = buildInputObject(c, val);
$.extend(true, data, a);
});
return data;
}
$("#output").html(JSON.stringify($('#myform').serializeControls(), null, 2));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form id="myform" action="" method="">
<input type="text" name="name[1][first]" value="beep">
<input type="text" name="name[1][second]" value="bloop">
<input type="text" name="name[2][first]" value="derp">
<input type="text" name="foo" value="bar">
</form>
<pre id="output">
</pre>
You can also call it on other selectors besides the entire form
. For example, calling:
$('input[name^="name\\["]').serializeControls()
will return an object containing only the name
fields. See http://codepen.io/alexweissman/pen/MyWZdN for more examples.
Please note that (for now), this will not work for field names with empty brackets (for example, fields like input name="potatoes[]"
will be ignored because a unique key cannot be extracted).
Here is a version of alexw code that works for field names with empty brackets. This allow you to manage fields with multiple values (checkboxes, select multiple).
$j.fn.serializeObject = function() {
var data = {};
function buildInputObject(arr, val) {
if (arr.length < 1) {
return val;
}
var objkey = arr[0];
if (objkey.slice(-1) == "]") {
objkey = objkey.slice(0,-1);
}
var result = {};
if (arr.length == 1){
result[objkey] = val;
} else {
arr.shift();
var nestedVal = buildInputObject(arr,val);
result[objkey] = nestedVal;
}
return result;
}
function gatherMultipleValues( that ) {
var final_array = [];
$j.each(that.serializeArray(), function( key, field ) {
// Copy normal fields to final array without changes
if( field.name.indexOf('[]') < 0 ){
final_array.push( field );
return true; // That's it, jump to next iteration
}
// Remove "[]" from the field name
var field_name = field.name.split('[]')[0];
// Add the field value in its array of values
var has_value = false;
$j.each( final_array, function( final_key, final_field ){
if( final_field.name === field_name ) {
has_value = true;
final_array[ final_key ][ 'value' ].push( field.value );
}
});
// If it doesn't exist yet, create the field's array of values
if( ! has_value ) {
final_array.push( { 'name': field_name, 'value': [ field.value ] } );
}
});
return final_array;
}
// Manage fields allowing multiple values first (they contain "[]" in their name)
var final_array = gatherMultipleValues( this );
// Then, create the object
$j.each(final_array, function() {
var val = this.value;
var c = this.name.split('[');
var a = buildInputObject(c, val);
$j.extend(true, data, a);
});
return data;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With