Konvertieren von Formulardaten in JavaScript-Objekte mit jQuery


Answers

Konvertieren von Formularen in JSON WIE EIN CHEF

Aktuelle Quelle ist GitHub und Laube.

$ bower installiere jquery-serialize-object

Der folgende Code ist jetzt veraltet .

Der folgende Code kann mit allen Arten von Eingabe-Namen arbeiten; und behandeln sie genau so, wie Sie es erwarten.

Beispielsweise:

<!-- 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);
Question

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

Ich möchte eine Möglichkeit haben, automatisch ein JavaScript-Objekt aus meinem Formular zu erstellen, ohne jedes Element durchlaufen zu müssen. Ich will keine Zeichenkette, wie von $('#formid').serialize(); Ich möchte auch nicht, dass die Map von $('#formid').serializeArray();




Mit der Lösung von Maček änderte ich die Funktionsweise so, dass ASP.NET MVC ihre verschachtelten / komplexen Objekte auf demselben Formular behandelt. Alles, was Sie tun müssen, ist das Validierungsstück zu ändern:

"validate": /^[a-zA-Z][a-zA-Z0-9_]*((?:\[(?:\d*|[a-zA-Z0-9_]+)\])*(?:\.)[a-zA-Z][a-zA-Z0-9_]*)*$/,

Dadurch werden Elemente mit Namen wie folgt zugeordnet und dann korrekt zugeordnet:

<input type="text" name="zooName" />

Und

<input type="text" name="zooAnimals[0].name" />



I wouldn't use this on a live site due to XSS attacks and probably plenty of other issues, but here's a quick example of what you could do:

$("#myform").submit(function(){
    var arr = $(this).serializeArray();
    var json = "";
    jQuery.each(arr, function(){
        jQuery.each(this, function(i, val){
            if (i=="name") {
                json += '"' + val + '":';
            } else if (i=="value") {
                json += '"' + val.replace(/"/g, '\\"') + '",';
            }
        });
    });
    json = "{" + json.substring(0, json.length - 1) + "}";
    // do something with json
    return false;
});



Ich habe ein Problem mit der ausgewählten Lösung gefunden.

Bei Verwendung von Formularen mit arraybasierten Namen wird die Funktion jQuery serializeArray () tatsächlich beendet.

Ich habe ein PHP-Framework, das Array-basierte Feldnamen verwendet, um zu ermöglichen, dass das gleiche Formular in mehreren Ansichten mehrmals auf dieselbe Seite gesetzt wird. Dies kann nützlich sein, wenn Sie auf derselben Seite hinzufügen, bearbeiten und löschen können, ohne dass dabei widersprüchliche Formularmodelle auftreten.

Da ich die Formulare seralisieren wollte, ohne diese absolute Basisfunktionalität ausnutzen zu müssen, entschied ich mich, mein eigenes seralizeArray () zu schreiben:

        var $vals = {};

        $("#video_edit_form input").each(function(i){
            var name = $(this).attr("name").replace(/editSingleForm\[/i, '');

            name = name.replace(/\]/i, '');

            switch($(this).attr("type")){
                case "text":
                    $vals[name] = $(this).val();
                    break;
                case "checkbox":
                    if($(this).attr("checked")){
                        $vals[name] = $(this).val();
                    }
                    break;
                case "radio":
                    if($(this).attr("checked")){
                        $vals[name] = $(this).val();
                    }
                    break;
                default:
                    break;
            }
        });

Bitte beachten Sie: Dies funktioniert auch außerhalb von form submit (). Wenn also ein Fehler im Rest Ihres Codes auftritt, wird das Formular nicht gesendet, wenn Sie auf eine Link-Schaltfläche "Änderungen speichern" klicken.

Beachten Sie außerdem, dass diese Funktion niemals zum Überprüfen des Formulars verwendet werden sollte, um nur die Daten zu sammeln, die zur Überprüfung an den Server gesendet werden. Die Verwendung eines solchen schwachen und massenzugewiesenen Codes verursacht XSS usw.




For a quick, modern solution, use the JSONify jQuery plugin. The example below is taken verbatim from the GitHub README. All credit to Kushal Pandya, author of the plugin.

Gegeben:

<form id="myform">
    <label>Name:</label>
    <input type="text" name="name"/>
    <label>Email</label>
    <input type="text" name="email"/>
    <label>Password</label>
    <input type="password" name="password"/>
</form>

Laufen:

$('#myform').jsonify();

Produziert:

{"name":"Joe User","email":"joe@example.com","password":"mypass"}

If you want to do a jQuery POST with this JSON object:

$('#mybutton').click(function() {
    $.post('/api/user', JSON.stringify($('#myform').jsonify()));
}



Ich bevorzuge diesen Ansatz, weil: Sie müssen nicht über 2 Sammlungen iterieren, Sie können andere Dinge als "Name" und "Wert" bekommen, wenn Sie müssen, und Sie können Ihre Werte bereinigen, bevor Sie sie im Objekt speichern ( wenn Sie Standardwerte haben, die Sie nicht speichern möchten, zum Beispiel).

$.formObject = function($o) {
    var o = {},
        real_value = function($field) {
            var val = $field.val() || "";

            // additional cleaning here, if needed

            return val;
        };

    if (typeof o != "object") {
        $o = $(o);
    }

    $(":input[name]", $o).each(function(i, field) {
        var $field = $(field),
            name = $field.attr("name"),
            value = real_value($field);

        if (o[name]) {
            if (!$.isArray(o[name])) {
                o[name] = [o[name]];
            }

            o[name].push(value);
        }

        else {
            o[name] = value;
        }
    });

    return o;
}

Verwenden Sie so:

var obj = $.formObject($("#someForm"));

Nur in Firefox getestet.




All diese Antworten schienen mir übertrieben. Es gibt etwas, das der Einfachheit halber gesagt werden muss. Solange alle Ihre Formulareingaben das Namensattribut haben, sollte dies nur jim dandy funktionieren.

$('form.myform').submit(function () {
  var $this = $(this)
    , viewArr = $this.serializeArray()
    , view = {};

  for (var i in viewArr) {
    view[viewArr[i].name] = viewArr[i].value;
  }

  //Do stuff with view object here (e.g. JSON.stringify?)
});



Ein-Liner (keine anderen Abhängigkeiten als jQuery), verwendet die Bindung fester Objekte für die Funktion Pass-zu- map Methode.

$('form').serializeArray().map(function(x){this[x.name] = x.value; return this;}.bind({}))[0]

Was es macht?

"id=2&value=1&comment=ok" => Object { id: "2", value: "1", comment: "ok" }

geeignet für progressive Web-Apps (sowohl reguläre Formular-Übermittlungsaktionen als auch Ajax-Anfragen können problemlos unterstützt werden)




Die einfachste und genaueste Methode, die ich für dieses Problem gefunden habe, war die Verwendung von BBQ-Plugin oder dieses (die etwa 0,5 KB Größe ist).

Es funktioniert auch mit multidimensionalen Arrays.

$.fn.serializeObject = function()
{
	return $.deparam(this.serialize());
};




Benutzen:

function form_to_json (selector) {
  var ary = $(selector).serializeArray();
  var obj = {};
  for (var a = 0; a < ary.length; a++) obj[ary[a].name] = ary[a].value;
  return obj;
}

Ausgabe:

{"myfield": "myfield value", "passwordfield": "mypasswordvalue"}



Wenn Sie versuchen, alle Formularfelder in JSON zu konvertieren, um dieses Formular über Ajax zu senden, hier ist ein jQuery-Formular-Plugin , das das tut.







Eine feste Version der Lösung von Tobias Cohen. Dieser behandelt korrekt falsche Werte wie 0 und '' .

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 für Ihre Codierung Komfort:

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



Es gibt wirklich keine Möglichkeit, dies zu tun, ohne jedes der Elemente zu untersuchen. Was Sie wirklich wissen möchten, ist "Hat jemand anderes bereits eine Methode geschrieben, die ein Formular in ein JSON-Objekt konvertiert?" So etwas wie das Folgende sollte funktionieren - beachten Sie, dass es Ihnen nur die Formularelemente gibt, die über einen POST zurückgegeben werden (muss einen Namen haben). Dies wird nicht getestet .

function formToJSON( selector )
{
     var form = {};
     $(selector).find(':input[name]:enabled').each( function() {
         var self = $(this);
         var name = self.attr('name');
         if (form[name]) {
            form[name] = form[name] + ',' + self.val();
         }
         else {
            form[name] = self.val();
         }
     });

     return form;
}



Diese Funktion sollte mehrdimensionale Arrays zusammen mit mehreren Elementen mit demselben Namen behandeln.

Ich benutze es seit ein paar Jahren:

jQuery.fn.serializeJSON=function() {
  var json = {};
  jQuery.map(jQuery(this).serializeArray(), function(n, i) {
    var _ = n.name.indexOf('[');
    if (_ > -1) {
      var o = json;
      _name = n.name.replace(/\]/gi, '').split('[');
      for (var i=0, len=_name.length; i<len; i++) {
        if (i == len-1) {
          if (o[_name[i]]) {
            if (typeof o[_name[i]] == 'string') {
              o[_name[i]] = [o[_name[i]]];
            }
            o[_name[i]].push(n.value);
          }
          else o[_name[i]] = n.value || '';
        }
        else o = o[_name[i]] = o[_name[i]] || {};
      }
    }
    else {
      if (json[n.name] !== undefined) {
        if (!json[n.name].push) {
          json[n.name] = [json[n.name]];
        }
        json[n.name].push(n.value || '');
      }
      else json[n.name] = n.value || '';      
    }
  });
  return json;
};



Links