Convert form data to JavaScript object with jQuery

ID : 596

viewed : 116

Tags : javascriptjqueryjsonserializationjavascript

Top 5 Answer for Convert form data to JavaScript object with jQuery

vote vote

99

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.

vote vote

87

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 {   "honey":{     "badger":"a"   },   "wombat":["b"],   "hello":{     "panda":["c"]   },   "animals":[     {       "name":"d",       "breed":"e"     }   ],   "crazy":[     null,     [       {"wonky":"f"}     ]   ],   "dream":{     "as":{       "vividly":{         "as":{           "you":{             "can":"g"           }         }       }     }   } } 

Usage

$('#my-form').serializeObject(); 

The Sorcery (JavaScript)

(function($){     $.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_]+$/             };           this.build = 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             if(!patterns.validate.test(this.name)){                 return;             }              var k,                 keys = this.name.match(patterns.key),                 merge = this.value,                 reverse_key = this.name;              while((k = keys.pop()) !== undefined){                  // Adjust reverse_key                 reverse_key = reverse_key.replace(new RegExp("\\[" + k + "\\]$"), '');                  // Push                 if(k.match(patterns.push)){                     merge = self.build([], self.push_counter(reverse_key), merge);                 }                  // Fixed                 else if(k.match(patterns.fixed)){                     merge = self.build([], k, merge);                 }                  // Named                 else if(k.match(patterns.named)){                     merge = self.build({}, k, merge);                 }             }              json = $.extend(true, json, merge);         });          return json;     }; })(jQuery); 
vote vote

80

What's wrong with:

var data = {}; $(".form-selector").serializeArray().map(function(x){data[x.name] = x.value;});  
vote vote

63

A fixed version of Tobias Cohen's solution. This one correctly handles falsy values like 0 and ''.

jQuery.fn.serializeObject = function() {   var arrayData, objectData;   arrayData = this.serializeArray();   objectData = {};    $.each(arrayData, function() {     var value;      if (this.value != null) {       value = this.value;     } else {       value = '';     }      if (objectData[this.name] != null) {       if (!objectData[this.name].push) {         objectData[this.name] = [objectData[this.name]];       }        objectData[this.name].push(value);     } else {       objectData[this.name] = value;     }   });    return objectData; }; 

And a CoffeeScript version for your coding convenience:

jQuery.fn.serializeObject = ->   arrayData = @serializeArray()   objectData = {}    $.each arrayData, ->     if @value?       value = @value     else       value = ''      if objectData[@name]?       unless objectData[@name].push         objectData[@name] = [objectData[@name]]        objectData[@name].push value     else       objectData[@name] = value    return objectData 
vote vote

57

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

$('#formid').serializeArray()     .reduce(function(a, x) { a[x.name] = x.value; return a; }, {}); 

This is similar to the answer using Array.prototype.map, 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).

Top 3 video Explaining Convert form data to JavaScript object with jQuery

Related QUESTION?