1758 Stimmen

Konvertieren von Formulardaten in ein JavaScript-Objekt mit jQuery

Wie kann ich alle Elemente meines Formulars in ein JavaScript-Objekt umwandeln?

Ich möchte eine Möglichkeit haben, automatisch ein JavaScript-Objekt aus meinem Formular zu erstellen, ohne jedes Element in einer Schleife durchlaufen zu müssen. Ich möchte keine Zeichenkette, wie sie von $('#formid').serialize(); noch will ich die Karte, die von $('#formid').serializeArray();

19 Stimmen

Denn die erste gibt eine Zeichenkette zurück, genau wie das, was Sie bekommen würden, wenn Sie das Formular mit einer GET-Methode übermitteln würden, und die zweite gibt Ihnen ein Array von Objekten, jedes mit einem Name-Wert-Paar. Ich möchte, dass ich, wenn ich ein Feld mit dem Namen "email" habe, ein Objekt erhalte, das es mir ermöglicht, diesen Wert mit obj.email abzurufen. Mit serializeArray() müsste ich etwas tun wie obj[indexOfElement].value

1731voto

Tobias Cohen Punkte 19666

serializeArray tut bereits genau das. Sie müssen die Daten nur noch in das von Ihnen gewünschte Format bringen:

function objectifyForm(formArray) {
    //serialize data function
    var returnArray = {};
    for (var i = 0; i < formArray.length; i++){
        returnArray[formArray[i]['name']] = formArray[i]['value'];
    }
    return returnArray;
}

Achten Sie auf ausgeblendete Felder, die denselben Namen haben wie echte Eingaben, da sie überschrieben werden.

71 Stimmen

Meinen Sie "warum serializeArray verwenden, um die Daten überhaupt zu erhalten?" Weil serializeArray bereits geschrieben wurde, in mehreren Browsern getestet wurde und theoretisch in späteren Versionen von jQuery verbessert werden könnte. Je weniger Code Sie schreiben, der auf inkonsistente Dinge wie DOM-Elemente direkt zugreifen muss, desto stabiler wird Ihr Code sein.

61 Stimmen

Seien Sie gewarnt, serializeArray() enthält keine deaktivierten Elemente. Ich deaktiviere oft Eingabeelemente, die mit anderen Elementen auf der Seite synchronisiert sind, aber ich möchte sie trotzdem in mein serialisiertes Objekt aufnehmen. Sie sind besser dran, wenn Sie etwas wie $.map( $("#container :input"), function(n, i) { /* n.name and $(n).val() */ } ); wenn Sie deaktivierte Elemente einbeziehen müssen.

471voto

maček Punkte 72991

Formulare in JSON konvertieren wie ein Chef


Die Stromquelle ist auf GitHub y Laube .

$ bower install jquery-serialize-object


Der folgende Code lautet nun Abgelehnt .

Der folgende Code kann mit allen Arten von Eingaben arbeiten und sie so behandeln, wie Sie es erwarten würden.

Zum Beispiel:

<!-- All of these will work! -->
<input name="honey[badger]" value="a">
<input name="wombat[]" value="b">
<input name="hello[panda][]" value="c">
<input name="animals[0][name]" value="d">
<input name="animals[0][breed]" value="e">
<input name="crazy[1][][wonky]" value="f">
<input name="dream[as][vividly][as][you][can]" value="g">

// Output
{
  "honey":{
    "badger":"a"
  },
  "wombat":["b"],
  "hello":{
    "panda":["c"]
  },
  "animals":[
    {
      "name":"d",
      "breed":"e"
    }
  ],
  "crazy":[
    null,
    [
      {"wonky":"f"}
    ]
  ],
  "dream":{
    "as":{
      "vividly":{
        "as":{
          "you":{
            "can":"g"
          }
        }
      }
    }
  }
}

Verwendung

$('#my-form').serializeObject();

Die Zauberei (JavaScript)

