form sérialiser javascript (pas de framework)

141

Vous vous demandez s'il existe une fonction en javascript sans jquery ou tout autre framework qui me permette de sérialiser le formulaire et d'accéder à la version sérialisée?

RussellHarrower
la source
1
Qu'entendez-vous par «accéder à la version sérialisée»? J'ai développé un script qui n'a pas de dépendances tierces qui peuvent convertir le formulaire HTML en un objet de type JSON qui est multidimensionnel: github.com/serbanghita/formToObject - si cela aide à déposer une réponse
Șerban Ghiță

Réponses:

39

La bibliothèque miniature from-serialize ne repose pas sur un framework. À part quelque chose comme ça, vous devrez implémenter vous-même la fonction de sérialisation. (mais avec un poids de 1,2 kilo-octets, pourquoi ne pas l'utiliser?)

Lusitanien
la source
2
C'était parfait. Mais case 'email':
j'ai
oh, maintenant je vois, googlecode ne fonctionne pas sans javascript. Il crache simplementThat's an error
user1040495
3
Veuillez inclure du code et pas seulement un lien vers une bibliothèque. Si la bibliothèque est open source, vous devriez pouvoir copier le code correspondant.
Luke
171

Voici une approche JavaScript pure:

var form = document.querySelector('form');
var data = new FormData(form);
var req = new XMLHttpRequest();
req.send(data);

Bien que cela semble fonctionner uniquement pour les demandes POST.

https://developer.mozilla.org/en-US/docs/Web/API/FormData

Artur Beljajev
la source
13
Notez que cela envoie plusieurs parties, ce qui fonctionne mal avec certains services REST simples (par exemple, feathers-mongoDB)
Jason McCarrell
Je pense que vous avez raison de dire que cela ne fonctionne qu'avec les requêtes POST. Ce n'était pas immédiatement clair dans la documentation.
manisha
Cela ne fonctionne pas pour moi. La forme est profondément imbriquée. L'objet FormData est vide…
chitzui
Remarque, vous devrez peut-être utiliser req.open("POST", "<your-url>");avant req.send(data);Sinon, j'ai eu l'erreur InvalidStateError: XMLHttpRequest state must be OPENED.sur Firefox 66. Cela devrait fonctionner avec d'autres requêtes aussi comme PUT si vous remplacez POST par PUT.
baptx le
1
Pensez-y: comment pourriez-vous envoyer un objet FormData en utilisant la méthode "GET"? Oui, FormData fonctionne uniquement avec "POST".
Rex the Strange
88

Pour les navigateurs modernes uniquement

Si vous ciblez les navigateurs prenant en charge l' URLSearchParamsAPI ( les navigateurs les plus récents ) et le FormData(formElement)constructeur ( les navigateurs les plus récents sauf Edge ), utilisez ceci:

new URLSearchParams(new FormData(formElement)).toString()

Partout sauf IE

Pour les navigateurs qui prennent en charge URLSearchParamsmais pas le FormData(formElement)constructeur, utilisez ce polyfill FormData et ce code (fonctionne partout sauf IE):

new URLSearchParams(Array.from(new FormData(formElement))).toString()

Exemple

Compatible avec IE 10

Pour les navigateurs encore plus anciens (par exemple IE 10), utilisez le polyfill FormData , un Array.frompolyfill si nécessaire et ce code:

Array.from(
  new FormData(formElement),
  e => e.map(encodeURIComponent).join('=')
).join('&')
glebm
la source
Est-ce .toString()vraiment nécessaire ici?
Ollie Williams
1
Si vous voulez une chaîne et non URLSearchParams , alors oui. La conversion de chaîne se produit également implicitement si vous l'interpolez ou l'ajoutez à une chaîne, auquel cas l' toStringappel explicite n'est pas nécessaire.
glebm
Une seule ligne a fait fonctionnait pas pour moi sur iOS Safari en avril 2018
jchook
Quelle erreur obtenez-vous et de quelle version de Safari s'agit-il? Peut new FormData(formElement)- être n'y est-il pas encore pris en charge?
glebm
@glebm oui ce n'est pas pris en charge dans Safari, avez-vous trouvé une autre solution?
rishiAgar
34
function serialize (form) {
    if (!form || form.nodeName !== "FORM") {
            return;
    }
    var i, j, q = [];
    for (i = form.elements.length - 1; i >= 0; i = i - 1) {
        if (form.elements[i].name === "") {
            continue;
        }
        switch (form.elements[i].nodeName) {
            case 'INPUT':
                switch (form.elements[i].type) {
                    case 'text':
                    case 'tel':
                    case 'email':
                    case 'hidden':
                    case 'password':
                    case 'button':
                    case 'reset':
                    case 'submit':
                        q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                        break;
                    case 'checkbox':
                    case 'radio':
                        if (form.elements[i].checked) {
                                q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                        }                                               
                        break;
                }
                break;
                case 'file':
                break; 
            case 'TEXTAREA':
                    q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                    break;
            case 'SELECT':
                switch (form.elements[i].type) {
                    case 'select-one':
                        q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                        break;
                    case 'select-multiple':
                        for (j = form.elements[i].options.length - 1; j >= 0; j = j - 1) {
                            if (form.elements[i].options[j].selected) {
                                    q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].options[j].value));
                            }
                        }
                        break;
                }
                break;
            case 'BUTTON':
                switch (form.elements[i].type) {
                    case 'reset':
                    case 'submit':
                    case 'button':
                        q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                        break;
                }
                break;
            }
        }
    return q.join("&");
}

