2010-12-03 6 views
5

Gebäude auf die $.fn.serializeObject() Funktion von this question von Serialisierung möchte Ich mag Lage sein, „Punktnotation“ in meiner Form Namen zu unterstützen, etwa so:Sonderfall Form zu einem Javascript-Objekt

<form> 
    <input name="Property.Items[0].Text" value="item 1" /> 
    <input name="Property.Items[0].Value" value="1" /> 
    <input name="Property.Items[1].Text" value="item 2" /> 
    <input name="Property.Items[1].Value" value="2" /> 
</form> 

gegeben, dass $('form').serializeArray() erzeugt folgendes:

{Property: {Items: [{Text: 'item 1', Value: '1'}, 
        {Text: 'item 2', Value: '2'}]} } 
:

[{"name":"Property.Items[0].Text","value":"item 1"}, 
{"name":"Property.Items[0].Value","value":"1"}, 
{"name":"Property.Items[1].Text","value":"item 2"}, 
{"name":"Property.Items[1].Value","value":"2"}] 

, wie ich das gewünschte Ergebnis unter erreichen könnte

jede Hilfe wäre willkommen.

EDIT: um spezifisch zu sein, würde der gewünschte Code der serializeObject Erweiterung hinzugefügt werden, so dass zusätzlich zu der Art, wie es jetzt funktioniert, würde es auch die obige Konvention unterstützen. hier ist die vorhandene Methode für die Bequemlichkeit.

$.fn.serializeObject = function() { 
    var o = {}; 
    var a = this.serializeArray(); 
    $.each(a, function() { 
     if (o[this.name]) { 
      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; 
}; 

EDIT 2: off Fütterung der Antwort zur Verfügung gestellt, hier ist meine aktuelle Implementierung:

$.fn.serializeObject = function() { 
    var o = {}; 
    var a = this.serializeArray(); 
    var regArray = /^([^\[\]]+)\[(\d+)\]$/; 

    $.each(a, function(i) { 
     var name = this.name; 
     var value = this.value; 

     // let's also allow for "dot notation" in the input names 
     var props = name.split('.'); 
     var position = o; 
     while (props.length) { 
      var key = props.shift(); 
      var matches; 
      if (matches = regArray.exec(key)) { 
       var p = matches[1]; 
       var n = matches[2]; 
       if (!position[p]) position[p] = []; 
       if (!position[p][n]) position[p][n] = {}; 
       position = position[p][n]; 
      } else { 
       if (!props.length) { 
        if (!position[key]) position[key] = value || ''; 
        else if (position[key]) { 
         if (!position[key].push) position[key] = [position[key]]; 
         position[key].push(value || ''); 
        } 
       } else { 
        if (!position[key]) position[key] = {}; 
        position = position[key]; 
       } 
      } 
     } 
    }); 
    return o; 
}; 

Sie es in Aktion sehen können here

+0

Schön, 2 Dinge. Es ist nicht nötig, $ zu verwenden. Hier ist es nur Overhead. Eine reguläre For-Schleife wird es tun. 2. Deklarieren Sie 'var' nicht in einer Schleife (for, while). In Javascript ist das erneute Zuweisen einer Var viel schneller, als jedes Mal eine neue 'var' zu deklarieren. Setzen Sie also 'var' außerhalb der Loops. – fredrik

+0

@Omer, was überprüft Ihr/^ ([^ \ [\]]) \ [(\ d +) \] $/Ausdruck genau? – R4nc1d

Antwort

4

Diese Lösung ein bisschen statisch ist. Aber es sollte den Trick tun:

var serialized = $.fn.serializeObject(), 
      properties = {}, 
      property = [], 
      position = {}, 
      key = '', 
      n = 0, 
      matchName = '', 
      i = 0; 

     for (i = 0; i < serialized.length; i += 1) { 
      property = serialized[i].name.split('.'); 
      position = properties; 
      while (property.length) { 
       key = property.shift(); 
       if (key.match(/\[\d+\]/) && key.match(/\[\d+\]/).join().match(/\d+/g)) { 
        matchName = key.match(/\w+/)[0] 
        n = parseInt(key.match(/\[\d+\]/).join().match(/\d+/g), 10); 
        if (!position[matchName]) { 
         position[matchName] = []; 
        } 

        if (!position[matchName][n]) { 
         position[matchName][n] = {} 
        } 

        position = position[matchName][n] 
       } else { 
        if (!property.length) { 
         position[key] = serialized[i].value 
        } else { 
         if (!position[key]) { 
          position[key] = {}; 
         } 
         position = position[key] 
        } 
       } 

      } 
     } 

     console.log(properties); 
+0

+1 danke. Es scheint zu funktionieren, nachdem $ .fn.serializeObject() in $() geändert wurde. serializeArray(). wird genauer testen und nachverfolgen. –

+0

Ich konnte deine Antwort verbessern ... schau es dir in der Post an. Danke noch einmal. –