Comment puis-je obtenir des données de formulaire avec JavaScript / jQuery?

404

Existe-t-il un moyen simple et en une ligne pour obtenir les données d'un formulaire comme il le serait s'il devait être soumis de manière classique uniquement HTML?

Par exemple:

<form>
    <input type="radio" name="foo" value="1" checked="checked" />
    <input type="radio" name="foo" value="0" />
    <input name="bar" value="xxx" />
    <select name="this">
        <option value="hi" selected="selected">Hi</option>
        <option value="ho">Ho</option>
</form>

Production:

{
    "foo": "1",
    "bar": "xxx",
    "this": "hi"
}

Quelque chose comme ça est trop simple, car il n'inclut pas (correctement) les zones de texte, les sélections, les boutons radio et les cases à cocher:

$("#form input").each(function () {
    data[theFieldName] = theFieldValue;
});
Bart van Heukelom
la source
3
Une autre question similaire à celle-ci: stackoverflow.com/questions/169506/…
Marcelo Rodovalho

Réponses:

431
$('form').serialize() //this produces: "foo=1&bar=xxx&this=hi"

démo

chelmertz
la source
15
Fermer, mais peut-être quelque chose qui renvoie un tableau avec des paires clé-valeur au lieu d'une seule chaîne?
Bart van Heukelom
80
Nvm, l'a trouvé dans les commentaires de la fonction serialize (). Cela s'appelle serializeArray. Il retourne un tableau de tableaux (qui contiennent une entrée "nom" et "valeur") mais qui devrait être assez facile à transformer.
Bart van Heukelom
22
Et l'utilisation de la bibliothèque de soulignements peut être transformée en utilisant:_.object($("#myform").serializeArray().map(function(v) {return [v.name, v.value];} ))
MhdSyrwan
8
@BartvanHeukelom Je sais que c'est 4 ans plus tard, mais .serializeArray () renverra un tableau.
TJ WealthEngine API Evangelist
6
Assurez-vous que chaque balise d'entrée comprend un attribut de nom, sinon elle ne renverra rien.
Eugene Kulabuhov
507

Use $('form').serializeArray(), qui renvoie un tableau :

[
  {"name":"foo","value":"1"},
  {"name":"bar","value":"xxx"},
  {"name":"this","value":"hi"}
]

Une autre option est $('form').serialize(), qui renvoie une chaîne :

"foo=1&bar=xxx&this=hi"

Jetez un œil à cette démo jsfiddle

Paul
la source
91
serializeArrayserait tellement plus utile s'il
renvoyait
8
Je suis d'accord qu'un objet serait idéal. Cependant, il y a un problème - une clé peut avoir plusieurs valeurs. Souhaitez-vous retourner un objet clé - «tableau de valeurs», ou clé - «première valeur» ou autre chose? Je pense que les gars de jQuery n'ont choisi rien de ce qui précède :)
Paul
Soyez conscient d'un problème avec plusieurs valeurs (comme @Paul mentionné ci-dessus), les cases à cocher et les entrées multiples avec name="multiple[]"ne fonctionnent pas. La solution pour la méthode POST est la même, utilisez simplement $ ('form'). Serialize (). De plus, la méthode POST n'a pas de limite de 2000 caractères comme GET dans la plupart des navigateurs, elle peut donc être utilisée même pour des données assez volumineuses.
Artru
Veuillez également noter que pour enregistrer une valeur à partir de n'importe quelle entrée de formulaire, l'entrée doit avoir un nameattribut.
Chris - Jr
@GetFree pourquoi ne pas simplement utiliser la fonction de carte jQuery? function getFormData (form) {var rawJson = form.serializeArray (); var model = {}; $ .map (rawJson, fonction (n, i) {modèle [n ['nom']] = n ['valeur'];}); modèle de retour; }
Tom McDonough
196

Réponse mise à jour pour 2014: HTML5 FormData fait cela

var formData = new FormData(document.querySelector('form'))

Vous pouvez ensuite publier formData exactement tel qu'il est - il contient tous les noms et valeurs utilisés dans le formulaire.