Source: http://code.google.com/p/form-serialize/source/browse/trunk/serialize-0.1.js

Johndave Decano
la source
1
Cette sérialisation ne semble pas compatible avec la sérialisation de formulaire standard, où les espaces sont représentés par "+". Ce qui précède utilise uniquement encodeURIComponent , qui encodera l'espace en tant que "% 20". Si la conformité est requise, une expression régulière peut être utilisée à la fin pour convertir "% 20" en "+" avant la transmission.
RobG
3
J'ai ajouté une telle version modifiée à gist.github.com/brettz9/7147458 (avec quelques autres améliorations)
Brett Zamir
3
Les boutons d'envoi ne doivent pas nécessairement être soumis, les boutons de réinitialisation ne doivent jamais être soumis, et les boutons uniquement lorsqu'ils sont utilisés pour l'envoi et sont traités comme un bouton d'envoi dans ce cas. Voir HTML5 4.10.22 Soumission du formulaire .
RobG
ne sérialisez pas les e-mails de type d'entrée.
Ivan le
25

Voici une version légèrement modifiée de TibTibs ':

function serialize(form) {
    var field, s = [];
    if (typeof form == 'object' && form.nodeName == "FORM") {
        var len = form.elements.length;
        for (i=0; i<len; i++) {
            field = form.elements[i];
            if (field.name && !field.disabled && field.type != 'file' && field.type != 'reset' && field.type != 'submit' && field.type != 'button') {
                if (field.type == 'select-multiple') {
                    for (j=form.elements[i].options.length-1; j>=0; j--) {
                        if(field.options[j].selected)
                            s[s.length] = encodeURIComponent(field.name) + "=" + encodeURIComponent(field.options[j].value);
                    }
                } else if ((field.type != 'checkbox' && field.type != 'radio') || field.checked) {
                    s[s.length] = encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value);
                }
            }
        }
    }
    return s.join('&').replace(/%20/g, '+');
}

Les champs désactivés sont ignorés et les noms sont également encodés en URL. Le remplacement de l'expression régulière de% 20 caractères n'a lieu qu'une seule fois, avant de renvoyer la chaîne.

La chaîne de requête est sous une forme identique au résultat de la méthode $ .serialize () de jQuery.

