Obtenir des champs de saisie de formulaire à l'aide de jQuery?


412

J'ai un formulaire avec de nombreux champs de saisie.

Lorsque j'attrape l'événement d'envoi de formulaire avec jQuery, est-il possible d'obtenir tous les champs d'entrée de ce formulaire dans un tableau associatif?


23
C'est une bonne question; en fait, je trouve vraiment étrange que jQuery n'ait pas de fonction qui le fasse précisément. Il existe des fonctions pour obtenir les données du formulaire dans deux formats différents, mais pas celle qui convient le mieux, vous savez, aux scripts … (Peut-être .val () devrait retourner un tel tableau s'il est appelé sur un élément de formulaire?)
Luke Maurer

Réponses:


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();
    });

});

Grâce à l'astuce de Simon_Weaver, voici une autre façon de le faire, en utilisant serializeArray:

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

Notez que cet extrait échouera sur les <select multiple>éléments.

Il semble que les nouvelles entrées de formulaire HTML 5 ne fonctionnent pas avec serializeArrayjQuery version 1.3. Cela fonctionne dans la version 1.4+


1
Dans les nouvelles versions de jQuery, la réponse de Simon_Weaver est plus robuste et plus simple.
MightyE

1
@MightyE & @Simon_Weaver - vous avez raison, c'est une méthode plus robuste, mais elle ne fait pas exactement ce que l'OP recherchait. serializeArray renvoie un tableau d'objets avec les propriétés nameet value. Une meilleure solution pourrait être de traiter la sortie de serializeArray dans le format requis.
nickf

1
Je pense que serializeArray () fait exactement ce que vous voulez et est beaucoup moins de code.
slacy

1
Pour la première option, qu'en est-il des <select>éléments? J'ai essayé var $inputs = $('#new-ticket :input, :select');mais ça ne marche pas. Est-ce que quelqu'un connaît la bonne façon de le faire parce que je ne pense pas que je fais ça correctement.
Nathan

2
@Nathan, vous devriez utiliser $("#new-ticket :input, #new-ticket :select"), ou mieux encore,$(":input, :select", "#new-ticket")
nickf

252

Tard à la fête sur cette question, mais c'est encore plus simple:

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

});

8
C'est vraiment la meilleure réponse. Il conserve même toute mise en forme de tableau que vous pourriez avoir pour vos champs de saisie. Je ne pense pas que la réponse de nickf garderait réellement vos structures de données intactes si elles étaient formées en utilisant Zend_Form par exemple, où vous auriez le champ [quelque chose] et le champ [quelque chose_else] comme noms des entrées ... au moins sémantiquement, je ne vois pas comment ça se passerait ...
msumme

43
Selon les documents de l'API jQuery, .serialize()( api.jquery.com/serialize ) place tous les éléments du formulaire dans une seule chaîne prête à être ajoutée à une URL dans une chaîne de requête, imitant essentiellement une demande de formulaire GET. Cela n'accomplirait pas ce que la réponse de nickf accomplit.
Christopher Parker

C'est la meilleure réponse!
Daniel Hunter

5
Bon à savoir: .serialize()fonctionne également sur les éléments de formulaire uniquement. Sera donc $('form select').serialize()sérialiser les données uniquement pour les sélections.
antitoxique

3
Plutôt que de répéter $('#myForm'), utilisez $ (this).
Jimothy

23

Le plugin jquery.form peut aider avec ce que les autres recherchent qui se retrouvent sur cette question. Je ne sais pas s'il fait directement ce que vous voulez ou non.

Il existe également la fonction serializeArray .


15

Parfois, je trouve qu'il est plus utile d'en obtenir un à la fois. Pour cela, il y a ceci:

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

Ajouter [0].valueà cela, c'est-à-dire $(...)[0].value;m'a donné la valeur de l'entrée directement, merci!
Pau Coma Ramirez

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

La variable elements contiendra toutes les entrées, sélections, zones de texte et ensembles de champs du formulaire.


9

Voici une autre solution, de cette façon, vous pouvez récupérer toutes les données sur le formulaire et l'utiliser dans un appel côté serveur ou quelque chose.

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

Vous pouvez ensuite l'utiliser avec des appels ajax:

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

J'espère que cela vous sera utile :)


5

J'ai eu un problème similaire avec une légère torsion et j'ai pensé que j'allais le jeter. J'ai une fonction de rappel qui récupère le formulaire, donc j'avais déjà un objet de formulaire et je ne pouvais pas facilement des variantes $('form:input'). Au lieu de cela, j'ai trouvé:

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

C'est une situation similaire mais pas identique, mais j'ai trouvé ce fil très utile et j'ai pensé que je mettrais cela au bout et j'espère que quelqu'un d'autre l'a trouvé utile.


4

Associatif? Non sans quelques travaux, mais vous pouvez utiliser des sélecteurs génériques:

var items = new Array();

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

en fait, la réponse de Lance maintient le tableau associatif intact pour les valeurs POST et prend une énorme ligne de code.
msumme

pourquoi les articles sont-ils un tableau? vous l'utilisez comme un simple objet. Il n'y a pas besoin de la matrice ici
Jonathan Morales Vélez

3
@ JonathanMoralesVélez 2008 Oli n'est plus là pour commenter. 2015 est d'accord avec vous.
Oli

4

jQuery serializeArrayn'inclut pas les champs désactivés, donc si vous en avez besoin aussi, essayez:

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


4

N'oubliez pas les cases à cocher et les boutons radio -

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

Ce morceau de code fonctionnera à la place du nom, email entrez le nom de vos champs de formulaire

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

Semble étrange que personne n'ait voté ou proposé une solution concise pour obtenir les données de la liste. Presque aucune forme ne sera un objet à une dimension.

L'inconvénient de cette solution est, bien sûr, que vos objets singleton vont devoir être accessibles à l'index [0]. Mais l'OMI est bien meilleur que d'utiliser l'une des solutions de cartographie de la douzaine de lignes.

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

J'ai eu le même problème et je l'ai résolu d'une manière différente.

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

Il renvoie la valeur de tous les champs d'entrée. Vous pouvez modifier le $(':input')pour être plus précis.


2

Même solution que celle donnée par nickf , mais avec les noms d'entrée de tableau pris en compte par exemple

<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

Si vous devez obtenir plusieurs valeurs à partir des entrées et que vous utilisez [] pour définir les entrées avec plusieurs valeurs, vous pouvez utiliser ce qui suit:

$('#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

Inspiré par les réponses de Lance Rushing et Simon_Weaver , c'est ma solution préférée.

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

La sortie est un tableau d'objets, par exemple

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

Avec le code ci-dessous,

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

sa sortie finale serait

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

1

J'utilise ce code sans chaque boucle:

$('.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

J'espère que cela est utile, ainsi que le plus simple.

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

Curieusement, cela n'a pas fonctionné sur la dernière version de jquery 3.4.1
relipse le

0

Lorsque j'ai eu besoin de faire un appel ajax avec tous les champs du formulaire, j'ai eu des problèmes avec : le sélecteur d' entrée renvoyant toutes les cases à cocher, qu'elles aient été cochées ou non. J'ai ajouté un nouveau sélecteur pour simplement obtenir les éléments de formulaire soumis:

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

usage:

$('#form_id :submitable');

Je ne l'ai pas encore testé avec plusieurs cases de sélection, mais cela fonctionne pour obtenir tous les champs du formulaire comme le ferait une soumission standard.

Je l'ai utilisé lors de la personnalisation des options du produit sur un site OpenCart pour inclure des cases à cocher et des champs de texte ainsi que le type de boîte de sélection standard.


0

serialize () est la meilleure méthode. @ Christopher Parker dit que la réponse de Nickf accomplit plus, mais elle ne tient pas compte du fait que le formulaire peut contenir une zone de texte et des menus sélectionnés. Il est de loin préférable d'utiliser serialize () puis de le manipuler comme vous le souhaitez. Les données de serialize () peuvent être utilisées dans une publication Ajax ou get, il n'y a donc aucun problème.


0

J'espère que cela aide quelqu'un. :)

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

Toutes les réponses sont bonnes, mais s'il y a un champ que vous aimez ignorer dans cette fonction? Facile, donnez au champ une propriété, par exemple ignore_this:

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

Et dans votre fonction de sérialisation:

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

C'est ainsi que vous ignorez certains champs.


1
Il s'agit plus d'un commentaire que d'une réponse car il ne répond pas à la question d'origine.
Wai Ha Lee

Peut-être parce qu'il a déjà des tonnes de réponses? C'est un complément aux réponses qu'il a reçues.
Marcelo Rocha

Je voudrais implémenter cela avec un nom de classe comme obligatoire si l'entrée doit être remplie. Je peux ensuite vérifier $('.mandatory');et!$('.mandatory');
lharby

Remplacez par ignore_thisau data-ignore-this="true"lieu de créer vos propres attributs qui ne valident pas le w3c
zanderwar

0

Essayez le code suivant:

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

2
Veuillez expliquer votre réponse
Ling Vu

0

Pour plusieurs éléments de sélection (<select multiple="multiple"> ), j'ai modifié la solution de @Jason Norwood-Young pour la faire fonctionner.

La réponse (telle que publiée) ne prend que la valeur du premier élément qui a été sélectionné, pas tous . Il n'a pas non plus initialisé ni retournédata , le premier lançant une erreur JavaScript.

Voici la nouvelle 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
}

Usage:

_get_values($('#form'))

Remarque: Il vous suffit de vous assurer que le namede votre sélection a été []ajouté à la fin de celui-ci, par exemple:

<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)
});
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.