2010-07-18 64 views
35

¿Hay alguna mejor solución para convertir datos de un formulario que ya está serializado por jQuery function serialize(), cuando el formulario contiene múltiples campos de matriz de entrada? Quiero poder convertir los datos del formulario en un objeto JSON para recrear algunas otras tablas informativas. Así que díganme una mejor manera de convertir la cadena serializada en un objeto JSON.Cómo convertir datos jQuery.serialize() al objeto JSON?

<form id='sampleform'> 
    <input name='MyName' type='text' /> // Raf 

    <!--array input fields below--> 
    <input name='friendname[]' type='text' /> // Bily 
    <input name='fiendemail[]' type='text' /> // [email protected] 

    <!--duplicated fields below to add more friends --> 
    <input name='friendname[]' type='text' /> // Andy 
    <input name='fiendemail[]' type='text' /> // [email protected] 

    <input name='friendname[]' type='text' /> // Adam 
    <input name='fiendemail[]' type='text' /> // [email protected] 
</form> 

El método jQuery aplicado para obtener los datos

var MyForm = $("#sampleform").serialize(); 
/** result : MyName=Raf&friendname[]=Billy&fiendemail[][email protected]&friendname[]=Andy&fiendemail[][email protected]&friendname[]=Adam&fiendemail[][email protected] 
*/ 

cómo hago estos datos en un objeto JSON? que debe tener el siguiente ejemplo de datos JSON del formulario anterior.

{ 
    "MyName":"raf", 
    "friendname":[ 
     {"0":"Bily"}, 
     {"1":"Andy"}, 
     {"2":"Adam"} 
    ], 
    "friendemail":[ 
     {"0":"[email protected]"}, 
     {"1":"[email protected]"}, 
     {"2":"[email protected]"} 
    ] 
} 
+1

Técnicamente, así no es como se formateará el objeto JSON en función de su cadena de consulta. Específicamente, los elementos de la matriz no serían objetos con índices, sino solo valores. Dicho esto, si necesita el formato que publicó, probablemente necesite escribir una función personalizada. –

+1

posible duplicado de [Serialize form to JSON with jQuery] (http://stackoverflow.com/questions/1184624/serialize-form-to-json-with-jquery) – SLaks

+0

Gracias Slaks y Jason, sí, estoy de acuerdo en que necesito una función para hacerlo y Slaks lo ha señalado por mí. – Raftalks

Respuesta

12

Recientemente he tenido este problema exacto. Inicialmente, estábamos usando el método serializeArray() de jQuery, pero eso no incluye los elementos del formulario que están deshabilitados. A menudo deshabilitaremos los elementos del formulario que están "sincronizados" con otras fuentes en la página, pero aún necesitamos incluir los datos en nuestro objeto serializado. Así que serializeArray() está fuera. Usamos el selector :input para obtener todos los elementos de entrada (tanto habilitados como deshabilitados) en un contenedor dado, y luego $.map() para crear nuestro objeto.

var inputs = $("#container :input"); 
var obj = $.map(inputs, function(n, i) 
{ 
    var o = {}; 
    o[n.name] = $(n).val(); 
    return o; 
}); 
console.log(obj); 

Tenga en cuenta que para que esto funcione, cada una de sus entradas tendrán un atributo name, que será el nombre de la propiedad del objeto resultante.

Eso es en realidad un poco modificado de lo que usamos. Necesitábamos crear un objeto que fue estructurado como un .NET IDictionary, así que utilizamos la siguiente: (proporciono aquí en caso de que sea útil)

var obj = $.map(inputs, function(n, i) 
{ 
    return { Key: n.name, Value: $(n).val() }; 
}); 
console.log(obj); 

me gusta tanto de estas soluciones, porque son usos simples de la función $.map(), y usted tiene control completo sobre su selector (entonces, qué elementos termina incluyendo en su objeto resultante). Además, no se requiere un complemento adicional. Llanura de jQuery.

+0

lo intentó pero no pareció funcionar. – Raftalks

+0

Acabo de notar que está utilizando 'friendname []' como el nombre de sus elementos de entrada, para capturar una matriz de valores en lugar de un solo valor. No creo que '$ .map()' funcione bien para eso. –

+2

Creo que su función de mapa no es del todo correcta ... está devolviendo un objeto por separado para cada atributo ... ¿no quiere poner todos los atributos en un solo objeto? ... así que declare el objeto fuera de la función, no adentro (y no devuelva nada - use el mapa solo para efectos secundarios) –

5

estoy usando este plugin de jQuery muy poco, que me he extendido desde DocumentCloud:

https://github.com/documentcloud/documentcloud/blob/master/public/javascripts/lib/jquery_extensions.js

Se trata básicamente de dos líneas de código, pero requiere _.js (Underscore.js) , ya que se basa en una función reduce.

$.fn.extend({ 
    serializeJSON: function(exclude) { 
    exclude || (exclude = []); 
    return _.reduce(this.serializeArray(), function(hash, pair) { 
     pair.value && !(pair.name in exclude) && (hash[pair.name] = pair.value); 
     return hash; 
    }, {}); 
    } 
}); 

Extensiones:

  • No serializar un valor de entrada si es nula
  • Se puede excluir algunas entradas pasando un array de nombres de entrada a la exclude argumento i.e. ["password_confirm"]
+0

¡Encantador, hace el trabajo a la perfección! –

2

Usando subrayado & jQuery

var formdata = $("#myform").serializeArray(); 
var data = {}; 
_.each(formdata, function(element){ 
// Return all of the values of the object's properties. 
    var value = _.values(element); 
// name : value 
    data[value[0]] = value[1]; 
}); 
console.log(data); //Example => {name:"alex",lastname:"amador"} 
5

Utilice el complemento jQuery.serializeJSON. Convierte formularios con el mismo formato que el que encontraría en un objeto params Rails, que es muy estándar y está bien probado.

33
var formdata = $("#myform").serializeArray(); 
var data = {}; 
$(formdata).each(function(index, obj){ 
    data[obj.name] = obj.value; 
}); 

simple y rápido;)