(function($){
    $.fn.serializeObject = function(){

        var self = this,
            json = {},
            push_counters = {},
            patterns = {
                "validate": /^[a-zA-Z][a-zA-Z0-9_]*(?:\[(?:\d*|[a-zA-Z0-9_]+)\])*$/,
                "key":      /[a-zA-Z0-9_]+|(?=\[\])/g,
                "push":     /^$/,
                "fixed":    /^\d+$/,
                "named":    /^[a-zA-Z0-9_]+$/
            };

        this.build = function(base, key, value){
            base[key] = value;
            return base;
        };

        this.push_counter = function(key){
            if(push_counters[key] === undefined){
                push_counters[key] = 0;
            }
            return push_counters[key]++;
        };

        $.each($(this).serializeArray(), function(){

            // Skip invalid keys
            if(!patterns.validate.test(this.name)){
                return;
            }

            var k,
                keys = this.name.match(patterns.key),
                merge = this.value,
                reverse_key = this.name;

            while((k = keys.pop()) !== undefined){

                // Adjust reverse_key
                reverse_key = reverse_key.replace(new RegExp("\\[" + k + "\\]$"), '');

                // Push
                if(k.match(patterns.push)){
                    merge = self.build([], self.push_counter(reverse_key), merge);
                }

                // Fixed
                else if(k.match(patterns.fixed)){
                    merge = self.build([], k, merge);
                }

                // Named
                else if(k.match(patterns.named)){
                    merge = self.build({}, k, merge);
                }
            }

            json = $.extend(true, json, merge);
        });

        return json;
    };
})(jQuery);

18 Stimmen

Das funktioniert also ziemlich gut. Aber es ist falsch benannt: Es gibt kein JSON zurück, wie der Name schon sagt. Stattdessen gibt es ein Objektliteral zurück. Außerdem ist es wichtig, auf hasOwnProperty zu prüfen, sonst haben Ihre Arrays alles, was an ihren Prototyp angehängt ist, wie: {numbers: ["1", "3", indexOf: function(){...}]}

313voto

mkschreder Punkte 287

Was ist falsch an:

var data = {};
$(".form-selector").serializeArray().map(function(x){data[x.name] = x.value;});

58 Stimmen

$(this).serializeArray().reduce(function(m,o){ m[o.name] = o.value; return m;}, {})

4 Stimmen

$(this).serializeArray().reduce((o,kv) => ({...o, [kv.name]: kv.value}), {})

0 Stimmen

Dies ist die einreihige Lösung, obwohl auch andere funktionieren.

107voto

Daniel X Moore Punkte 13868

Eine korrigierte Version der Lösung von Tobias Cohen. Diese geht korrekt mit fehlerhaften Werten wie 0 y '' .

jQuery.fn.serializeObject = function() {
  var arrayData, objectData;
  arrayData = this.serializeArray();
  objectData = {};

  $.each(arrayData, function() {
    var value;

    if (this.value != null) {
      value = this.value;
    } else {
      value = '';
    }

    if (objectData[this.name] != null) {
      if (!objectData[this.name].push) {
        objectData[this.name] = [objectData[this.name]];
      }

      objectData[this.name].push(value);
    } else {
      objectData[this.name] = value;
    }
  });

  return objectData;
};

Und eine CoffeeScript-Version, damit Sie bequem programmieren können:

jQuery.fn.serializeObject = ->
  arrayData = @serializeArray()
  objectData = {}

  $.each arrayData, ->
    if @value?
      value = @value
    else
      value = ''

    if objectData[@name]?
      unless objectData[@name].push
        objectData[@name] = [objectData[@name]]

      objectData[@name].push value
    else
      objectData[@name] = value

  return objectData

70voto

Ethan Brown Punkte 25661

Ich benutze gerne Array.prototype.reduce weil es sich um einen Einzeiler handelt, der sich nicht auf Underscore.js oder dergleichen:

$('#formid').serializeArray()
    .reduce(function(a, x) { a[x.name] = x.value; return a; }, {});

Dies ist vergleichbar mit der Antwort mit Array.prototype.map aber Sie müssen Ihren Anwendungsbereich nicht mit einer zusätzlichen Objektvariablen überfrachten. Einkaufen aus einer Hand.

WICHTIGER HINWEIS : Formulare mit Eingaben, die doppelt vorhanden sind name Attribute sind gültiges HTML, und es handelt sich dabei um einen gängigen Ansatz. Die Verwendung einer der Antworten in diesem Thread ist in diesem Fall unangemessen (da Objektschlüssel eindeutig sein müssen).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X