mikemaccana
la source
13
De plus, FormData est bon et utile, mais il convient de noter que si vous souhaitez lire les données dans FormData, ce n'est pas si facile (voir stackoverflow.com/questions/7752188/… )
StackExchange What The Heck
1
Gardez à l'esprit que FormData fait partie des fonctionnalités avancées de XMLHttpRequest (auparavant connues sous le nom de XMLHttpRequest niveau 2), vous devez donc vous fier à un polyfill pour Internet Explorer <10. caniuse.com/#feat=xhr2
Pier-Luc Gendreau
3
@yochannah, non. Bien sûr, on ne peut pas simplement accéder aux données et les modifier comme un objet normal, mais il est toujours trivial d'obtenir les données. Découvrez la entries()méthode [page MDN ].
Web et Flow
@Web et Flow merci de l'avoir signalé! J'adore quand les navigateurs ajoutent de nouvelles fonctionnalités utiles :) fois, elles changent.
StackExchange What The Heck
J'essaie d'utiliser FormData pour envoyer un objet à mon script Flask-python, mais il ne semble pas venir comme un objet de requête normal que je peux décompresser. Quelqu'un peut-il indiquer une explication des étapes spéciales pour le gérer côté serveur? C'est là que ça me semble vide.
manisha
181

Basé sur jQuery.serializeArray, retourne des paires clé-valeur.

var data = $('#form').serializeArray().reduce(function(obj, item) {
    obj[item.name] = item.value;
    return obj;
}, {});
neuront
la source
12
Des paires valeur-clé ici, les gars, tout le monde, venez ici! C'est doré !!! Merci! Si je veux une valeur d'un élément nommé "détaillant", je fais ceci console.log ($ ('# formulaire'). SerializeArray (). Réduire (fonction (obj, item) {obj [item.name] = item. value; return obj;}, {}) ['détaillant']];
Yevgeniy Afanasyev
J'ai créé hier une méthode JQuery basée sur cette réponse mais travaillant avec des multisélection et des tableaux d'entrée (avec le nom 'exemple []'). Vous pouvez le trouver dans ma réponse ci-dessous. Quoi qu'il en soit, bonne approche neuront, merci! :)
manuman94
Celui-ci me convenait le mieux, parmi toutes les réponses!
VPetrovic
Cette IMHO est la meilleure réponse!
Rahul
74
document.querySelector('form').addEventListener('submit', (e) => {
  const formData = new FormData(e.target);
  // Now you can use formData.get('foo'), for example.
  // Don't forget e.preventDefault() if you want to stop normal form .submission
});

C'est une réponse épineuse, mais laissez-moi vous expliquer pourquoi c'est une meilleure solution:

  • Nous traitons correctement une soumission de formulaire plutôt qu'une simple pression sur un bouton. Certaines personnes aiment pousser sur les champs. Certaines personnes utilisent des périphériques d'entrée alternatifs tels que l'entrée vocale ou d'autres périphériques d'accessibilité. Manipulez le formulaire soumis et vous le résolvez correctement pour tout le monde.

  • Nous creusons dans les données du formulaire pour le formulaire réel qui a été soumis. Si vous modifiez votre sélecteur de formulaire ultérieurement, vous n'avez pas à modifier les sélecteurs pour tous les champs. De plus, vous pouvez avoir plusieurs formulaires avec les mêmes noms d'entrée. Pas besoin de lever l'ambiguïté avec des identifiants excessifs et ce qui ne l'est pas, il suffit de suivre les entrées en fonction du formulaire qui a été soumis. Cela vous permet également d'utiliser un seul gestionnaire d'événements pour plusieurs formulaires si cela convient à votre situation.

  • L'interface FormData est assez nouvelle, mais est bien prise en charge par les navigateurs. C'est un excellent moyen de créer cette collecte de données pour obtenir les vraies valeurs de ce qui est dans le formulaire. Sans cela, vous devrez parcourir tous les éléments (comme avec form.elements) et déterminer ce qui est vérifié, ce qui ne l'est pas, quelles sont les valeurs, etc. Tout à fait possible si vous avez besoin de l'ancien support du navigateur, mais le FormData l'interface est plus simple.

  • J'utilise ES6 ici ... ce n'est en aucun cas une exigence, alors changez-le pour qu'il soit compatible ES5 si vous avez besoin de l'ancien support du navigateur.

Brad
la source
fyi, les objets FormData n'exposent pas leurs valeurs. Pour en obtenir un objet simple, voir stackoverflow.com/questions/41431322/…
phil294
2
@Blauhirn Nonsense, bien sûr, ils exposent les valeurs. Le code dans ma réponse fonctionne. Tu devrais l'essayer. Ici, j'ai fait un violon pour vous: jsfiddle.net/zv9s1xq5 Si vous voulez un itérateur, utilisez formData.entries().
Brad
Je sais que cela fonctionne, mais les propriétés ne sont pas accessibles par clé. Par exemple, formData.foo n'est pas défini. Comme vous l'avez vu dans votre réponse, il .get() faut appeler ce qui, à mon avis, n'est pas pratique. Peut-être que "n'expose pas" est tombé dans le mauvais sens. Donc, pour générer quelque chose comme à { foo: 'bar' }partir d'un submitévénement, vous devez les parcourir manuellement. D'où le . To get a plain object from it, see [link].
phil294
1
@Blauhirn Vous vous trompez à ce sujet. XMLHttpRequest prend directement en charge FormData. xhr.send(formData);
Brad
1
@Blauhirn JSON.stringify([...formData]) Ou, si vous voulez que vos clés / valeurs soient séparées ... [...formData].reduce((prev, cur) => { prev[cur[0]] = cur[1]; return prev;}, {})
Brad
26

