2010-09-09 13 views
19

Ich habe seit Stunden dafür gesucht und habe keine Antwort gefunden. Bitte lesen Sie die ganze Frage vor dem Flammen! :)Serialisieren Sie komplexe Formular zu JSON-Objekt mithilfe von jQuery

Ich habe eine Form ähnlich wie diese:

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

Und müssen in der Lage sein, es zu dieser serialisiert:

{ 
name: 'name value', 

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

ich die meisten Antworten auf SO einschließlich jquery-json versucht haben, Bibliotheken und die meisten von ihnen so etwas wie dies zurück:

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

Das ist etwas Ich kann nicht verwenden! : P

Vielen Dank im Voraus.

Antwort

18

Versuchen Sie diesen Code, den ich für Sie schrieb ... funktioniert gut für mich, nur mit Ihren Daten Ergebnis. Sie können daran arbeiten und ein einfaches jQuery-Plugin erstellen ...

Das Beispiel benötigt JSON.Stringify, um vollständig zu arbeiten.

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

Vielen Dank Juliano! Dies ist die perfekte Lösung! : D –

+0

Funktioniert wie Magie. Hatte eine kleine Änderung daran, um eine Situation zu behandeln, wo Ihre Liste in der Form ist var d = { 'name': 'Name Wert', 'Telefon [0] .type': 'Zelle', 'Telefon [0] .number ':' 000 ', ' Telefon [1] .type ':' home ', ' Telefon [1] .number ':' 111 ', }; Das Ergebnis hat (.) In von der inneren Liste Key, also fügte ich Nach der ersten for-Schleife in der processExpression () Funktion. –

+0

_key_ ist in der Funktion zweimal deklariert. – robsch

1

Mit dieser Struktur glaube ich nicht, dass jede JSON-Bibliothek die ganze Arbeit erledigen kann. Also, ich denke, dass es einfacher ist, unsere eigene Konvertierungsschleife zu schreiben.

Hier ist der Code auf Ihre Serialisierung: http://jsfiddle.net/7MAUv/1/

Die Logik ist ziemlich einfach ist, ist das Geheimnis der eval Strings wie dynamische Befehle auszuführen. Ich habe versucht, es so einfach wie möglich zu machen, fast alle Zeilen kommentiert.

BTW, fühlt sich frei, Fragen zu stellen.

+0

Ihr Code funktioniert perfekt Erick. Vielen Dank für das Posten. Ich werde versuchen und sehen, ob ohne Eval Teil getan werden kann, aber sollte für jetzt fantastisch sein. –

2

Das ist für mich sehr gut funktioniert. Dies benötigt nicht die form2js-Bibliothek.

$.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; 
    }; 

Um die Formulardaten zu serialisieren, habe ich diesen Code dann verwendet.

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

Wenn Sie irgendwelche Zweifel haben, zögern Sie nicht, einen Kommentar hinzuzufügen.

+0

Wie sieht Ihre Form aus, damit dies funktioniert? – trebor

0

Es ist nicht genau das, was Sie gefragt, aber wenn Sie jQuery-Bibliothek verwenden und Ihre komplexen Form für einen Zweck serialisiert brauchen es in Ajax senden, können Sie etw wie diese

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

Sie verwenden können in $ .post und $ .get auch

nJoy!

0

Eine andere Bibliothek, die dieses Problem löst, ist jquery.serializeJSON von Mario Izquierdo. Es funktioniert und erweitert jQuery.

Verwandte Themen