Formulareingabefelder mit jQuery abrufen?


412

Ich habe ein Formular mit vielen Eingabefeldern.

Ist es möglich, alle Eingabefelder dieses Formulars in einem assoziativen Array abzurufen, wenn ich das Ereignis zum Senden eines Formulars mit jQuery abfange?


23
Das ist eine gute Frage. Tatsächlich finde ich es wirklich seltsam, dass jQuery keine Funktion hat, die genau dies tut. Es gibt Funktionen , die Formulardaten in zwei verschiedenen Formaten zu bekommen, aber nicht die, die am bequemsten für Sie wissen, Scripting ... (Vielleicht .val () sollte ein solches Array zurück , wenn auf einem Formular - Element genannt?)
Luke Maurer

Antworten:


524
$('#myForm').submit(function() {
    // get all the inputs into an array.
    var $inputs = $('#myForm :input');

    // not sure if you wanted this, but I thought I'd add it.
    // get an associative array of just the values.
    var values = {};
    $inputs.each(function() {
        values[this.name] = $(this).val();
    });

});

Dank des Tipps von Simon_Weaver können Sie dies auf folgende Weise tun serializeArray:

var values = {};
$.each($('#myForm').serializeArray(), function(i, field) {
    values[field.name] = field.value;
});

Beachten Sie, dass dieses Snippet bei <select multiple>Elementen fehlschlägt .

Es scheint, dass die neuen HTML 5-FormulareingabenserializeArray in jQuery Version 1.3 nicht funktionieren . Dies funktioniert in Version 1.4+


1
In neueren Versionen von jQuery ist die Antwort von Simon_Weaver robuster und einfacher.
MightyE

1
@MightyE & @Simon_Weaver - Sie haben Recht, es ist eine robustere Methode, aber sie macht nicht genau das, wonach das OP gesucht hat. serializeArray gibt ein Array von Objekten mit den Eigenschaften nameund zurück value. Eine bessere Lösung könnte darin bestehen, die Ausgabe von serializeArray in das erforderliche Format zu verarbeiten.
Nickf

1
Ich denke, serializeArray () macht genau das, was Sie wollen, und ist viel weniger Code.
Slacy

1
Was ist mit <select>Elementen für die erste Option ? Ich habe es versucht, var $inputs = $('#new-ticket :input, :select');aber das funktioniert nicht. Kennt jemand den richtigen Weg, weil ich nicht glaube, dass ich das richtig mache?
Nathan

2
@ Nathan, sollten Sie verwenden $("#new-ticket :input, #new-ticket :select"), oder noch besser,$(":input, :select", "#new-ticket")
Nickf

252

Spät zur Party auf diese Frage, aber das ist noch einfacher:

$('#myForm').submit(function() {
    // Get all the forms elements and their values in one step
    var values = $(this).serialize();

});

8
Das ist wirklich die beste Antwort. Es behält sogar die Array-Formatierung bei, die Sie möglicherweise für Ihre Eingabefelder haben. Ich glaube nicht, dass die Antwort von nickf Ihre Datenstrukturen intakt halten würde, wenn sie beispielsweise mit Zend_Form erstellt würden, wobei Sie Feld [etwas] und Feld [etwas_else] als Namen der Eingaben hätten ... zumindest semantisch kann ich nicht sehen, wie es wäre ...
msumme

43
Gemäß den jQuery-API-Dokumenten fügt.serialize() ( api.jquery.com/serialize ) alle Elemente des Formulars in eine einzelne Zeichenfolge ein, die zum Anhängen an eine URL in einer Abfragezeichenfolge bereit ist, und ahmt im Wesentlichen eine GET-Formularanforderung nach. Dies würde nicht das erreichen, was Nickfs Antwort bewirkt.
Christopher Parker

Das ist die beste Antwort!
Daniel Hunter

5
Wissenswert: Funktioniert .serialize()auch nur mit Formularelementen. So $('form select').serialize()werden die Daten nur für wählt serialisiert.
Antitoxikum

3
$('#myForm')Verwenden Sie $ (this), anstatt es zu wiederholen .
Jimothy

23

Das Plugin jquery.form kann dabei helfen, wonach andere suchen, um diese Frage zu beantworten. Ich bin mir nicht sicher, ob es direkt das tut, was Sie wollen oder nicht.

Es gibt auch die Funktion serializeArray .


15

Manchmal finde ich es nützlicher, einen nach dem anderen zu bekommen. Dafür gibt es folgendes:

