By Yisroel

2009-07-26 13:39:54 8 Comments

How do I convert all elements of my form to a JavaScript object?

I'd like to have some way of automatically building a JavaScript object from my form, without having to loop over each element. I do not want a string, as returned by $('#formid').serialize();, nor do I want the map returned by $('#formid').serializeArray();


@Bhavik Hirani 2016-08-31 11:35:36

I checked that there is a problem with all the other answers, that if the input name is as an array, such as name[key], then it should be generated like this:

name:{ key : value }

For example: If you have an HTML form similar to the one below:

    <input name="name" value="value" >
    <input name="name1[key1]" value="value1" >
    <input name="name2[key2]" value="value2" >
    <input name="name3[key3]" value="value3" >

But it should be generated just like the JSON below, and does not become an object like the following with all the other answers. So if anyone wants to bring something like the following JSON, try the JS code below.

    name  : 'value',
    name1 : { key1 : 'value1' },
    name2 : { key2 : 'value2' },
    name3 : { key2 : 'value2' }

$.fn.getForm2obj = function() {
  var _ = {};
  $.map(this.serializeArray(), function(n) {
    const keys =[a-zA-Z0-9_]+|(?=\[\])/g);
    if (keys.length > 1) {
      let tmp = _;
      pop = keys.pop();
      for (let i = 0; i < keys.length, j = keys[i]; i++) {
        tmp[j] = (!tmp[j] ? (pop == '') ? [] : {} : tmp[j]), tmp = tmp[j];
      if (pop == '') tmp = (!Array.isArray(tmp) ? [] : tmp), tmp.push(n.value);
      else tmp[pop] = n.value;
    } else _[keys.pop()] = n.value;
  return _;
$('form input').change(function() {
<script src=""></script>
  <input name="name" value="value">
  <input type="checkbox" name="name1[]" value="1" checked="checked">1
  <input type="checkbox" name="name1[]" value="2">2
  <input type="checkbox" name="name1[]" value="3">3<br>
  <input type="radio" name="gender" value="male" checked="checked">male
  <input type="radio" name="gender" value="female"> female
  <input name="name2[key1]" value="value1">
  <input name="one[another][another_one]" value="value4">
  <input name="name3[1][name]" value="value4">
  <input name="name3[2][name]" value="value4">
  <input name="[]" value="value5">

@Leonardo Beal 2018-02-14 16:06:39

This answer does cover the case mentioned, but it does not cover cases like checkbox[] or even one[another][another_one]

@Bhavik Hirani 2018-02-27 19:30:28

@LeonardoBeal i fix my ans .. check this now ..!

@Jack Giffin 2019-07-31 21:04:09

I am the downvoter and I downvoted because eval should not be used in this way because eval, when used in this way, promotes terribly unreliable, buggy, illperformant, and potentially unsecure practices.

@iRaS 2019-11-27 09:11:55

I can't agree this is a good answer. And please when you write answers make your code self-explanatory or explain it. this.c = function(k,v){ eval("c = typeof "+k+";"); if(c == 'undefined') _t.b(k,v);} is short und not explanatory. A dev with less experience will just copy this without understanding why and how it works.

@Bhavik Hirani 2020-05-25 17:02:19

@JackGiffin Check out my new code now because I've removed eval() from my code.

@Jack Giffin 2020-05-25 20:38:27

@BhavikHirani Thank you for removing useless uses of eval. I have changed my downvote into an upvote.

@aret 2020-05-14 16:37:33

[UPDATE 2020]

With a simple oneliner in vanilla js:

Object.fromEntries(new FormData(form))

@Arik 2020-02-24 08:03:23

Taking advantage of ES6 goodness in a one liner:

$("form").serializeArray().reduce((o, {name: n, value: v}) => Object.assign(o, { [n]: v }), {});

@Zaz 2019-12-02 19:07:57

Here's a one-liner using reduce. Reduce is a functional function that takes the return value of the passed function and passes it back to the passed function in the next iteration, along with the nth value from the list.

$('#formid').serializeArray().reduce((o,p) => ({...o, []: p.value}))

We have to use a few of tricks to get this to work:

  • ...o (spread syntax) inserts all the key: value pairs from o
  • Wrap the object we are returning in () to distinguish it from the {} that denote a function
  • Wrap the key ( in []

@Paflow 2020-02-25 10:57:46

I get wrong result if I don't add a init-object to that function: $('form').serializeArray().reduce((o, p) => ({...o, []: p.value}), {})

@maček 2011-12-06 22:25:15

Convert forms to JSON like a boss

The current source is on GitHub and Bower.

$ bower install jquery-serialize-object

The following code is now deprecated.

The following code can take work with all sorts of input names; and handle them just as you'd expect.

For example:

<!-- All of these will work! -->
<input name="honey[badger]" value="a">
<input name="wombat[]" value="b">
<input name="hello[panda][]" value="c">
<input name="animals[0][name]" value="d">
<input name="animals[0][breed]" value="e">
<input name="crazy[1][][wonky]" value="f">
<input name="dream[as][vividly][as][you][can]" value="g">
// Output



The Sorcery (JavaScript)

    $.fn.serializeObject = function(){

        var self = this,
            json = {},
            push_counters = {},
            patterns = {
                "validate": /^[a-zA-Z][a-zA-Z0-9_]*(?:\[(?:\d*|[a-zA-Z0-9_]+)\])*$/,
                "key":      /[a-zA-Z0-9_]+|(?=\[\])/g,
                "push":     /^$/,
                "fixed":    /^\d+$/,
                "named":    /^[a-zA-Z0-9_]+$/
 = function(base, key, value){
            base[key] = value;
            return base;

        this.push_counter = function(key){
            if(push_counters[key] === undefined){
                push_counters[key] = 0;
            return push_counters[key]++;

        $.each($(this).serializeArray(), function(){

            // Skip invalid keys

            var k,
                keys =,
                merge = this.value,
                reverse_key =;

            while((k = keys.pop()) !== undefined){

                // Adjust reverse_key
                reverse_key = reverse_key.replace(new RegExp("\\[" + k + "\\]$"), '');

                // Push
                    merge =[], self.push_counter(reverse_key), merge);

                // Fixed
                else if(k.match(patterns.fixed)){
                    merge =[], k, merge);

                // Named
                else if(k.match(patterns.named)){
                    merge ={}, k, merge);

            json = $.extend(true, json, merge);

        return json;

@frontendbeauty 2011-12-29 00:44:02

So, that works pretty well. But it's misnamed: it doesn't return JSON, as the name implies. Instead, it returns an object literal. Also, it's important to check for hasOwnProperty, otherwise your arrays have anything that's attached to their prototype, like: {numbers: ["1", "3", indexOf: function(){...}]}

@julien_c 2012-03-13 17:07:19

@frontendbeauty It would be very cool if you be a little more explicit or even do a pull request on Github for this (I'm not sure what you mean with the hasOwnProperty remark)

@frontendbeauty 2012-03-14 20:45:48

@julien_c re: hasOwnProperty, check out the docs on MDN

@Ryan Florence 2012-05-23 17:21:16

@frontendbeauty actually, toJSON is exactly what the spec says it should be called: an unfortunate misnomer.

@maček 2012-12-20 19:27:00

@frontendbeauty, I never understood your comment. This is using jQuery's .serializeArray() so it's just constructing a new object with key/value pairs; nothing else.

@Marek 2013-01-31 13:03:38

Unfortunately it doesn't work well for <select> with multiple - returns only first selected option value as string instead of array with all selected options.

@maček 2013-01-31 18:14:05

@Marek, I did a test for here on jsfiddle. The trick is to name your select properly. <select name="foo" multiple="multiple"> will not work in any scenario. However, if you use [], as in <select name="bar[]" multiple="multiple">, it will work just fine :)

@rix 2013-09-05 13:15:47

Hi, I made a fiddle using select boxes and can't get this to work -

@Ivan Hušnjak 2013-09-06 22:31:27

@rix it does not work because jsfiddle refuses to load jquery plugin due to "its MIME type ('text/plain') is not executable, and strict MIME type checking is enabled" I have copied the JS source of jquery plugin which is above in this answer. here is updated demo:

@maček 2013-09-09 03:15:45

I didn't realize he left a comment on this answer too. Anyone following @rix's (invalid) bug, please see the github issue

@Șerban Ghiță 2013-09-26 22:22:41

Wanted to point out that is a similar JavaScript method (no 3rd party libraries needed) that does the same job. Supports 'multiple', ignores 'disabled' elements.

@SquareCat 2014-02-23 00:34:46

This solution should be on top as it deals with the problem of nested keys as form element names.

@Michael Moser 2014-03-06 22:42:15

I agree that this is the more robust solution. If you have more than just a flat set of data you will need this solution. In my case, I have arrays of sub types (e.g. Reservations have an array of Payments). This solutions returned an array of subdocuments called Payments with each payment attribute. Love it!

@SquareCat 2014-03-09 23:00:12

Today i had a problem with multiple-select fields. If they were empty (=no selection) no value would get sent to the server (this is correct behaviour!), thus the server would not recognize that the selection was (more or less) reset to nothing. So if anyone runs into this problem: i solved it by adding a hidden form field before each multiple-select, with the same name. Therefore if no value is selected in the multiple-select, an empty value with the same form field name is sent to the server and there you can deal with the thing accordingly.

@SquareCat 2014-03-25 22:00:17

I ran into another issue with the function today. I think that i may have found a leak. Author, could you please explain why: happens?

@maček 2014-03-25 23:45:12

@SquareCat, If you're referring to the [null,null,...,null,1], this is not a leak. Please see this issue. Also, please update the version of the plugin you're using. I can only afford to support the current version.

@BlackjacketMack 2015-09-24 12:54:10

How can I use brackets for arrays and dots for properties? Example of form names: <input name='people[0].first' value='Bill', people[0].last='Henderson' /> <input name='people[1].first' value='Jane', people[1].last='Henderson' /> needs to become: {people:[{'first':'Bill','last':'Henderson'},{'first':'Jane'‌​,'last':'Henderson'}‌​]}...This is the way the default model binder in mvc works (and the output is nice and transparent too).

@maček 2015-09-28 04:52:07

@BlackjacketMack all support for this project has moved to Github. Please read the readme.

@LINKeRxUA 2015-12-23 06:51:19

thank you so much. best solution what i have ever seen for multidimensional forms!

@GetFree 2016-08-04 08:55:15

@frontendbeauty, it doesn't return an object literal. That's misunderstanding the concept of a literal. It just returns an object.

@Thomas Cheng 2016-08-11 19:16:38

I have this input: <input name="vehicle[]" value="0"> <input name="vehicle[]" value="1"> <input name="vehicle[]" value="2"> <input name="vehicle[]" value="3"> <input name="vehicle[3]" value="4"> <input name="vehicle[2]" value="5"> <input name="vehicle[]" value="6"> <input name="vehicle[rt]" value="7"> Natively, in PHP I see: "vehicle" => array:6 [▼ 0 => "0" 1 => "1" 2 => "5" 3 => "4" 4 => "6" "rt" => "7" ] Use AJAX and your method, in PHP I see: "vehicle" => array:1 [ "rt" => "7" ] Behavior is not same, specific to PHP?

@Ultimater 2018-11-01 04:34:21

Please explain what "The following code is now deprecated." means. In favor of what?

@Codewise 2019-03-16 15:31:08

Yes, if this is deprecated what is the preferred solution?

@Tushar Saxena 2019-10-24 08:48:50

I dont know why this answer is not on the top. Works like a champ.

@LP13 2020-05-16 06:36:30

This solution does not work. if you have input elements named, for example,World.Countries[0], World.Countries[1],World.Countries[2],World.Countries[3] then it does not create proper object

@LP13 2020-05-16 06:50:22

does not work example

@ShQ 2019-09-03 09:38:50

Javascript / jQuery one-liner-ish - which works on older versions too (pre ES6):

$('form').serializeArray().reduce((f,c) => {f[c['name']]=(f[c['name']])?[].concat(f[c['name']],c['value']):c['value']; return f}, {} );

@sites 2015-06-13 21:31:23

From some older answer:

$('form input, form select').toArray().reduce(function(m,e){m[] = $(e).val(); return m;},{})

@dvtan 2016-05-27 01:12:34

From what I can tell, the difference is that your solution does not depend on serializeArray so you have the freedom to choose whatever inputs you want (eg. you can include disabled inputs), right? I.e. this is not coupled to any form or the submit event, it's just independent by itself?

@sites 2016-05-27 15:09:34

the only small difference with linked answer is that there is no data needed to instantiate, reduce returns the object. This is not independent since toArray is from jQuery.

@Stonetip 2018-05-24 20:42:50

const formData = new FormData(form);

let formDataJSON = {};

for (const [key, value] of formData.entries()) {

    formDataJSON[key] = value;

@test30 2017-10-20 16:08:48

Another answer

document.addEventListener("DOMContentLoaded", function() {
  setInterval(function() {
    var form = document.getElementById('form') || document.querySelector('form[name="userprofile"]');
    var json = Array.from(new FormData(form)).map(function(e,i) {this[e[0]]=e[1]; return this;}.bind({}))[0];
    document.querySelector('#asJSON').value = JSON.stringify(json);
  }, 1000);
<form name="userprofile" id="form">
  <p>Name <input type="text" name="firstname" value="John"/></p>
  <p>Family name <input name="lastname" value="Smith"/></p>
  <p>Work <input name="employment[name]" value="inc, Inc."/></p>
  <p>Works since <input name="employment[since]" value="2017" /></p>
  <p>Photo <input type="file" /></p>
  <p>Send <input type="submit" /></p>

JSON: <textarea id="asJSON"></textarea>


@user3658510 2018-03-22 13:33:23

A more modern way is to use reduce with serializeArray() in this way:

    .reduce((a, x) => ({ ...a, []: x.value }), {});

It will help for many of the 'normal' cases.

For the very common instance where there are multiple tags with duplicate name attributes, this is not enough.

Since inputs with duplicate name attributes are normally inside some 'wrapper' (div, ul, tr, ...), like in this exemple:

  <div class="wrapperClass">
    <input type="text" name="one">
    <input type="text" name="two">
  <div class="wrapperClass">
    <input type="text" name="one">
    <input type="text" name="two">

one can use reduce with the map operator to iterate on them:

$(".wrapperClass").map(function () {
  return $(this).find('*').serializeArray()
    .reduce((a, x) => ({ ...a, []: x.value }), {});

The result will be an array of objects in the format:

      one: valueOfOne,
      two: valueOfTwo
    }, {
      one: valueOfOne,
      two: valueOfTwo

The .get() operator is used in conjunction with map to get the basic array instead of the jQuery object which gives a cleaner result. jQuery docs

@test30 2017-10-16 11:35:57

One-liner (no dependencies other than jQuery), uses fixed object binding for function passsed to map method.

$('form').serializeArray().map(function(x){this[] = x.value; return this;}.bind({}))[0]

What it does?

"id=2&value=1&comment=ok" => Object { id: "2", value: "1", comment: "ok" }

suitable for progressive web apps (one can easily support both regular form submit action as well as ajax requests)

@Folkmann 2017-10-08 13:59:47

So I used the accepted answer and found a major flaw.
It doesn't support input arrays like:

<input type="checkbox" name="array[]" value="1"/>
<input type="checkbox" name="array[]" value="2"/>
<input type="checkbox" name="array[]" value="3"/>

This minor change should fix that:

function objectifyForm(inp){
    var rObject = {};
    for (var i = 0; i < inp.length; i++){
        if(inp[i]['name'].substr(inp[i]['name'].length - 2) == "[]"){
            var tmp = inp[i]['name'].substr(0, inp[i]['name'].length-2);
            } else{
                rObject[tmp] = [];
        } else{
            rObject[inp[i]['name']] = inp[i]['value'];
    return rObject;

Remember to pass it the output from $(this).serializeArray(); otherwise it wont work.

@Tobias Cohen 2009-07-27 03:38:41

serializeArray already does exactly that. You just need to massage the data into your required format:

function objectifyForm(formArray) {//serialize data function

  var returnArray = {};
  for (var i = 0; i < formArray.length; i++){
    returnArray[formArray[i]['name']] = formArray[i]['value'];
  return returnArray;

Watch out for hidden fields which have the same name as real inputs as they will get overwritten.

@Yisroel 2009-07-27 16:15:05

as tvanfosson says, why iterate over the collection twice?

@Tobias Cohen 2009-07-28 03:05:06

Do you mean "why use serializeArray to get the data in the first place?" Because serializeArray is already written, is unit tested in multiple browsers, and could theoretically be improved in later versions of jQuery. The less code you write that has to access inconsistent things like DOM elements directly, the more stable your code will be.

@Matt Gardner 2009-08-18 21:52:22

Thanks Tobias, was looking for a best practice.

@Samuel Meacham 2010-07-18 23:54:44

Be warned, serializeArray() will not include disabled elements. I often disable input elements that are sync'd to other elements on the page, but I still want them included in my serialized object. You're better off using something like $.map( $("#container :input"), function(n, i) { /* and $(n).val() */ } ); if you need to include disabled elements.

@Morteza Milani 2010-09-15 01:26:43

I think you need to add this to your code just after each statement:<pre>'[]','');</pre> if not, then there would be error in parsing JSON.

@James McCormack 2010-12-23 12:32:57

serializeObject() is half the solution - the other half is the Crockford JSON lib. Full solution is therefore: JSON.stringify($('myForm').serializeObject())

@Andrew B. 2011-02-22 05:04:48

Samuel Meacham, you may want to use readonly elements instead of disabled ones.

@Frank Nocke 2011-04-05 10:22:19

The $.toJson in your referenced example does not exist (any more). Also even in your sample the inner expression does not catch all form elements (e.g. checkboxes status, ...).

@Daniel X Moore 2011-04-06 20:06:10

This solution contains a bug where "falsy" values such as 0, '', and false won't be serialized correctly. I have posted a fixed solution.

@Shamaila Tahir 2011-10-02 09:11:59

Plugin by Ben Alman can also be used:

@Alexey Zakharov 2011-10-26 07:30:49

This doesn't work for general case. It produce invalid results for name="model[property_name]". It also doesn't handle nested properties. name="model[prop_1][prop_2]". So it should not considered as answer.

@maček 2011-12-06 21:57:24

This is so rigid, it's mind-blowing that it ever received more than a couple upvotes.

@Tobias Cohen 2011-12-07 04:33:04

@macek Is there something specific about it that you've found problematic? I wrote this code in about 5 minutes to answer the question as asked, and it seems to have worked fine for the OP, as well as for many others.

@maček 2011-12-07 20:13:45

@TobiasCohen It doesn't handle foo[bar]-type inputs as expected, not to mention most of the other input name varieties. After being very frustrated with shallow solutions to this problem, I ended up writing my own jQuery plugin -- details in the answer I provided to this question.

@Tobias Cohen 2011-12-08 00:47:19

@macek I think you might be looking for an answer to a different question. foo[bar] style input naming is common convention in a number of web frameworks, but it's certainly not a standard part of HTML forms, it's not mentioned in the question, and I've made no attempt to deal with it here.

@Kevin Jhangiani 2012-05-19 06:19:10

@macek The foo[bar] type input is a PHP only parsing thing, but I too find it very useful. Using Tobias's great solution above, I modified it to correctly handle the foo[bar] case. I just whipped this up in about 5 minutes so I'm sure it can be made a lot neater. Okay, it seems I can't post it in a comment, so see my answer below

@maček 2012-05-22 03:35:54

@TobiasCohen, I understand not wanting to support it, but saying it's "not a standard part of HTML forms" is neither correct or a valid counter point. An input named foo[bar] is certainly valid; atop that, adding support for the intended functionality results in a more robust and flexible solution.

@Tobias Cohen 2012-05-22 07:44:29

@macek Could you show me where in the HTML spec it says that inputs named in this format should be treated specially?

@maček 2012-05-22 18:34:13

@TobiasCohen, I never said the HTML spec says they should be treated specially. I was simply arguing that foo[bar]-type names are completely valid and [] is commonly understood to be an array accessor; why not handle them as such? Or to pose it a bit differently, in what scenario would you name an input foo[bar] and not wish to treat foo as an array?

@kroehre 2012-09-08 08:29:18

@macek I know this is a few months old, but since when did do arrays use non-numeric indexes? No one should name an input foo[bar] and hope to treat it as an array. Are you confusing arrays and hashes? Yes, [] is commonly understood to be an accessor but not just for arrays. Also saying it's valid HTML but not in the HTML spec is a contradiction. Yes, the browser may not choke on it, but not many webservers are going to know how to deserialize that like they would an array. Why? Because its not in the HTML spec. Therefore, it is indeed invalid.

@Tony R 2013-01-15 20:40:03

This is great but it doesn't parse data types. It makes all the values strings. Maybe that should be handled elsewhere but it's a caveat to this snippet. Still, amazingly useful for how simple it is. Thanks!

@nilskp 2013-02-13 14:44:15

@Samuel Meacham, I believe you should be using the readonly attribute, not disabled, if you want to include the inputs on the form submission/serialization.

@destan 2013-04-04 11:39:51

jQuery itself should provide this function in most recent next version, don't you think so?

@dewd 2013-05-28 14:53:49

treats a select with only one option selected as a string. where there is potential for mulitple options and only one is selected, it should be treated as an array. i'm working on something to remedy this.

@tothemario 2014-01-08 03:03:29

The jQuery plugin serializeJSON uses serailizeArray under the hood to serialize complex forms into the same format as Rails params:

@H.M. 2014-04-21 15:19:27

change:case 'checkbox': if (val === 'on' || val === 'checked' || val === true || val === 1) $el.attr('checked', 'checked'); else $el.attr('checked', null);

@Aaron Lozier 2014-06-22 19:01:46

Would like to suggest this improvement: The difference is it handles keys in the input name, e.g. name="test[1]" and preserves these in an object. so rather than: "test[]" : ['val1','val2'] you would have: "test" : { 1 : 'val1', 2 : 'val2' } This worked better for my purposes anyway, passing form values into an underscore template.

@Gustavo Gondim 2014-07-14 13:52:59

Shouldn't this code be added to jQuery? It really needs to be implemented.

@ladieu 2014-07-17 14:19:13

I use this function all the time and it works fantastic. Just wanted to counterpoint all the negative feedback. No bulky plugins, works fast and reliably. Support VALID html so that's all I needed.

@victor 2014-12-30 14:34:13

@TobiasCohen, I know this is quite an old thread, but I updated you function to serialize disabled fields as well. Hope it helps!

@jcarlosweb 2015-01-31 20:10:45

@TobiasCohen and for files the type="file". Is it possible?

@tfmontague 2015-05-30 18:03:47

@TobiasCohen - I think Ben Alman provides a better solution: You also use o[] in multiple places, and that should be cached for faster performance: var oname = o[];

@nima 2015-07-29 22:10:34

If you use jquery to post this object to the server, and you have a multiple select on your form, and the name of your control is 'foo', then jquery will send 'foo' if only one item is selected and 'foo[]' if multiple items are selected. This will be very confusing on the server side.

@Eon 2016-07-19 14:15:01

better than the alternative than to massage an array into a JSON object using string manipulations

@Andrew Day 2017-01-18 14:36:37

@clod986 2017-06-29 17:04:07

Does anyone know if this is still maintained? Should I avoid using it???

@conny 2017-09-08 09:46:39

Modern version of the above: form.serializeArray().reduce(function(acc,cur) { acc[] = cur.value return acc }, {})

@cstuncsik 2018-02-16 08:48:30

const data = $(form).serializeArray().reduce((acc, next) => ({ ...acc, []: next.value }), {})

@Paul Chris Jones 2019-10-04 11:02:45

@conny, your modern version gives me the error "unexpected token: keyword 'return'"

@conny 2019-10-17 09:41:44

@PaulJones you are correct, it must have been due to some copy paste mistake on my side. form.serializeArray().reduce(function(acc,cur) { acc[] = cur.value ; return acc }, {}) should do the job (missing ;).

@LP13 2020-05-15 21:52:31

is there a full proof solution? none of the answers handles all the scenarios. like arrays, deep hierarchy.

@Harini Sekar 2014-04-07 10:40:06

You can do this:

var frm = $(document.myform);
var data = JSON.stringify(frm.serializeArray());


@Ivan Nosov 2016-06-10 09:03:29

using lodash#set

let serialized = [
  { key: 'data[model][id]', value: 1 },
  { key: 'data[model][name]', value: 'product' },
  { key: 'sid', value: 'dh0un1hr4d' }

serialized.reduce(function(res, item) {
  _.set(res, item.key, item.value);
  return res;
}, {});

// returns
  "data": {
    "model": {
      "id": 1,
      "name": "product"
  "sid": "dh0un1hr4d"

@supertrue 2017-04-10 16:17:43

I like this solution, but it doesn't handle form fields in key[] array format; [ {key: 'items[]', value: 1 }, {key: 'items[]', value: 2 } ] results in { items: { "": 2 } }.

@Justin Levene 2016-05-27 10:31:02

Create a map and cycle all fields, saving their values.

var params = {};
    params[this.getAttribute("name")] = this.value;

@ceed 2016-01-01 18:43:08

This function returns all values converted to the right type;

bool/string/(integer/floats) possible

Tho you kinda need jQuery for this, but since serializeArray is jQuery too, so no big deal imho.

 * serialized a form to a json object
 * @usage: $("#myform").jsonSerialize();

(function($) {
    "use strict";
    $.fn.jsonSerialize = function() {
        var json = {};
        var array = $(this).serializeArray();
        $.each(array, function(key, obj) {
            var value = (obj.value == "") ? false : obj.value;
            if(value) {
                // check if we have a number
                var isNum = /^\d+$/.test(value);
                if(isNum) value = parseFloat(value);
                // check if we have a boolean
                var isBool = /^(false|true)+$/.test(value);
                if(isBool) value = (value!=="false");
            json[] = value;
        return json;

@Roey 2015-12-08 09:50:25

the simplest and most accurate way i found for this problem was to use bbq plugin or this one (which is about 0.5K bytes size).

it also works with multi dimensional arrays.

$.fn.serializeObject = function()
	return $.deparam(this.serialize());

@Alf Eaton 2016-04-19 14:36:25

This does seem to work nicely. There's an alternative repository for jquery-deparam that includes description files for bower and npm.

@Max Heiber 2015-07-28 02:18:34

Here's a non-jQuery way:

    var getFormData = function(form) {
        //Ignore the submit button
        var elements =, function(element) {
            var type = element.getAttribute('type');
            return !type || type.toLowerCase() !== 'submit';

You can use it like this:

function() {

    var getFormData = function(form) {
        //Ignore the submit button
        var elements =, function(element) {
            var type = element.getAttribute('type');
            return !type || type.toLowerCase() !== 'submit';

        //Make an object out of the form data: {name: value}
        var data = elements.reduce(function(data, element) {
            data[] = element.value;
            return data;
        }, {});

        return data;

    var post = function(action, data, callback) {
        var request = new XMLHttpRequest();
        request.onload = callback;'post', action);
        request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
        request.send(JSON.stringify(data), true);

    var submit = function(e) {
        var form =;
        var action = form.action;
        var data = getFormData(form);
        //change the third argument in order to do something
        //more intersting with the response than just print it
        post(action, data, console.log.bind(console));

    //change formName below
    document.formName.onsubmit = submit;


@tfmontague 2015-05-31 07:13:53

If you want to convert a form to a javascript object, then the easiest solution (at this time) is to use jQuery's each and serializeArray function-methods.

$.fn.serializeObject = function() {

  var form = {};
  $.each($(this).serializeArray(), function (i, field) {
    form[] = field.value || "";

  return form;

Plugin hosted on GitHub:

Can be installed with Bower:
bower install git://

@Florin Mircea 2014-10-24 10:21:13

I recently had the same problem so I developed a function that allows parsing a form's controls to obtain control id/value and convert that to JSON.

It is flexible enough to allow adding more controls. You just need to specify the control type and the attribute that you want to interpreted as value.

You can find the full script here.

The advantage is that it only takes the data you actually need, without dragging the whole object.

The dissadvantage is that if you have nested options, you need to prefix the IDs accordingly so you can use a duplicate option to its specific group.

I hope this helps!

@Ethan Brown 2015-03-12 01:23:02

I like using Array.prototype.reduce because it's a one-liner, and it doesn't rely on Underscore.js or the like:

    .reduce(function(a, x) { a[] = x.value; return a; }, {});

This is similar to the answer using, but you don't need to clutter up your scope with an additional object variable. One-stop shopping.

IMPORTANT NOTE: Forms with inputs that have duplicate name attributes are valid HTML, and is actually a common approach. Using any of the answers in this thread will be inappropriate in that case (since object keys must be unique).

@gfullam 2015-03-12 14:02:20

This is quite elegant. But it's worth noting that array.prototype.reduce() is not available in IE8 as it is part of the ECMAScript 5 specification. So if you need IE8 support, you'll want to use a polyfill or another solution altogether.

@Ethan Brown 2015-03-12 15:16:33

True, but it's easy enough to polyfill. Also, the IE8 headache is almost over, thanks to Microsoft's great work with IE11 Enterprise Mode -- I no longer cater to individual users with IE8, but when an organization with 10,000 employees that all use IE8 comes along...that's different. Fortunately, Microsoft is working hard on that problem.

@Ethan Brown 2015-03-12 15:19:53

Well you should have your IT folks look into IE11 Enterprise mode -- it provides a modern browser AND a way to run IE8-compatible apps. Smart move on Microsoft's part:…

@Harini Sekar 2014-04-07 10:44:48

If you are sending a form with JSON you must remove [] in sending the string. You can do that with the jQuery function serializeObject():

var frm = $(document.myform);
var data = JSON.stringify(frm.serializeObject());

$.fn.serializeObject = function() {
    var o = {};
    //var a = this.serializeArray();
    $(this).find('input[type="hidden"], input[type="text"], input[type="password"], input[type="checkbox"]:checked, input[type="radio"]:checked, select').each(function() {
        if ($(this).attr('type') == 'hidden') { //If checkbox is checked do not take the hidden field
            var $parent = $(this).parent();
            var $chb = $parent.find('input[type="checkbox"][name="' +\[/g, '\[').replace(/\]/g, '\]') + '"]');
            if ($chb != null) {
                if ($chb.prop('checked')) return;
        if ( === null || === undefined || === '')
        var elemValue = null;
        if ($(this).is('select'))
            elemValue = $(this).find('option:selected').val();
            elemValue = this.value;
        if (o[] !== undefined) {
            if (!o[].push) {
                o[] = [o[]];
            o[].push(elemValue || '');
        else {
            o[] = elemValue || '';
    return o;

@Michael Yagudaev 2014-01-03 00:24:10

There is a plugin to do just that for jQuery, jquery.serializeJSON. I have used it successfully on a few projects now. It works like a charm.

@olleicua 2013-11-12 20:08:05

If you are using Underscore.js you can use the relatively concise:

_.object($('#myform').serializeArray(), _.values))

@G-Ram 2013-10-11 14:04:58

Using maček's solution, I modified it to work with the way ASP.NET MVC handles their nested/complex objects on the same form. All you have to do is modify the validate piece to this:

"validate": /^[a-zA-Z][a-zA-Z0-9_]*((?:\[(?:\d*|[a-zA-Z0-9_]+)\])*(?:\.)[a-zA-Z][a-zA-Z0-9_]*)*$/,

This will match and then correctly map elements with names like:

<input type="text" name="zooName" />


<input type="text" name="zooAnimals[0].name" />

@Adrian Seeley 2013-10-06 15:16:51


function form_to_json (selector) {
  var ary = $(selector).serializeArray();
  var obj = {};
  for (var a = 0; a < ary.length; a++) obj[ary[a].name] = ary[a].value;
  return obj;


{"myfield": "myfield value", "passwordfield": "mypasswordvalue"}

@Niko 2013-10-06 07:53:38

I wrote a jQuery module, jsForm, that can do this bidirectional even for quite complicated forms (allows collections and other more complex structures as well).

It uses the name of the fields (plus a few special classes for collections) and matches a JSON object. It allows automatic replication of DOM-elements for collections and data handling:

        <script src="//"></script>
        <script src=""></script>
            // Some JSON data
            var jsonData = {
                name: "TestName",   // Standard inputs
                description: "long Description\nMultiline", // Textarea
                links: [{href:'',description:'StackOverflow'}, {href:'', description:'GitHub'}],   // Lists
                active: true,   // Checkbox
                state: "VISIBLE"    // Selects (enums)

            // Initialize the form, prefix is optional and defaults to data

            $("#show").click(function() {
                // Show the JSON data
                alert(JSON.stringify($("#details").jsForm("get"), null, " "));
        <h1>Simpel Form Test</h1>
        <div id="details">
            Name: <input name=""/><br/>
            <input type="checkbox" name=""/> active<br/>
            <textarea name="data.description"></textarea><br/>
            <select name="data.state">
                <option value="VISIBLE">visible</option>
                <option value="IMPORTANT">important</option>
                <option value="HIDDEN">hidden</option>
                <ul class="collection" data-field="data.links">
                    <li><span class="field">links.description</span> Link: <input name="links.href"/> <button class="delete">x</button></li>
            <button class="add" data-field="data.links">add a link</button><br/>
            Additional field: <input name="data.addedField"/>
        <button id="show">Show Object</button>

@Șerban Ghiță 2013-10-03 13:55:51

I coded a form to a multidimensional JavaScript object myself to use it in production. The result is

@Chris Baker 2013-12-19 17:35:50

I used a variation of this for a very specific implementation, thanks a lot!

@Șerban Ghiță 2013-12-20 08:50:26

Thanks for letting me know that it's useful. I have some incoming features to roll and this motivates me.

@ngr 2013-04-06 20:43:20

Simplicity is best here. I've used a simple string replace with a regular expression, and they worked like a charm thus far. I am not a regular expression expert, but I bet you can even populate very complex objects.

var values = $(this).serialize(),
attributes = {};

values.replace(/([^&]+)=([^&]*)/g, function (match, name, value) {
    attributes[name] = value;

Related Questions

Sponsored Content

95 Answered Questions

[SOLVED] How can I remove a specific item from an array?

  • 2011-04-23 22:17:18
  • Walker
  • 6685409 View
  • 8266 Score
  • 95 Answer
  • Tags:   javascript arrays

80 Answered Questions

[SOLVED] How can I convert a string to boolean in JavaScript?

  • 2008-11-05 00:13:08
  • Kevin
  • 2004589 View
  • 2543 Score
  • 80 Answer
  • Tags:   javascript

57 Answered Questions

[SOLVED] How do I check if an element is hidden in jQuery?

41 Answered Questions

[SOLVED] How do I loop through or enumerate a JavaScript object?

86 Answered Questions

[SOLVED] How do JavaScript closures work?

42 Answered Questions

[SOLVED] How do I remove a property from a JavaScript object?

3 Answered Questions

48 Answered Questions

[SOLVED] How to check if an object is an array?

27 Answered Questions

[SOLVED] What does "use strict" do in JavaScript, and what is the reasoning behind it?

67 Answered Questions

[SOLVED] What is the most efficient way to deep clone an object in JavaScript?

Sponsored Content