Vous vous demandez s'il y a une fonction en javascript sans jquery ou un framework qui me permet de sérialiser le formulaire et d'accéder à la version sérialisée?
La bibliothèque miniature from-serialize ne repose pas sur un framework. En dehors de cela, vous devrez implémenter vous-même la fonction de sérialisation. (bien que d'un poids de 1,2 kilo-octets, pourquoi ne pas l'utiliser?)
Voici l'approche pure JavaScript:
var form = document.querySelector('form');
var data = new FormData(form);
var req = new XMLHttpRequest();
req.send(data);
Bien que cela ne semble fonctionner que pour les demandes POST.
Si vous ciblez les navigateurs qui prennent en charge le constructeur URLSearchParams
( les navigateurs les plus récents ) et le constructeur FormData(formElement)
(navigateurs récents à l'exception de Edge), utilisez ceci:
new URLSearchParams(new FormData(formElement)).toString()
Pour les navigateurs qui supportent URLSearchParams
mais pas le constructeur FormData(formElement)
, utilisez this FormData polyfill et:
new URLSearchParams(Array.from(new FormData(formElement))).toString()
Pour les navigateurs plus anciens (par exemple, IE 10), utilisez le polyfill FormData , un Array.from
si nécessaire, et ce code unique:
Array.from(new FormData(formElement), e => e.map(encodeURIComponent).join('=')).join('&')
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
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 codés en URL. Le remplacement des expressions rationnelles de% 20 caractères n’est effectué qu’une fois, avant que la chaîne ne soit renvoyée.
La chaîne de requête a la même forme que le résultat de la méthode $ .serialize () de jQuery.
J'ai commencé avec la réponse de Johndave Decano.
Cela devrait résoudre quelques-uns des problèmes mentionnés dans les réponses à sa fonction.
Les types de boutons 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))">
Si vous devez envoyer le formulaire "myForm" en utilisant POST au format json, vous pouvez procéder comme suit:
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 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 (). Ce mapFn est appliqué à chaque paire ["a", "b"] et les convertit en {"a": "b"} de sorte que le tableau contienne beaucoup d'objets avec une seule propriété. MapFn utilise la "déstructuration" pour obtenir les noms des première et deuxième parties de la paire, et utilise également un "ComputedPropertyName" ES6 pour définir le nom de la propriété dans l'objet renvoyé par mapFn (c'est pourquoi " x]: quelque chose "plutôt que simplement" x: quelque chose ".
Tous ces objets de propriété uniques sont ensuite passés dans les arguments de la fonction Object.assign () qui fusionne tous les objets de propriété uniques en un seul objet comportant toutes les propriétés.
Array.from (): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
Destructuration des 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 objet littéral JavaScript?
Fonctionne dans tous les navigateurs.
function 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 r = formSerialize(document.querySelector('form'));
console.log(r);
console.log(JSON.stringify(r));
<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="msg">Message:</label>
<textarea id="msg" name="user_message">Hello My Friend</textarea>
</div>
</form>
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é.
Une version refactorisée du code de @ SimonSteinberger utilisant moins de variables et tirant parti de la vitesse des boucles forEach
(qui sont un peu plus rapides que for
s)
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, '+');
}
Si vous souhaitez sérialiser les entrées d'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.
J'ai repensé TibTibs pour répondre à 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);
}
J'ai récupéré la méthode entries () de formData à @moison answer et à MDN il est dit que
La méthode FormData.entries () retourne un itérateur permettant d'aller à travers toutes les paires clé/valeur contenues dans cet objet. La clé de chaque paire est un objet USVString; la valeur soit un USVString, ou un Blob.
mais le seul problème est que le navigateur mobile (Android et Safari ne sont pas pris en charge) et IE et le bureau Safari
mais fondamentalement 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
// 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);
L'utilisation de la fonction de réduction JavaScript devrait faire l'affaire 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;} // if input is checkbox or radio type
acc.Push(o);
return acc;
},[]);
Exemple live ci-dessous.
var _formId = document.getElementById('formId'),
formData = Array.prototype.slice.call(_formId.elements).reduce(function(acc,cur,indx,arr){
var o = {type : cur.type, name : cur.name, value : cur.value};
if(['checkbox','radio'].indexOf(cur.type) !==-1){o.checked = cur.checked;}
acc.Push(o);
return acc;
},[]);
// view
document.getElementById('formOutput').innerHTML = JSON.stringify(formData, null, 4)
<form id="formId">
<input type="text" name="texttype" value="some text">
<select>
<option value="Opt 1">Opt 1</option>
<option value="Opt 2" selected>Opt 2</option>
<option value="Opt 3">Opt 3</option>
</select>
<input type="checkbox" name="checkboxtype" value="Checkbox 1" checked> Checkbox 1
<input type="checkbox" name="checkboxtype" value="Checkbox 2"> Checkbox 2
<input type="radio" name="radiotype" value="Radio Btn 1"> Radio Btn 1
<input type="radio" name="radiotype" value="Radio Btn 2" checked> Radio Btn 2
</form>
<pre><code id="formOutput"></code></pre>
Je pourrais être fou mais je trouve ces réponses sérieusement bouffies. 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);
}
J'espère que ça va marcher
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;
}
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;
}
À des fins de débogage, cela pourrait 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;
}