Simon Steinberger
la source
6
+1 pour avoir pris le temps d'améliorer le code. J'aime quand les gens découvrent mes défauts, car c'est une bonne opportunité d'apprentissage. +1 pour le garder aussi beau. -1 parce que je ne peux pas donner +2 = (
TibTibs
1
vous pouvez ajouter à la form.nodeName.toLowerCase() == "form"place deform.nodeName == "FORM"
StefanNch
12

J'ai commencé par la réponse de Johndave Decano.

Cela devrait résoudre quelques-uns des problèmes mentionnés dans les réponses à sa fonction.

  1. Remplacez% 20 par un symbole +.
  2. Les types Soumettre / Bouton ne seront soumis que si vous avez cliqué pour envoyer le formulaire.
  3. Les boutons de réinitialisation seront ignorés.
  4. Le code me semblait redondant car il fait essentiellement la même chose quels que soient les types de champs. Sans parler de l'incompatibilité avec les types de champs HTML5 tels que «tel» et «email», j'ai donc supprimé la plupart des détails avec les instructions switch.

Les types de bouton seront toujours ignorés s'ils n'ont pas de valeur de nom.

function serialize(form, evt){
    var evt    = evt || window.event;
    evt.target = evt.target || evt.srcElement || null;
    var field, query='';
    if(typeof form == 'object' && form.nodeName == "FORM"){
        for(i=form.elements.length-1; i>=0; i--){
            field = form.elements[i];
            if(field.name && field.type != 'file' && field.type != 'reset'){
                if(field.type == 'select-multiple'){
                    for(j=form.elements[i].options.length-1; j>=0; j--){
                        if(field.options[j].selected){
                            query += '&' + field.name + "=" + encodeURIComponent(field.options[j].value).replace(/%20/g,'+');
                        }
                    }
                }
                else{
                    if((field.type != 'submit' && field.type != 'button') || evt.target == field){
                        if((field.type != 'checkbox' && field.type != 'radio') || field.checked){
                            query += '&' + field.name + "=" + encodeURIComponent(field.value).replace(/%20/g,'+');
                        }   
                    }
                }
            }
        }
    }
    return query.substr(1);
}

C'est ainsi que j'utilise actuellement cette fonction.

<form onsubmit="myAjax('http://example.com/services/email.php', 'POST', serialize(this, event))">
TibTibs
la source
6
+1 pour le code joliment remanié. -1 pour ignorer les champs désactivés, qui ne doivent pas apparaître dans la chaîne de requête. +1 pour l'instruction for très élégante, qui évite le comptage répété des éléments de formulaire. Total: +1 :-) Merci!
Simon Steinberger
Bonne note sur les champs désactivés, je suis tombé dessus récemment avec une nouvelle fonction que j'écrivais. +1 à vous deux, car j'aime lire des commentaires amusants. :)
TibTibs
11

Si vous devez soumettre le formulaire "myForm" en utilisant POST au format json, vous pouvez faire:

const formEntries = new FormData(myForm).entries();
const json = Object.assign(...Array.from(formEntries, ([x,y]) => ({[x]:y})));
fetch('/api/foo', {
  method: 'POST',
  body: JSON.stringify(json)
});

La deuxième ligne convertit à partir d'un tableau comme:

[["firstProp", "firstValue"], ["secondProp", "secondValue"], ...and so on... ]

... dans un objet régulier, comme:

{"firstProp": "firstValue", "secondProp": "secondValue", ...and so on ... }