var input_name = "firstname";
var input = $("#form_id :input[name='"+input_name+"']"); 

Das Anhängen [0].valuedaran $(...)[0].value;gab mir also den Wert der Eingabe direkt, danke!
Pau Coma Ramirez

12
$('#myForm').bind('submit', function () {
  var elements = this.elements;
});

Die Elementvariable enthält alle Eingaben, Auswahlen, Textbereiche und Feldsätze innerhalb des Formulars.


9

Hier ist eine andere Lösung: Auf diese Weise können Sie alle Daten über das Formular abrufen und in einem serverseitigen Aufruf oder Ähnlichem verwenden.

$('.form').on('submit', function( e )){ 
   var form = $( this ), // this will resolve to the form submitted
       action = form.attr( 'action' ),
         type = form.attr( 'method' ),
         data = {};

     // Make sure you use the 'name' field on the inputs you want to grab. 
   form.find( '[name]' ).each( function( i , v ){
      var input = $( this ), // resolves to current input element.
          name = input.attr( 'name' ),
          value = input.val();
      data[name] = value;
   });

  // Code which makes use of 'data'.

 e.preventDefault();
}

Sie können dies dann mit Ajax-Aufrufen verwenden:

function sendRequest(action, type, data) {
       $.ajax({
            url: action,
           type: type,
           data: data
       })
       .done(function( returnedHtml ) {
           $( "#responseDiv" ).append( returnedHtml );
       })
       .fail(function() {
           $( "#responseDiv" ).append( "This failed" );
       });
}

Hoffe, dass dies für jeden von euch von Nutzen ist :)


5

Hatte ein ähnliches Problem mit einer leichten Wendung und ich dachte, ich würde das rauswerfen. Ich habe eine Rückruffunktion, die das Formular abruft, sodass ich bereits ein Formularobjekt hatte und keine einfachen Varianten verwenden konnte $('form:input'). Stattdessen habe ich mir Folgendes ausgedacht:

    var dataValues = {};
    form.find('input').each(
        function(unusedIndex, child) {
            dataValues[child.name] = child.value;
        });

Es ist eine ähnliche, aber nicht identische Situation, aber ich fand diesen Thread sehr nützlich und dachte, ich würde ihn am Ende verstauen und hoffe, jemand anderes fand ihn nützlich.


4

Assoziativ? Nicht ohne Arbeit, aber Sie können generische Selektoren verwenden:

var items = new Array();

$('#form_id:input').each(function (el) {
    items[el.name] = el;
});

Tatsächlich hält Lances Antwort das assoziative Array für die POST-Werte intakt und benötigt eine ganze Codezeile.
msumme

Warum sind Elemente ein Array? Sie verwenden es wie ein einfaches Objekt. Das Array ist hier nicht erforderlich
Jonathan Morales Vélez,

3
@ JonathanMoralesVélez 2008 Oli ist nicht mehr für einen Kommentar da. 2015 stimmt mit Ihnen überein.
Oli

4

jQuery's serializeArrayenthält keine deaktivierten Felder. Wenn Sie diese ebenfalls benötigen, versuchen Sie Folgendes:

var data = {};
$('form.my-form').find('input, textarea, select').each(function(i, field) {
    data[field.name] = field.value;
});


4

Vergessen Sie nicht die Kontrollkästchen und Optionsfelder -

var inputs = $("#myForm :input");
var obj = $.map(inputs, function(n, i) {
  var o = {};
  if (n.type == "radio" || n.type == "checkbox")
    o[n.id] = $(n).attr("checked");
  else
    o[n.id] = $(n).val();
  return o;
});
return obj

3

Dieser Code funktioniert anstelle des Namens. Geben Sie per E-Mail den Namen Ihres Formularfelds ein

$(document).ready(function(){
  $("#form_id").submit(function(event){
    event.preventDefault();
    var name = $("input[name='name']",this).val();
    var email = $("input[name='email']",this).val();
  });
});

3

Es scheint seltsam, dass niemand eine präzise Lösung für das Abrufen von Listendaten bewertet oder vorgeschlagen hat. Kaum ein Formular wird ein eindimensionales Objekt sein.

Der Nachteil dieser Lösung ist natürlich, dass auf Ihre Singleton-Objekte über den Index [0] zugegriffen werden muss. Aber IMO ist das viel besser als die Verwendung einer der Dutzend-Linien-Mapping-Lösungen.