utilisez .serializeArray () pour obtenir les données au format tableau, puis convertissez-les en objet:

function getFormObj(formId) {
    var formObj = {};
    var inputs = $('#'+formId).serializeArray();
    $.each(inputs, function (i, input) {
        formObj[input.name] = input.value;
    });
    return formObj;
}
Nils
la source
Cela écrase mes cases à cocher si j'ai quelque chose comme <input type="checkbox" name="someList" value="one" /> <input type="checkbox" name="someList" value="two" />. Si les deux sont cochés, l'objet contient uniquement la deuxième valeur de case à cocher.
dmathisen
2
N'est-ce pas un cas où someListdevrait être type="radio"?
dylanjameswagner
vote positif car la réponse acceptée ne renvoie pas d'objet avec les clés comme:name:value
Matt-le-Marxiste
24

Voici une solution très simple et courte qui ne nécessite même pas Jquery.

var formElements=document.getElementById("myForm").elements;    
var postData={};
for (var i=0; i<formElements.length; i++)
    if (formElements[i].type!="submit")//we dont want to include the submit-buttom
        postData[formElements[i].name]=formElements[i].value;
Clox
la source
1
Cela ne fonctionne pas avec les boutons radio: la dernière option est toujours celle enregistrée postData.
Kyle Falconer
3
Merci de nous avoir donné une réponse non jquery.
Glen Pierce
24

Nous sommes en 2019 et il existe une meilleure façon de procéder:

const form = document.querySelector('form');
const data = new URLSearchParams(new FormData(form).entries());

ou si vous voulez un objet simple à la place

const form = document.querySelector('form');
const data = Object.fromEntries(new FormData(form).entries());

mais notez que cela ne fonctionnera pas avec les clés en double comme vous le faites avec les cases à cocher à sélection multiple et en double avec le même nom.

fringd
la source
Totalement. Cependant, je n'ai pas obtenu de tableau pour une liste d'entrées qui ont toutes le même nom, ce qui signifiait que je devais utiliser document.getElementsByClassNameet une boucle for mais bon, toujours plus agréable que d'exiger jQuery, etc.
alphanumeric0101
1
Cette réponse est ma préférée. Mais il faut lire document.querySelectorau lieu de juste querySelector.
adabru
Remarque "FormData n'utilisera que les champs de saisie qui utilisent l'attribut name" - de MDN
binaryfunt
17
$('#myform').serialize();
Andy Baird
la source
13
$("#form input, #form select, #form textarea").each(function() {
 data[theFieldName] = theFieldValue;
});

à part cela, vous voudrez peut-être regarder serialize () ;

pixeline
la source
13

J'utilise ceci:

Plugin jQuery

(function($){
  $.fn.getFormData = function(){
    var data = {};
    var dataArray = $(this).serializeArray();
    for(var i=0;i<dataArray.length;i++){
      data[dataArray[i].name] = dataArray[i].value;
    }
    return data;
  }
})(jQuery);

Formulaire HTML

<form id='myform'>
  <input name='myVar1' />
  <input name='myVar2' />
</form>

Obtenez les données

var myData = $("#myForm").getFormData();
Dustin Poissant
la source
Notez que ce plugin ne fonctionne pas dans les cas où plusieurs entrées de saisie de formulaire avec le même nom sont présentes. La dernière entrée remplacerait la précédente alors que le comportement attendu serait d'obtenir toutes les valeurs sous forme deArray
Milli
1
Juste une note qu'un an plus tard, je pense maintenant que c'est une réponse terrible et que personne ne devrait l'utiliser. Comme le commentaire précédent le dit, des choses comme les boutons radio ne fonctionneraient pas. Il y a de meilleures réponses ci-dessus, utilisez plutôt l'une d'entre elles.
Dustin Poissant
11

Voici une implémentation de JavaScript uniquement qui gère correctement les cases à cocher, les boutons radio et les curseurs (probablement d'autres types d'entrée également, mais je ne les ai testés que).

