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?

Vasil
la source
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+

nickf
la source
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();

});
Lance Rushing
la source
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 .

Simon_Weaver
la source
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+"']"); 
Malachie
la source
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.

Quentin
la source
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 :)

Ole Aldric
la source
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.

Chris
la source
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;
});
Oli
la source
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;
});
Sarah Vessels
la source
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
L'homme a appelé Haney
la source
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();
  });
});
turkane clairsemée
la source
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;
}, {});
Ryanman
la source
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.

suizo
la source
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();
  }
});
Itako
la source
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;
        }
    }                   
});
Jason Norwood-Young
la source
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"}
T.Liu
la source
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;
});
Roman Grinev
la source
1

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

 $("#form").submit(function (e) { 
    e.preventDefault();
    input_values =  $(this).serializeArray();
  });
dipenparmar12
la source
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.

slarti42uk
la source
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.

Gamelle
la source
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: "[email protected]"
//   1: "[email protected]"
// 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;
};
julien
la source
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.

Marcelo Rocha
la source
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("&")
Teodor Rautu
la source
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>
tzazo
la source
-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)
});
Raushan
la source