var formData = $('#formId').serializeArray().reduce(function (obj, item) {
    if (obj[item.name] == null) {
        obj[item.name] = [];
    } 
    obj[item.name].push(item.value);
    return obj;
}, {});

2

Ich hatte das gleiche Problem und löste es auf andere Weise.

var arr = new Array();
$(':input').each(function() {
 arr.push($(this).val());
});
arr;

Es gibt den Wert aller Eingabefelder zurück. Sie können das ändern $(':input'), um genauer zu sein.


2

Gleiche Lösung wie von nickf angegeben , jedoch unter Berücksichtigung der Array-Eingabenamen, z

<input type="text" name="array[]" />

values = {};
$("#something :input").each(function() {
  if (this.name.search(/\[\]/) > 0) //search for [] in name
  {
    if (typeof values[this.name] != "undefined") {
      values[this.name] = values[this.name].concat([$(this).val()])
    } else {
      values[this.name] = [$(this).val()];
    }
  } else {
    values[this.name] = $(this).val();
  }
});

1

Wenn Sie mehrere Werte von Eingaben erhalten müssen und [] verwenden, um die Eingaben mit mehreren Werten zu definieren, können Sie Folgendes verwenden:

$('#contentform').find('input, textarea, select').each(function(x, field) {
    if (field.name) {
        if (field.name.indexOf('[]')>0) {
            if (!$.isArray(data[field.name])) {
               data[field.name]=new Array();
            }
            data[field.name].push(field.value);
        } else {
            data[field.name]=field.value;
        }
    }                   
});

1

Inspiriert von den Antworten von Lance Rushing und Simon_Weaver ist dies meine Lieblingslösung.

$('#myForm').submit( function( event ) {
    var values = $(this).serializeArray();
    // In my case, I need to fetch these data before custom actions
    event.preventDefault();
});

Die Ausgabe ist ein Array von Objekten, z

[{name: "start-time", value: "11:01"}, {name: "end-time", value: "11:11"}]

Mit dem Code unten,

var inputs = {};
$.each(values, function(k, v){
    inputs[v.name]= v.value;
});

seine endgültige Ausgabe wäre

{"start-time":"11:01", "end-time":"11:01"}

1

Ich benutze diesen Code ohne jede Schleife:

$('.subscribe-form').submit(function(e){
    var arr=$(this).serializeArray();
    var values={};
    for(i in arr){values[arr[i]['name']]=arr[i]['value']}
    console.log(values);
    return false;
});

1

Ich hoffe, das ist sowohl hilfreich als auch am einfachsten.

 $("#form").submit(function (e) { 
    e.preventDefault();
    input_values =  $(this).serializeArray();
  });

Seltsamerweise funktionierte dies bei der neuesten Version von jquery 3.4.1
relipse

0

Als ich einen Ajax-Aufruf mit allen Formularfeldern durchführen musste, hatte ich Probleme mit der Eingabeauswahl: gab alle Kontrollkästchen zurück, unabhängig davon, ob sie aktiviert waren oder nicht. Ich habe einen neuen Selektor hinzugefügt, um nur die übertragbaren Formularelemente zu erhalten:

$.extend($.expr[':'],{
    submitable: function(a){
        if($(a).is(':checkbox:not(:checked)'))
        {
            return false;
        }
        else if($(a).is(':input'))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
});

Verwendungszweck:

$('#form_id :submitable');

Ich habe es zwar noch nicht mit mehreren Auswahlfeldern getestet, aber es funktioniert, um alle Formularfelder so zu erhalten, wie es eine Standardübermittlung tun würde.

Ich habe dies verwendet, als ich die Produktoptionen auf einer OpenCart-Site so angepasst habe, dass Kontrollkästchen und Textfelder sowie der Standard-Auswahlfeldtyp enthalten sind.


0

serialize () ist die beste Methode. @ Christopher Parker sagt, dass Nickfs Antwort mehr leistet, berücksichtigt jedoch nicht, dass das Formular möglicherweise Textbereiche und ausgewählte Menüs enthält. Es ist weitaus besser, serialize () zu verwenden und das dann nach Bedarf zu bearbeiten. Daten von serialize () können entweder in einem Ajax-Post oder in get verwendet werden, sodass dort kein Problem auftritt.


0

Hoffe das hilft jemandem. :) :)