+1

Esto no genera un objeto JS jerarquizado – Epoc

+2

@Epoc ¿A qué concepto de jerarquía se refiere? Los datos del formulario son planos. – John

+0

var formdata = $ ("# myform"). SerializeArray(); formdata = JSON.parse (formdata); // agregue esta línea var data = {}; $ (formdata) .each (función (índice, obj) { datos [obj.name] = obj.value; }); –

2

una solución equivalente a Danilo Colasso's, con los pros y los contras de sames .serializeArray() (básicamente se utiliza en lugar de .reduce$.each).

Con poco esfuerzo, permite implementar las funciones adicionales en las respuestas de S.C. sin requerir extensiones.

$(selector).serializeArray() 
    .reduce(function(accum, item) { 
     // This 'if' allows ignoring some values 
     if (-1 === [ 'ignoreThis', 'andThat' ].indexOf(item.name)) { 
      // This allows ignoring NULL values 
      if (item.value !== null) { 
       accum[item.name] = item.value; 
      } 
     } 
     return accum; 
    }, 
    { 
     // By supplying some initial values, we can add defaults 
     // for, say, disabled form controls. 
     preFilledName: preFilledValue, // optional 
     defaultName : defaultValue // optional 
    } 
); 
0
var formdata = $("#myform").serializeArray(); 

var data = {}; 

$(formdata).each(function(index, obj){ 

     if(data[obj.name] === undefined) 
       data[obj.name] = []; 

      data[obj.name].push(obj.value); 

}); 
+1

Si bien este fragmento de código puede resolver la pregunta, [incluyendo una explicación] (// meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) realmente ayuda a mejorar la calidad de su publicación. Recuerde que usted está respondiendo la pregunta a los lectores en el futuro, y es posible que esas personas no sepan los motivos de su sugerencia de código.Por favor, intente no saturar su código con comentarios explicativos, ¡esto reduce la legibilidad tanto del código como de las explicaciones! – kayess

0

creo que hay una gran cantidad de buena respuesta aquí, y me hizo que mi propia función en base a estas respuestas.

function formToJSON(f) { 
    var fd = $(f).serializeArray(); 
    var d = {}; 
    $(fd).each(function() { 
     if (d[this.name] !== undefined){ 
      if (!Array.isArray(d[this.name])) { 
       d[this.name] = [d[this.name]]; 
      } 
      d[this.name].push(this.value); 
     }else{ 
      d[this.name] = this.value; 
     } 
    }); 
    return d; 
} 

//The way to use it : 
$('#myForm').submit(function(){ 
    var datas = formToJSON(this); 
    return false; 
}); 

Bueno déjeme explican básicamente por eso que prefiero esta solución ... Si tiene múltiplos de entrada con el mismo nombre, se almacenará todos los valores de una matriz, pero si no es así, el valor se almacenará directamente como el valor del índice en el JSON ... Aquí es donde es diferente de la respuesta de Danilo Colasso donde el JSON devuelto se basa únicamente de valores de la matriz ...

Así que si usted tiene un formulario con un área de texto llamado contenido y múltiplos autores, esta función volverá a y ou:

{ 
    content : 'This is The Content', 
    authors : 
     [ 
      0: 'me', 
      1: 'you', 
      2: 'him', 
     ] 
}