... il effectue cette conversion en passant un mapFn dans Array.from (). Cette mapFn est appliquée à chaque paire ["a", "b"] et les convertit en {"a": "b"} afin que le tableau contienne beaucoup d'objets avec une seule propriété dans chacun. Le mapFn utilise la "déstructuration" pour obtenir les noms des première et deuxième parties de la paire, et il utilise également un ES6 "ComputedPropertyName" pour définir le nom de propriété dans l'objet retourné par le mapFn (c'est pourquoi il est dit "[ x]: quelque chose "plutôt que simplement" x: quelque chose ".

Tous ces objets de propriété uniques sont ensuite passés en arguments de la fonction Object.assign () qui fusionne tous les objets de propriété uniques en un seul objet qui a toutes les propriétés.

Array.fr de (): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

Destructuration dans les paramètres: https://simonsmith.io/destructuring-objects-as-function-parameters-in-es6/

Plus d'informations sur les noms de propriété calculés ici: Variable comme nom de propriété dans un littéral d'objet JavaScript?

Molsson
la source
Cela fonctionne pour moi même si je ne comprends pas la deuxième ligne, pouvez-vous donner plus d'informations à ce sujet s'il vous plaît ??
Espoir Murhabazi
Belle réponse en utilisant l'opérateur de propagation et les méthodes natives Object et Array.
Vinny Fonseca le
Notez que cette approche n'est pas prise en charge dans IE (.entries ())
dude
La page MDN pour Object.entries () a un court polyfill que vous pouvez utiliser pour IE: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... mais IE ne prend pas non plus en charge l'opérateur de propagation.
molsson le
vous pouvez sérialiser le formulaire en utilisant la nouvelle méthode Object.fromEntries (new FormData (myFormElement)).
miguel savignano
10

Fonctionne dans tous les navigateurs.

const formSerialize = formElement => {
  const values = {};
  const inputs = formElement.elements;

  for (let i = 0; i < inputs.length; i++) {
    values[inputs[i].name] = inputs[i].value;
  }
  return values;
}

const dumpValues = form => () => {
  
  const r = formSerialize(form);
  console.log(r);
  console.log(JSON.stringify(r));
}

const form = document.querySelector('form');

dumpValues(form)();

form.addEventListener('change',dumpValues(form));
<form action="/my-handling-form-page" method="post">
  <div>
    <label for="name">Name:</label>
    <input type="text" id="name" name="user_name" value="John">
  </div>
  <div>
    <label for="mail">E-mail:</label>
    <input type="email" id="mail" name="user_mail" value="[email protected]">
  </div>
  <div>
    <label for="interests">Interest:</label>
    <select required=""  id="interests" name="interests">
      <option value="" selected="selected">- None -</option>
      <option value="drums">Drums</option>
      <option value="js">Javascript</option>
      <option value="sports">Sports</option>
      <option value="trekking">Trekking</option>
    </select>
  </div>
  <div>
    <label for="msg">Message:</label>
    <textarea id="msg" name="user_message">Hello My Friend</textarea>
  </div>
</form>

David Lemon
la source
celui-ci fait json, je suppose que l'auteur posait des questions sur la sérialisation en URI.
jaskmar
J'aimerais voir cela fonctionner pour plusieurs formulaires d'options de sélection.
Zach Smith
@ZachSmith Cela fonctionnait déjà, mais j'ai ajouté un exemple pour que vous puissiez le vérifier
David Lemon
8
HTMLElement.prototype.serialize = function(){
    var obj = {};
    var elements = this.querySelectorAll( "input, select, textarea" );
    for( var i = 0; i < elements.length; ++i ) {
        var element = elements[i];
        var name = element.name;
        var value = element.value;

        if( name ) {
            obj[ name ] = value;
        }
    }
    return JSON.stringify( obj );
}

Pour utiliser comme ceci:

var dataToSend = document.querySelector("form").serialize();

J'espère avoir aidé.

Eduardo Borges
la source
3
Ne fonctionnera pas avec les cases à cocher. Ici, vous devez vérifier explicitement le type d'entrée.
Adrian Preuss
5

Si vous cherchez à sérialiser les entrées sur un événement. Voici une approche JavaScript pure que j'utilise.

// serialize form
var data = {};
var inputs = [].slice.call(e.target.getElementsByTagName('input'));
inputs.forEach(input => {
  data[input.name] = input.value;
});

Les données seront un objet JavaScript des entrées.

CAOakley
la source
2
Cela devrait fonctionner sur la plupart des éléments. Certainement pas textarea / select, cependant
jaggedsoft
est-ce que slice.call est identique à Array.from?
user1040495
5

Une version refactorisée du code de @ SimonSteinberger utilisant moins de variables et tirant parti de la vitesse des forEachboucles (qui sont un peu plus rapides que fors)

function serialize(form) {
    var result = [];
    if (typeof form === 'object' && form.nodeName === 'FORM')
        Array.prototype.slice.call(form.elements).forEach(function(control) {
            if (
                control.name && 
                !control.disabled && 
                ['file', 'reset', 'submit', 'button'].indexOf(control.type) === -1
            )
                if (control.type === 'select-multiple')
                    Array.prototype.slice.call(control.options).forEach(function(option) {
                        if (option.selected) 
                            result.push(encodeURIComponent(control.name) + '=' + encodeURIComponent(option.value));
                    });
                else if (
                    ['checkbox', 'radio'].indexOf(control.type) === -1 || 
                    control.checked
                ) result.push(encodeURIComponent(control.name) + '=' + encodeURIComponent(control.value));
        });
        return result.join('&').replace(/%20/g, '+');
}
Stefan Gabos
la source
3

J'ai refactoré la réponse TibTibs en quelque chose de beaucoup plus clair à lire. C'est un peu plus long à cause de la largeur de 80 caractères et de quelques commentaires.

En outre, il ignore les noms de champs vides et les valeurs vides.

// Serialize the specified form into a query string.
//
// Returns a blank string if +form+ is not actually a form element.
function $serialize(form, evt) {
  if(typeof(form) !== 'object' && form.nodeName !== "FORM")
    return '';

  var evt    = evt || window.event || { target: null };
  evt.target = evt.target || evt.srcElement || null;
  var field, query = '';

  // Transform a form field into a query-string-friendly
  // serialized form.
  //
  // [NOTE]: Replaces blank spaces from its standard '%20' representation
  //         into the non-standard (though widely used) '+'.
  var encode = function(field, name) {
    if (field.disabled) return '';

    return '&' + (name || field.name) + '=' +
           encodeURIComponent(field.value).replace(/%20/g,'+');
  }

  // Fields without names can't be serialized.
  var hasName = function(el) {
    return (el.name && el.name.length > 0)
  }

  // Ignore the usual suspects: file inputs, reset buttons,
  // buttons that did not submit the form and unchecked
  // radio buttons and checkboxes.
  var ignorableField = function(el, evt) {
    return ((el.type == 'file' || el.type == 'reset')
        || ((el.type == 'submit' || el.type == 'button') && evt.target != el)
        || ((el.type == 'checkbox' || el.type == 'radio') && !el.checked))
  }

  var parseMultiSelect = function(field) {
    var q = '';

    for (var j=field.options.length-1; j>=0; j--) {
      if (field.options[j].selected) {
        q += encode(field.options[j], field.name);
      }
    }

    return q;
  };

  for(i = form.elements.length - 1; i >= 0; i--) {
    field = form.elements[i];

    if (!hasName(field) || field.value == '' || ignorableField(field, evt))
      continue;

    query += (field.type == 'select-multiple') ? parseMultiSelect(field)
                                               : encode(field);
  }

  return (query.length == 0) ? '' : query.substr(1);
}
Brian Edmonds
la source
J'ai copié ceci directement dans mon application et la sélection multiple ne semble pas fonctionner (les valeurs sont dupliquées)
anastymous
@anastymous Merci pour la capture, cela a été corrigé.
Brian Edmonds
Salut Brian, à quoi sert evt ? et que devrais-je passer pour cela? Firefox me dit qu'il n'est pas défini.
anastymous
Salut anastyme, merci encore pour la capture, cela devrait être corrigé en changeant l'affectation à evt evt = evt || window.event || { target: null };(comme l'édition l'a fait) Le but derrière cela est de transmettre l'événement qui a déclenché la sérialisation, s'il y en a un, comme un formulaire "soumettre" un événement ou un "clic" sur un bouton. Si un formulaire a plusieurs boutons pour l'envoi, vous ne voulez tenir compte que de la valeur du bouton qui a déclenché l'événement et ignorer les autres. J'ai hacké un exemple très rudimentaire de ce comportement sur dump.bedmonds.net/serialize-js
Brian Edmonds
2
  // supports IE8 and IE9 
  function serialize(form) {
    var inputs = form.elements;
    var array = [];
    for(i=0; i < inputs.length; i++) {
      var inputNameValue = inputs[i].name + '=' + inputs[i].value;
      array.push(inputNameValue);
    }
    return array.join('&');
  }
 //using the serialize function written above
 var form = document.getElementById("form");//get the id of your form. i am assuming the id to be named form.
 var form_data = serialize(form);
 var xhr = new XMLHttpRequest();
 xhr.send(form_data);

 //does not work with IE8 AND IE9
 var form = document.querySelector('form');
 var data = new FormData(form);
 var xhr = new XMLHttpRequest();
 xhr.send(data);
Onome Mine Adamu
la source
2

J'ai récupéré la méthode entries () de formData de @moison answer et de MDN, il est dit que:

La méthode FormData.entries () retourne un itérateur permettant de parcourir toutes les paires clé / valeur contenues dans cet objet. La clé de chaque paire est un objet USVString; la valeur soit une USVString, soit un Blob.

mais le seul problème est que le navigateur mobile (Android et Safari ne sont pas pris en charge) et le bureau IE et Safari également

mais en gros voici mon approche:

let theForm =  document.getElementById("contact"); 

theForm.onsubmit = function(event) {
    event.preventDefault();

    let rawData = new FormData(theForm);
    let data = {};

   for(let pair of rawData.entries()) {
     data[pair[0]] = pair[1]; 
    }
    let contactData = JSON.stringify(data);
    console.warn(contactData);
    //here you can send a post request with content-type :'application.json'

};

le code peut être trouvé ici

Espoir Murhabazi
la source
2

L'utilisation de la fonction de réduction de JavaScript devrait faire une astuce pour tous les navigateurs, y compris IE9>:

Array.prototype.slice.call(form.elements) // convert form elements to array
    .reduce(function(acc,cur){   // reduce 
        var o = {type : cur.type, name : cur.name, value : cur.value}; // get needed keys
        if(['checkbox','radio'].indexOf(cur.type) !==-1){
            o.checked = cur.checked;
        } else if(cur.type === 'select-multiple'){
            o.value=[];
            for(i=0;i<cur.length;i++){
                o.value.push({
                    value : cur.options[i].value,
                    selected : cur.options[i].selected
                });
            }
        }
        acc.push(o);
        return acc;
 },[]);

Exemple en direct ci-dessous.

crashtestxxx
la source
cela fonctionne-t-il pour plusieurs sélections? semble lorsque j'utilise votre code, il ne renvoie que le premier élément de la valeur des options multiples sélectionnées
Zach Smith
@ZachSmith J'ai mis à jour ma réponse pour inclure plusieurs éléments de sélection.
crashtestxxx
0

J'espère que cela fonctionnera

var serializeForm = (formElement) => {
  const formData = {};
  const inputs = formElement.elements;

  for (let i = 0; i < inputs.length; i++) {
    if(inputs[i].name!=="")
        formData[inputs[i].name] = inputs[i].value;
  }
  return formData;
}
Manoj Rana
la source
0

Améliorer la réponse de David Lemon.

Cela convertit les données du formulaire en JSON et vous permet de définir le formulaire à partir d'un objet de données.

const main = () => {
  const form = document.forms['info'];
  const data = {
    "user_name"       : "John",
    "user_email"      : "[email protected]",
    "user_created"    : "2020-03-24",
    "user_age"        : 42,
    "user_subscribed" : true,
    "user_interests"  : "sports",
    "user_message"    : "Hello My Friend"
  };

  populateForm(form, data);
  updateJsonView(form);
  form.addEventListener('change', (e) => updateJsonView(form));
}

const getFieldValue = (field, opts) => {
  let type = field.getAttribute('type');
  if (type) {
    switch (type) {
      case 'checkbox':
        return field.checked;
      case 'number':
        return field.value.includes('.')
          ? parseFloat(field.value)
          : parseInt(field.value, 10);
    }
  }
  if (opts && opts[field.name] && opts[field.name].type) {
    switch (opts[field.name].type) {
      case 'int':
        return parseInt(field.value, 10);
      case 'float':
        return parseFloat(field.value);
    }
  }
  return field.value;
}

const setFieldValue = (field, value) => {
  let type = field.getAttribute('type');
  if (type) {
    switch (type) {
      case 'checkbox':
        field.checked = value;
        break;
      default:
        field.value = value;
        break;
    }
  } else {
    field.value = value;
  }
}

const extractFormData = (form, opts) => {
  return Array.from(form.elements).reduce((data, element) => {
    return Object.assign(data, { [element.name] : getFieldValue(element, opts) });
  }, {});
};

const populateForm = (form, data) => {
  return Array.from(form.elements).forEach((element) => {
    setFieldValue(element, data[element.name]);
  });
};

const updateJsonView = (form) => {
  let fieldOptions = {};
  let formData = extractFormData(form, fieldOptions);
  let serializedData = JSON.stringify(formData, null, 2);
  document.querySelector('.json-view').textContent = serializedData;
};

main();
.form-field {
  margin-bottom: 0.5em;
}

.form-field label {
  display: inline-block;
  font-weight: bold;
  width: 7em;
  vertical-align: top;
}

.json-view {
  position: absolute;
  top: 0.667em;
  right: 0.667em;
  border: thin solid grey;
  padding: 0.5em;
  white-space: pre;
  font-family: monospace;
  overflow: scroll-y;
  max-height: 100%;
}
<form name="info" action="/my-handling-form-page" method="post">
  <div class="form-field">
    <label for="name">Name:</label>
    <input type="text" id="name" name="user_name">
  </div>
  <div class="form-field">
    <label for="mail">E-mail:</label>
    <input type="email" id="mail" name="user_email">
  </div>
  <div class="form-field">
    <label for="created">Date of Birth:</label>
    <input type="date" id="created" name="user_created">
  </div>
  <div class="form-field">
    <label for="age">Age:</label>
    <input type="number" id="age" name="user_age">
  </div>
  <div class="form-field">
    <label for="subscribe">Subscribe:</label>
    <input type="checkbox" id="subscribe" name="user_subscribed">
  </div>
  <div class="form-field">
    <label for="interests">Interest:</label>
    <select required=""  id="interests" name="user_interests">
      <option value="" selected="selected">- None -</option>
      <option value="drums">Drums</option>
      <option value="js">Javascript</option>
      <option value="sports">Sports</option>
      <option value="trekking">Trekking</option>
    </select>
  </div>
  <div class="form-field">
    <label for="msg">Message:</label>
    <textarea id="msg" name="user_message"></textarea>
  </div>
</form>
<div class="json-view"></div>

M. Polywhirl
la source
0

Cela pourrait être fait par une fonction très simple comme suit

function serialize(form) {
        let requestArray = [];
        form.querySelectorAll('[name]').forEach((elem) => {
            requestArray.push(elem.name + '=' + elem.value);
        });
        if(requestArray.length > 0)
            return requestArray.join('&');
        else
            return false;
    }

 serialized = serialize(document.querySelector('form'))
  console.log(serialized);
<form>

  <input type='text' name='fname' value='Johne'/>
  <input type='text' name='lname' value='Doe'/>
  <input type='text' name='contact[]' value='99999999'/>
  <input type='text' name='contact[]' value='34423434345'/>

</form>

Anil
la source
0

Voici une approche JavaScript pure:

var form = document.querySelector('form');
var data = new FormData(form);

  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
       console.log(this.responseText);
    }
  };
  xhttp.open("POST", "<YOUR-URL>", true);
  xhttp.send(data);
}
RahmanRezaee
la source
-1
document.serializeForm = function (selector) {
     var dictionary = {};
     var form = document.querySelector(selector);
     var formdata = new FormData(form);
     var done = false;
     var iterator = formdata.entries();
     do {
         var prop = iterator.next();
         if (prop.done && !prop.value) {
             done = true;
         }
         else {
             dictionary[prop.value[0]] = prop.value[1];
         }

     } while (!done);
     return dictionary;
}
Hasan
la source
Cela a l'air soigné, mais cela ne prend pas en compte les boutons radio ou les cases à cocher
Yvonne Aburrow
-1

À des fins de débogage, cela peut vous aider:

function print_form_data(form) {
    const form_data = new FormData(form);

    for (const item of form_data.entries()) {
        console.log(item);
    }

    return false;
}
tobias47n9e
la source
-1

Je pourrais être fou mais je trouve ces réponses sérieusement gonflées. Voici ma solution

function serialiseForm(form) {
  var input = form.getElementsByTagName("input");
  var formData = {};
  for (var i = 0; i < input.length; i++) {
    formData[input[i].name] = input[i].value;
  }
  return formData = JSON.stringify(formData);
}
Michael Sherris Caley
la source
baser votre formulaire pour récupérer des éléments par type d'entrée échouera pour select, et tout
Zach Smith