// This html:
// <form id="someCoolForm">
// <input type="text" class="form-control" name="username" value="...." />
// 
// <input type="text" class="form-control" name="profile.first_name" value="...." />
// <input type="text" class="form-control" name="profile.last_name" value="...." />
// 
// <input type="text" class="form-control" name="emails[]" value="..." />
// <input type="text" class="form-control" name="emails[]" value=".." />
// <input type="text" class="form-control" name="emails[]" value="." />
// </form>
// 
// With this js:
// 
// var form1 = parseForm($('#someCoolForm'));
// console.log(form1);
// 
// Will output something like:
// {
// username: "test2"
// emails:
//   0: ".@....com"
//   1: "...@........com"
// profile: Object
//   first_name: "..."
//   last_name: "..."
// }
// 
// So, function below:

var parseForm = function (form) {

    var formdata = form.serializeArray();

    var data = {};

    _.each(formdata, function (element) {

        var value = _.values(element);

        // Parsing field arrays.
        if (value[0].indexOf('[]') > 0) {
            var key = value[0].replace('[]', '');

            if (!data[key])
                data[key] = [];

            data[value[0].replace('[]', '')].push(value[1]);
        } else

        // Parsing nested objects.
        if (value[0].indexOf('.') > 0) {

            var parent = value[0].substring(0, value[0].indexOf("."));
            var child = value[0].substring(value[0].lastIndexOf(".") + 1);

            if (!data[parent])
                data[parent] = {};

            data[parent][child] = value[1];
        } else {
            data[value[0]] = value[1];
        }
    });

    return data;
};

0

Alle Antworten sind gut, aber wenn es ein Feld gibt, das Sie in dieser Funktion gerne ignorieren? Geben Sie dem Feld einfach eine Eigenschaft, z. B. ignore_this:

<input type="text" name="some_name" ignore_this>

Und in Ihrer Serialisierungsfunktion:

if(!$(name).prop('ignorar')){
   do_your_thing;
}

Auf diese Weise ignorieren Sie einige Felder.


1
Dies ist eher ein Kommentar als eine Antwort, da die ursprüngliche Frage nicht beantwortet wird.
Wai Ha Lee

Vielleicht, weil er schon unzählige Antworten hat? Es ist eine Ergänzung zu den Antworten, die er erhalten hat.
Marcelo Rocha

Ich würde dies mit einem Klassennamen wie obligatorisch implementieren, wenn die Eingabe ausgefüllt werden muss. Dann kann ich überprüfen $('.mandatory');und!$('.mandatory');
lharby

Wechseln Sie ignore_thiszu, data-ignore-this="true"anstatt Ihre eigenen Attribute zu erstellen, die w3c nicht validieren
zanderwar

0

Versuchen Sie den folgenden Code:

jQuery("#form").serializeArray().filter(obje => 
obje.value!='').map(aobj=>aobj.name+"="+aobj.value).join("&")

2
Bitte erläutern Sie Ihre Antwort
Ling Vu

0

Für mehrere ausgewählte Elemente ( <select multiple="multiple">) habe ich die Lösung von @Jason Norwood-Young geändert, damit sie funktioniert.

Die Antwort (wie gebucht) übernimmt nur den Wert des ersten ausgewählten Elements, nicht alle . Es wurde auch nicht initialisiert oder zurückgegeben data, wobei ersteres einen JavaScript-Fehler auslöste.

Hier ist die neue Version:

function _get_values(form) {
  let data = {};
  $(form).find('input, textarea, select').each(function(x, field) {
    if (field.name) {
      if (field.name.indexOf('[]') > 0) {
        if (!$.isArray(data[field.name])) {
          data[field.name] = new Array();
        }
        for (let i = 0; i < field.selectedOptions.length; i++) {
          data[field.name].push(field.selectedOptions[i].value);
        }

      } else {
        data[field.name] = field.value;
      }
    }

  });
  return data
}

Verwendungszweck:

_get_values($('#form'))

Hinweis: Sie müssen nur sicherstellen, dass das nameIhrer Auswahl []an das Ende angehängt wurde, zum Beispiel:

<select name="favorite_colors[]" multiple="multiple">
  <option value="red">Red</option>
  <option value="green">Green</option>
  <option value="blue">Blue</option>
</select>

-1
$("#form-id").submit(function (e) { 
  e.preventDefault();
  inputs={};
  input_serialized =  $(this).serializeArray();
  input_serialized.forEach(field => {
    inputs[field.name] = field.value;
  })
  console.log(inputs)
});
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.