Convierta datos de formulario a objetos JavaScript con jQuery
¿Cómo convierto todos los elementos de mi formulario en un objeto JavaScript?
Me gustaría tener alguna forma de crear automáticamente un objeto JavaScript a partir de mi formulario, sin tener que recorrer cada elemento. No quiero una cadena, como la devuelta por $('#formid').serialize();
, ni quiero el mapa devuelto por$('#formid').serializeArray();
serializeArray ya hace exactamente eso. Sólo necesita masajear los datos en el formato requerido:
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;
}
Tenga cuidado con los campos ocultos que tienen el mismo nombre que las entradas reales, ya que se sobrescribirán.
Convierte formularios a JSON como un jefe
La fuente actual es mía en GitHub y Bower .
$ bower instala jquery-serialize-objeto
El siguiente código ahora está en desuso .
El siguiente código puede funcionar con todo tipo de nombres de entrada; y manejarlos tal y como era de esperar.
Por ejemplo:
<!-- 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"
}
}
}
}
}
}
Uso
$('#my-form').serializeObject();
La brujería (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);
Qué hay de malo en:
var data = {};
$(".form-selector").serializeArray().map(function(x){data[x.name] = x.value;});
Una versión fija de la solución de Tobias Cohen. Éste maneja correctamente valores falsos como 0
y ''
.
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;
};
Y una versión de CoffeeScript para su comodidad en la codificación:
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
Me gusta usarlo Array.prototype.reduce
porque es de una sola línea y no depende de Underscore.js o similares:
$('#formid').serializeArray()
.reduce(function(a, x) { a[x.name] = x.value; return a; }, {});
Esto es similar a la respuesta usando Array.prototype.map
, pero no necesita saturar su alcance con una variable de objeto adicional. Uno para de comprar.
NOTA IMPORTANTE : Los formularios con entradas que tienen name
atributos duplicados son HTML válido y, en realidad, es un enfoque común. Usar cualquiera de las respuestas en este hilo será inapropiado en ese caso (ya que las claves de objeto deben ser únicas).