2010-09-09 9 views
19

Ho cercato ore per questo e non ho trovato risposta. Si prega di leggere tutta la domanda prima di fiammeggiare! :)Serializzare il modulo complesso sull'oggetto JSON utilizzando jQuery

Ho una forma simile a questo:

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

e devono essere in grado di serializzare a questo:

{ 
name: 'name value', 

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

Ho provato la maggior parte delle risposte sul compreso SO jquery-JSON biblioteche e la maggior parte di loro tornano o meno così:

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

questo è qualcosa Non posso usare! : P

Grazie a tutti in anticipo.

risposta

18

Prova questo codice che ho scritto per te ... Funziona bene per me, usando solo i risultati dei tuoi dati. Puoi lavorarci sopra e creare un semplice plugin jQuery ...

L'esempio richiede che JSON.stringify funzioni completamente.

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

Grazie mille Juliano! Questa è la soluzione perfetta! : D –

+0

Funziona come una magia. Ho avuto qualche modifica per gestire una situazione in cui il tuo elenco è nella forma var d = { 'nome': 'nome valore', 'phone [0] .type': 'cell', 'phone [0] .number ':' 000 ', ' phone [1] .type ':' home ', ' phone [1] .number ':' 111 ', }; Il risultato ha (.) In dalla chiave dell'elenco interno, quindi ho aggiunto Dopo il primo ciclo for nel processExpression () funzione. –

+0

_key_ viene dichiarato due volte nella funzione. – robsch

1

Con questa struttura, non credo che nessuna libreria JSON possa fare tutto il lavoro. Quindi, penso che sia più facile scrivere il nostro ciclo di conversione.

Ecco il codice al vostro serializzazione: http://jsfiddle.net/7MAUv/1/

La logica è piuttosto semplice, il segreto è la eval per eseguire stringhe come comandi dinamici. Ho cercato di renderlo il più semplice possibile, quasi tutte le righe sono state commentate.

BTW, si sente libero di fare domande.

+0

Il tuo codice funziona perfettamente con Erick. Grazie mille per averlo pubblicato. Cercherò di vedere se si può fare senza la parte eval ma dovrebbe essere fantastico per ora. –

2

Questo ha funzionato molto bene per me. Questo non ha bisogno di avere la libreria 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; 
    }; 

Per serializzare i dati del modulo, ho utilizzato questo codice quindi.

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

In caso di dubbi, si prega di aggiungere commenti.

+0

Come si presenta il modulo in modo che funzioni? – trebor

0

La sua non è esattamente quello che hai chiesto, ma se si utilizza libreria jQuery e bisogno della vostra forma complessa serializzato per uno scopo di inviarlo in ajax, è possibile utilizzare sth come questo

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

è possibile utilizzare in $ .post e $ .get pure

nJoy!

Problemi correlati