54

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?

informatik01
  • 16,038
  • 10
  • 74
  • 104
Tarang
  • 75,157
  • 39
  • 215
  • 276

11 Answers11

92
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);

Live demo.

0b10011
  • 18,397
  • 4
  • 65
  • 86
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 11
    This approach won't work if you have a form with checkboxes or radio buttons as they all have the same name attribute. Any ideas on handling that (other than a bunch of conditionals and creating an array manually)? – Hollister Sep 13 '12 at 03:08
  • 1
    this gives an error: `SyntaxError: illegal character` – zygimantus Apr 28 '17 at 07:45
  • 1
    @zygimantus There was an illegal (and non-printing) character before and after `$('form')`, after `serializeArray()` and `})`. I edited them out. – 0b10011 Aug 03 '17 at 21:49
40
$.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;
};
Luka Govedič
  • 646
  • 5
  • 9
31

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();
Wadih M.
  • 12,810
  • 7
  • 47
  • 57
Hollister
  • 3,758
  • 2
  • 20
  • 22
7
new_obj = {}

$.each($(form).serializeArray(), function(i, obj) { new_obj[obj.name] = obj.value })

your data is in new_obj

Erez Rabih
  • 15,562
  • 3
  • 47
  • 64
5

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>
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
3

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;
}
Mr. Mak
  • 837
  • 1
  • 11
  • 25
2

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.

Community
  • 1
  • 1
1

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>
0

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;
};
Tina
  • 89
  • 1
  • 11
0

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"}

Gregory Bologna
  • 270
  • 1
  • 6
  • 20
0

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.

Meddie
  • 571
  • 1
  • 7
  • 22