function setOrPush(target, val) {
    var result = val;
    if (target) {
        result = [target];
        result.push(val);
    }
    return result;
}

function getFormResults(formElement) {
    var formElements = formElement.elements;
    var formParams = {};
    var i = 0;
    var elem = null;
    for (i = 0; i < formElements.length; i += 1) {
        elem = formElements[i];
        switch (elem.type) {
            case 'submit':
                break;
            case 'radio':
                if (elem.checked) {
                    formParams[elem.name] = elem.value;
                }
                break;
            case 'checkbox':
                if (elem.checked) {
                    formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
                }
                break;
            default:
                formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
        }
    }
    return formParams;
}

Exemple de travail:

    function setOrPush(target, val) {
      var result = val;
      if (target) {
        result = [target];
        result.push(val);
      }
      return result;
    }

    function getFormResults(formElement) {
      var formElements = formElement.elements;
      var formParams = {};
      var i = 0;
      var elem = null;
      for (i = 0; i < formElements.length; i += 1) {
        elem = formElements[i];
        switch (elem.type) {
          case 'submit':
            break;
          case 'radio':
            if (elem.checked) {
              formParams[elem.name] = elem.value;
            }
            break;
          case 'checkbox':
            if (elem.checked) {
              formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
            }
            break;
          default:
            formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
        }
      }
      return formParams;
    }

    //
    // Boilerplate for running the snippet/form
    //

    function ok() {
      var params = getFormResults(document.getElementById('main_form'));
      document.getElementById('results_wrapper').innerHTML = JSON.stringify(params, null, ' ');
    }

    (function() {
      var main_form = document.getElementById('main_form');
      main_form.addEventListener('submit', function(event) {
        event.preventDefault();
        ok();
      }, false);
    })();
<form id="main_form">
  <div id="questions_wrapper">
    <p>what is a?</p>
    <div>
      <input type="radio" required="" name="q_0" value="a" id="a_0">
      <label for="a_0">a</label>
      <input type="radio" required="" name="q_0" value="b" id="a_1">
      <label for="a_1">b</label>
      <input type="radio" required="" name="q_0" value="c" id="a_2">
      <label for="a_2">c</label>
      <input type="radio" required="" name="q_0" value="d" id="a_3">
      <label for="a_3">d</label>
    </div>
    <div class="question range">
      <label for="a_13">A?</label>
      <input type="range" required="" name="q_3" id="a_13" min="0" max="10" step="1" list="q_3_dl">
      <datalist id="q_3_dl">
        <option value="0"></option>
        <option value="1"></option>
        <option value="2"></option>
        <option value="3"></option>
        <option value="4"></option>
        <option value="5"></option>
        <option value="6"></option>
        <option value="7"></option>
        <option value="8"></option>
        <option value="9"></option>
        <option value="10"></option>
      </datalist>
    </div>
    <p>A and/or B?</p>
    <div>
      <input type="checkbox" name="q_4" value="A" id="a_14">
      <label for="a_14">A</label>
      <input type="checkbox" name="q_4" value="B" id="a_15">
      <label for="a_15">B</label>
    </div>
  </div>
  <button id="btn" type="submit">OK</button>
</form>
<div id="results_wrapper"></div>

Éditer:

Si vous cherchez une implémentation plus complète, jetez un coup d'œil à cette section du projet pour lequel j'ai fait cela . Je mettrai à jour cette question avec la solution complète que j'ai trouvée, mais peut-être que cela sera utile à quelqu'un.

Kyle Falconer
la source
1
Belle solution :) J'ai cependant trouvé un bogue, avec la fonction setOrPush. Il n'inclut pas de vérification pour voir si la cible est déjà un tableau, provoquant la création d'un tableau imbriqué profond en cas de plusieurs cases à cocher cochées avec le même nom.
Wouter van Dam
@KyleFalconer Nice! Pourquoi n'avez-vous pas fusionné les boîtiers de commutation pour la radio et la case à cocher - ils fonctionneront correctement (je suppose).
Ethan
@Ethan C'est parce qu'une case à cocher peut avoir plusieurs valeurs sélectionnées et qu'une radio ne peut avoir qu'une seule valeur sélectionnée, donc la façon dont je stocke la valeur change.
Kyle Falconer du
@KyleFalconer Oui, je comprends cela. Le code de gestion de la «case à cocher» prend également en charge le choix unique possible de «radio», grâce à la routine «SetOrPush».
Ethan
@Ethan Oh je pense que je sais ce que tu dis. Cela pourrait être fait dans les deux sens, mais je pense que je l'ai fait de cette façon simplement parce que je voulais une seule valeur, pas un tableau de valeurs.
Kyle Falconer
9

