2010-09-09 22 views
19

He estado buscando horas para esto y no he encontrado una respuesta. ¡Lea toda la pregunta antes de flamear! :)Serializar formulario complejo al objeto JSON utilizando jQuery

que tienen una forma similar a esto:

<form id="sample"> 
<input name="name" type="text" value="name value" /> 

<input name="phone[0][type]" type="text" value="cell" /> 
<input name="phone[0][number]" type="text" value="000" /> 

<input name="phone[1][type]" type="text" value="home" /> 
<input name="phone[1][number]" type="text" value="111" /> 
</form> 

y deben ser capaces de serializarlo a esto:

{ 
name: 'name value', 

phone: [ 
    { 
    type: 'cell', 
    number: '000' 
    }, 
    { 
    type: 'home', 
    number: '111' 
    } 
] 
} 

He probado la mayoría de las respuestas sobre la inclusión de SO-jquery json bibliotecas y la mayoría de ellos vuelven algo como esto:

{ 
'name': 'name value', 
'phone[0][type]': 'cell', 
'phone[0][number]': '000', 
'phone[1][type]': 'home', 
'phone[1][number]': '111', 
} 

esto es algo No puedo usar! : P

Gracias a todos de antemano.

Respuesta

18

Pruebe este código que escribí para usted ... Funciona bien para mí, simplemente usando su resultado de datos. Puede trabajar en ello y crear un plugin de jQuery simple ...

La muestra necesita JSON.stringify para funcionar por completo.

var d = { 
    'name': 'name value', 
    'phone[0][type]': 'cell', 
    'phone[0][number]': '000', 
    'phone[1][type]': 'home', 
    'phone[1][number]': '111', 
}; 

$(document).ready(function(){ 

    arrangeJson(d); 
    alert(JSON.stringify(d)); 
}); 

function arrangeJson(data){ 
    var initMatch = /^([a-z0-9]+?)\[/i; 
    var first = /^\[[a-z0-9]+?\]/i; 
    var isNumber = /^[0-9]$/; 
    var bracers = /[\[\]]/g; 
    var splitter = /\]\[|\[|\]/g; 

    for(var key in data) { 
     if(initMatch.test(key)){ 
      data[key.replace(initMatch,'[$1][')] = data[key]; 
     } 
     else{ 
      data[key.replace(/^(.+)$/,'[$1]')] = data[key]; 
     } 
     delete data[key]; 
    } 


    for (var key in data) { 
     processExpression(data, key, data[key]); 
     delete data[key]; 
    } 

    function processExpression(dataNode, key, value){ 
     var e = key.split(splitter); 
     if(e){ 
      var e2 =[]; 
      for (var i = 0; i < e.length; i++) { 
        if(e[i]!==''){e2.push(e[i]);} 
      } 
      e = e2; 
      if(e.length > 1){ 
       var x = e[0]; 
       var target = dataNode[x]; 
       if(!target){ 
        if(isNumber.test(e[1])){ 
         dataNode[x] = []; 
        } 
        else{ 
         dataNode[x] ={} 
        } 
       } 
       processExpression(dataNode[x], key.replace(first,''), value); 
      } 
      else if(e.length == 1){ 
       dataNode[e[0]] = value; 
      } 
      else{ 
       alert('This should not happen...'); 
      } 
     } 
    } 
} 
+1

Muchas gracias Juliano! ¡Esta es la solución perfecta! : D –

+0

Funciona como magia. Tenía una pequeña modificación para manejar una situación donde su Lista está en el formulario var d = { 'nombre': 'nombre de valor', 'teléfono [0] .tipo': 'celda', 'teléfono [0] .number ':' 000 ', ' phone [1] .type ':' home ', ' phone [1] .number ':' 111 ', }; El resultado tiene (.) Desde la lista interna Clave, así que agregué Después del primer ciclo for en el procesoExpression () función. –

+0

_key_ se ha declarado dos veces en la función. – robsch

1

Con esta estructura, no creo que ninguna biblioteca JSON pueda hacer todo el trabajo. Entonces, creo que es más fácil escribir nuestro propio ciclo de conversión.

Aquí es el código a su serialización: http://jsfiddle.net/7MAUv/1/

La lógica es bastante simple, el secreto es el eval para ejecutar comandos como Cuerdas dinámicas. Traté de hacerlo lo más fácil posible, se comentan casi todas las líneas.

Por cierto, no dude en hacer preguntas.

+0

Su código funciona perfectamente Erick. Muchas gracias por publicarlo. Voy a tratar de ver si se puede hacer sin la parte de evaluación, pero debe ser impresionante por ahora. –

2

Esto funcionó muy bien para mí. Esto no necesita tener la biblioteca form2js.

$.fn.serializeObject = function serializeObject() { 
     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; 
    }; 

Para serializar los datos del formulario, utilicé este código a continuación.

JSON.stringify($(this).serializeObject());//'this' points to the form 

Si tiene alguna duda, no dude en añadir un comentario.

+0

¿Cómo se ve tu formulario para que funcione? – trebor

0

No es exactamente lo que pidieron, pero si usted está usando la biblioteca jQuery y necesita su compleja forma serializada para un propósito de enviarlo en ajax, puede usar algo como esto

ajaxRunning = $.ajax(
    "?"+$('#yourForm').serialize(), 
    { 
     data: { 
      anotherData: 'worksFine', 
      etc: 'still works' 
     }, 
     success: function(result) { 
      doSth(); 
     }, 
     dataType: "json" 
}); 

puede utilizar en $ .post y $ .get también

nJoy!

Cuestiones relacionadas