Si vous utilisez jQuery, voici une petite fonction qui fera ce que vous cherchez.

Tout d'abord, ajoutez un ID à votre formulaire (sauf s'il s'agit du seul formulaire sur la page, vous pouvez simplement utiliser 'formulaire' comme requête dom)

<form id="some-form">
 <input type="radio" name="foo" value="1" checked="checked" />
 <input type="radio" name="foo" value="0" />
 <input name="bar" value="xxx" />
 <select name="this">
  <option value="hi" selected="selected">Hi</option>
  <option value="ho">Ho</option>
</form>

<script>
//read in a form's data and convert it to a key:value object
function getFormData(dom_query){
    var out = {};
    var s_data = $(dom_query).serializeArray();
    //transform into simple data/value object
    for(var i = 0; i<s_data.length; i++){
        var record = s_data[i];
        out[record.name] = record.value;
    }
    return out;
}

console.log(getFormData('#some-form'));
</script>

La sortie ressemblerait à:

{
 "foo": "1",
 "bar": "xxx",
 "this": "hi"
}
RobKohr
la source
7

Vous pouvez également utiliser les objets FormData ; L'objet FormData vous permet de compiler un ensemble de paires clé / valeur à envoyer à l'aide de XMLHttpRequest. Il est principalement destiné à être utilisé pour envoyer des données de formulaire, mais peut être utilisé indépendamment des formulaires afin de transmettre des données à clé.

        var formElement = document.getElementById("myform_id");
        var formData = new FormData(formElement);
        console.log(formData);
numediaweb
la source
Merci, mais si vous n'avez pas de pièce d'identité? Et si vous avez un formulaire en tant qu'objet JQuery? var form = $ (this) .closest ('form'); ? Devrait var formElement = document.getElementById (form [0]); travailler à la place votre première ligne? Eh bien, cela ne fonctionne pas, malheureusement. Est-ce que tu sais pourquoi?
Yevgeniy Afanasyev,
En fait, FormData n'est pas pris en charge par tous les navigateurs :( il vaut donc mieux utiliser une approche différente
numediaweb
Merci. J'ai utilisé le dernier chrome et cela ne fonctionnait toujours pas. Je suis donc allé avec la réponse #neuront de là-haut.
Yevgeniy Afanasyev,
6

Cela ajoutera tous les champs du formulaire à l'objet JavaScript "res":

var res = {};
$("#form input, #form select, #form textarea").each(function(i, obj) {
    res[obj.name] = $(obj).val();
})
gamliela
la source
Probablement parce que cette même réponse exacte a déjà été publiée en 2010.
nathanvda
Je ne le savais pas. Pour une réponse aussi courte, cela n'est pas surprenant. Et même ainsi, où est la référence?
gamliela
Sérieusement? Vous ne croyez pas mon commentaire sans la référence et vous ne pouvez même pas parcourir la liste des réponses pour voir si elles sont les mêmes? stackoverflow.com/a/2276469/216513
nathanvda
Je pensais que vous voulez dire une réponse dans une autre question. Je ne me souviens pas maintenant des détails et de mes raisons; peut-être parce que ce n'est pas exactement la même chose
gamliela
1
Réponse parfaite pour quelqu'un qui veut que cela fonctionne pour la saisie, sélectionnez plusieurs et zone de texte. Parce que, en utilisant sérialiser, vous n'obtiendrez pas tous les éléments sélectionnés dans la balise de sélection. Mais, en utilisant .val (), vous obtiendrez exactement ce que vous voulez en tant que tableau. Réponse simple et directe.
Sailesh Kotha
6

J'ai inclus la réponse pour rendre également l'objet requis.

function getFormData(form) {
var rawJson = form.serializeArray();
var model = {};

$.map(rawJson, function (n, i) {
    model[n['name']] = n['value'];
});

return model;
}
Tom McDonough
la source
Cela ne gérera pas du tout les tableaux; foo[bar][] = 'qux'devrait sérialiser vers { foo: { bar: [ 'qux' ] } }.
amphétamachine
6

Sur la base de la réponse de Neuront, j'ai créé une méthode JQuery simple qui obtient les données du formulaire par paires clé-valeur, mais cela fonctionne pour les sélections multiples et pour les entrées de tableau avec name = 'example []'.

Voici comment il est utilisé:

var form_data = $("#form").getFormObject();

Vous trouverez ci-dessous un exemple de sa définition et de son fonctionnement.

// Function start
$.fn.getFormObject = function() {
    var object = $(this).serializeArray().reduce(function(obj, item) {
        var name = item.name.replace("[]", "");
        if ( typeof obj[name] !== "undefined" ) {
            if ( !Array.isArray(obj[name]) ) {
                obj[name] = [ obj[name], item.value ];
            } else {
               obj[name].push(item.value);
            }
        } else {
            obj[name] = item.value;
        }
        return obj;
    }, {});
    return object;
}
// Function ends

// This is how it's used
$("#getObject").click( function() {
  var form_data = $("#form").getFormObject();
  console.log(form_data);
});
/* Only to make view better ;) */
#getObject {
  padding: 10px;
  cursor:pointer;
  background:#0098EE;
  color:white;
  display:inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<form id="form">
  <input type="text" name="text" value="Hola amigo" /> 
  
  <input type="text" name="text_array[]" value="Array 1" /> 
  <input type="text" name="text_array[]" value="Array 2" /> 
  <input type="text" name="text_array[]" value="Array 3" /> 
  
  <select name="multiselect" multiple>
    <option name="option1" selected> option 1 </option>
    <option name="option2" selected> option 2 </option>
  </select>
  
  <input type="checkbox" name="checkbox" value="checkbox1" checked/>
  <input type="checkbox" name="checkbox" value="checkbox2" checked/>
  
  <input type="radio" name="radio" value="radio1" checked/>
  <input type="radio" name="radio" value="radio2"/>

</form>

<div id="getObject"> Get object (check the console!) </div>

manuman94
la source
5
var formData = new FormData($('#form-id'));
params   = $('#form-id').serializeArray();

$.each(params, function(i, val) {
    formData.append(val.name, val.value);
});
George John
la source
4
function getFormData($form){
    var unindexed_array = $form.serializeArray();
    var indexed_array = {};

    $.map(unindexed_array, function(n, i){
        if(indexed_array[n['name']] == undefined){
            indexed_array[n['name']] = [n['value']];
        }else{
            indexed_array[n['name']].push(n['value']);
        }
    });

    return indexed_array;
}
郭润民
la source
4

vous pouvez utiliser cette fonction pour avoir un objet ou un JSON à partir du formulaire.

pour l'utiliser:

var object = formService.getObjectFormFields("#idform");

 function  getObjectFormFields(formSelector)
        {
            /// <summary>Função que retorna objeto com base nas propriedades name dos elementos do formulário.</summary>
            /// <param name="formSelector" type="String">Seletor do formulário</param>

            var form = $(formSelector);

            var result = {};
            var arrayAuxiliar = [];
            form.find(":input:text").each(function (index, element)
            {
                var name = $(element).attr('name');

                var value = $(element).val();
                result[name] = value;
            });

            form.find(":input[type=hidden]").each(function (index, element)
            {
                var name = $(element).attr('name');
                var value = $(element).val();
                result[name] = value;
            });


            form.find(":input:checked").each(function (index, element)
            {
                var name;
                var value;
                if ($(this).attr("type") == "radio")
                {
                    name = $(element).attr('name');
                    value = $(element).val();
                    result[name] = value;
                }
                else if ($(this).attr("type") == "checkbox")
                {
                    name = $(element).attr('name');
                    value = $(element).val();
                    if (result[name])
                    {
                        if (Array.isArray(result[name]))
                        {
                            result[name].push(value);
                        } else
                        {
                            var aux = result[name];
                            result[name] = [];
                            result[name].push(aux);
                            result[name].push(value);
                        }

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

            });

            form.find("select option:selected").each(function (index, element)
            {
                var name = $(element).parent().attr('name');
                var value = $(element).val();
                result[name] = value;

            });

            arrayAuxiliar = [];
            form.find("checkbox:checked").each(function (index, element)
            {
                var name = $(element).attr('name');
                var value = $(element).val();
                result[name] = arrayAuxiliar.push(value);
            });

            form.find("textarea").each(function (index, element)
            {
                var name = $(element).attr('name');
                var value = $(element).val();
                result[name] = value;
            });

            return result;
        }

Marcos Costa
la source
2
Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien de référence. Les réponses de lien uniquement peuvent devenir invalides si la page liée change. - De l'avis
Wahyu Kristianto
Mais ce lien a une fonction pour l'aider (je pense). Mais je vais mettre le code la prochaine fois.
Marcos Costa
3

J'ai écrit une bibliothèque pour résoudre ce problème: JSONForms . Il prend une forme, parcourt chaque entrée et crée un objet JSON que vous pouvez facilement lire.

Disons que vous avez le formulaire suivant:

<form enctype='application/json'>
  <input name='places[0][city]' value='New York City'>
  <input type='number' name='places[0][population]' value='8175133'>
  <input name='places[1][city]' value='Los Angeles'>
  <input type='number' name='places[1][population]' value='3792621'>
  <input name='places[2][city]' value='Chicago'>
  <input type='number' name='places[2][population]' value='2695598'>
</form>

La transmission du formulaire à la méthode d'encodage de JSONForms vous renvoie l'objet suivant:

{
  "places": [
    {
      "city": "New York City",
      "population": 8175133
    },
    {
      "city": "Los Angeles",
      "population": 3792621
    },
    {
      "city": "Chicago",
      "population": 2695598
    }
  ]
}

Voici une démo avec votre formulaire.

Cezary Wojtkowski
la source
Regarde et fonctionne bien, merci. Une seule chose, la version minifiée appelle un fichier de carte, devrait être facultative imo.
adi518
2

$( "form" ).bind( "submit", function(e) {
    e.preventDefault();
    
    console.log(  $(this).serializeObject() );    

    //console.log(  $(this).serialize() );
    //console.log(  $(this).serializeArray() );

});


$.fn.serializeObject = function() {
    var o = {};
    var a = this.serializeArray();

    $.each( a, function() {
        if ( o[this.name] !== undefined) 
        {
            if ( ! o[this.name].push ) 
            {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        }
        else 
        {
            o[this.name] = this.value || '';
        }
    });

    return o;
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<form>

    <input type="radio" name="foo" value="1" checked="checked" />
    <input type="radio" name="foo" value="0" />
    <input name="bar" value="xxx" />

    <select name="this">
        <option value="hi" selected="selected">Hi</option>
        <option value="ho">Ho</option>
    </select>

    <input type="submit" value="Submit" />

</form>

Codepen

antelove
la source
2

Pour ceux d'entre vous qui préféreraient une Objectchaîne par opposition à une chaîne sérialisée (comme celle renvoyée par $(form).serialize(), et une légère amélioration $(form).serializeArray()), n'hésitez pas à utiliser le code ci-dessous:

var Form = {
    _form: null,
    _validate: function(){
        if(!this._form || this._form.tagName.toLowerCase() !== "form") return false;
        if(!this._form.elements.length) return false;
    }, _loopFields: function(callback){
        var elements = this._form.elements;
        for(var i = 0; i < elements.length; i++){
            var element = form.elements[i];
            if(name !== ""){
                callback(this._valueOfField(element));
            }
        }
    }, _valueOfField: function(element){
        var type = element.type;
        var name = element.name.trim();
        var nodeName = element.nodeName.toLowerCase();
        switch(nodeName){
            case "input":
                if(type === "radio" || type === "checkbox"){
                    if(element.checked){
                        return element.value;
                    }
                }
                return element.value;
                break;
            case "select":
                if(type === "select-multiple"){
                    for(var i = 0; i < element.options.length; i++){
                        if(options[i].selected){
                            return element.value;
                        }
                    }
                }
                return element.value;
                break;
            case "button":
                switch(type){
                    case "reset": 
                    case "submit": 
                    case "button":
                        return element.value;
                        break;
                }
                break;
        } 
    }, serialize: function(form){
        var data = {};
        this._form = form;

        if(this._validate()){
            this._loopFields(function(value){
                if(value !== null) data[name] = value;
            });
        }
        return data;
    }
};

Pour l'exécuter, utilisez simplement Form.serialize(form)et la fonction renverra un Objectsemblable à ceci:

<!-- { username: "username", password: "password" } !-->
<input type="text" value="username">
<input type="password" value="password">

En prime, cela signifie que vous n'avez pas à installer l'ensemble complet de jQuery juste pour une fonction de sérialisation.

GROVER.
la source
1

J'ai écrit une fonction qui prend en charge plusieurs cases à cocher et plusieurs sélections. Dans ces cas, il renvoie un tableau.

function getFormData(formId) {
    return $('#' + formId).serializeArray().reduce(function (obj, item) {
        var name = item.name,
            value = item.value;

        if (obj.hasOwnProperty(name)) {
            if (typeof obj[name] == "string") {
                obj[name] = [obj[name]];
                obj[name].push(value);
            } else {
                obj[name].push(value);
            }
        } else {
            obj[name] = value;
        }
        return obj;
    }, {});
}
István
la source
1

montrant les champs des éléments d'entrée du formulaire et le fichier d'entrée pour soumettre votre formulaire sans actualiser la page et saisir toutes les valeurs avec le fichier inclus ici c'est

<form id="imageUploadForm"   action="" method="post" enctype="multipart/form-data">
<input type="text" class="form-control" id="fname" name='fname' placeholder="First Name" >
<input type="text" class="form-control" name='lname' id="lname" placeholder="Last Name">
<input type="number" name='phoneno'  class="form-control" id="phoneno" placeholder="Phone Number">
<textarea class="form-control" name='address' id="address" rows="5" cols="5" placeholder="Your Address"></textarea>
<input type="file" name="file" id="file" >
<input type="submit" id="sub" value="Registration">					   
</form>
sur la page du bouton Soumettre enverra une demande ajax à votre fichier php.
$('#imageUploadForm').on('submit',(function(e) 
{
     fname = $('#fname').val();
     lname =  $('#lname').val();
     address =  $('#address').val();
     phoneno =  $('#phoneno').val();
     file =  $('#file').val();
     e.preventDefault();
     var formData = new FormData(this);
     formData.append('file', $('#file')[0]);
     formData.append('fname',$('#fname').val());
     formData.append('lname',$('#lname').val());
     formData.append('phoneno',$('#phoneno').val());
     formData.append('address',$('#address').val());
     $.ajax({
		type:'POST',
                url: "test.php",
                //url: '<?php echo base_url().'edit_profile/edit_profile2';?>',

                data:formData,
                cache:false,
                contentType: false,
                processData: false,
                success:function(data)
                {
                     alert('Data with file are submitted !');

                }

     });

}))

Mohsin Shoukat
la source
Quel est le besoin de nouveaux FormData ici?
Sahu V Kumar
1
@VishalKumarSahu je télécharge un fichier, c'est pourquoi j'utilise formData pour cela.
Mohsin Shoukat
1
$(form).serializeArray().reduce(function (obj, item) {
      if (obj[item.name]) {
           if ($.isArray(obj[item.name])) {
               obj[item.name].push(item.value);
           } else {
                var previousValue = obj[item.name];
                obj[item.name] = [previousValue, item.value];
           }
      } else {
           obj[item.name] = item.value;
      }

     return obj;
}, {});

Cela résoudra le problème: ne pouvait pas fonctionner avec des sélections multiples.

ke ke
la source
0

Vous n'êtes pas tout à fait correct. Vous ne pouvez pas écrire:

formObj[input.name] = input.value;

Parce que de cette façon, si vous avez une liste multi-sélection - ses valeurs seront remplacées par la dernière, car elles sont transmises comme: "param1": "valeur1", "param1": "valeur2".

Donc, l'approche correcte est:

if (formData[input.name] === undefined) {
    formData[input.name] = input.value;
}
else {
    var inputFieldArray = $.merge([], $.isArray(formData[input.name]) ? formData[input.name] : [formData[input.name]]);
    $.merge(inputFieldArray, [input.value]);
    formData[input.name] = $.merge([], inputFieldArray);
}
Alexandre
la source
0

Cette méthode devrait le faire. Il sérialise les données du formulaire, puis les convertit en objet. Prend également soin des groupes de cases à cocher.

function getFormObj(formId) {
  var formParams = {};
  $('#' + formId)
    .serializeArray()
    .forEach(function(item) {
      if (formParams[item.name]) {
        formParams[item.name] = [formParams[item.name]];
        formParams[item.name].push(item.value)
      } else {
        formParams[item.name] = item.value
      }
    });
  return formParams;
}
user1101791
la source
Fonctionne pour les cases à cocher, mais pas pour les boutons radio où les contrôles partagent l' nameattribut.
Kyle Falconer
0

Voici une belle fonction JS vanille que j'ai écrite pour extraire les données du formulaire en tant qu'objet. Il a également des options pour insérer des ajouts dans l'objet et pour effacer les champs de saisie du formulaire.

const extractFormData = ({ form, clear, add }) => {
  return [].slice.call(form.children).filter(node => node.nodeName === 'INPUT')
  .reduce((formData, input) => {
    const value = input.value
    if (clear) { input.value = '' }
    return {
      ...formData,
      [input.name]: value
    }
  }, add)
}

Voici un exemple de son utilisation avec une demande de publication:

submitGrudge(e) {
  e.preventDefault()

  const form = e.target
  const add = { id: Date.now(), forgiven: false }
  const grudge = extractFormData({ form, add, clear: true })

  // grudge = {
  //  "name": "Example name",
  //  "offense": "Example string",
  //  "date": "2017-02-16",
  //  "id": 1487877281983,
  //  "forgiven": false
  // }

  fetch('http://localhost:3001/api/grudge', {
    method: 'post',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(grudge)
  })
    .then(response => response.json())
    .then(grudges => this.setState({ grudges }))
    .catch(err => console.log('error: ', err))
}
IanLancaster
la source