formulario serializar javascript (sin marco)

141

¿Se pregunta si hay una función en javascript sin jquery o cualquier marco que me permita serializar el formulario y acceder a la versión serializada?

RussellHarrower
fuente
1
¿Qué quiere decir con "acceder a la versión serializada"? Desarrollé un script que no tiene dependencias de terceros que pueden convertir el formulario HTML en un objeto similar a JSON que es multidimensional: github.com/serbanghita/formToObject - si ayuda a dejar caer una respuesta
Șerban Ghiță

Respuestas:

39

La biblioteca en miniatura de serialización no se basa en un marco. Aparte de algo así, deberá implementar la función de serialización usted mismo. (aunque con un peso de 1.2 kilobytes, ¿por qué no usarlo?)

Lusitano
fuente
2
Esto fue perfecto. Pero tuve que agregar un case 'email':en la sección de entrada del código
aravind
oh, ahora veo, googlecode no funciona sin javascript. Simplemente escupeThat's an error
user1040495
3
Incluya un código y no solo un enlace a una biblioteca. Si la biblioteca es de código abierto, debería poder copiar el código correspondiente.
Luke
171

Aquí hay un enfoque de JavaScript puro:

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

Aunque parece estar funcionando solo para solicitudes POST.

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

Artur Beljajev
fuente
13
Tenga en cuenta que esto envía multiparte, que funciona mal con algunos servicios REST simples (es decir, feathers-mongoDB)
Jason McCarrell
Creo que tienes razón en que solo funciona con solicitudes POST. Eso no fue inmediatamente claro por los documentos.
manisha
Esto no funciona para mi. La forma está profundamente anidada. El objeto FormData está vacío ...
chitzui 01 de
Tenga en cuenta que es posible que tenga que usar req.open("POST", "<your-url>");antes. req.send(data);De lo contrario, tuve el error InvalidStateError: XMLHttpRequest state must be OPENED.en Firefox 66. Debería funcionar con otras solicitudes también como PUT si reemplaza POST con PUT.
baptx
1
Piénselo: ¿cómo podría enviar un objeto FormData utilizando el método "GET"? Sí, FormData solo funciona con "POST".
Rex the Strange
88

Solo para navegadores modernos

Si apunta a navegadores que admiten la URLSearchParamsAPI ( navegadores más recientes ) y el FormData(formElement)constructor ( navegadores más recientes, excepto Edge ), use esto:

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

En todas partes excepto IE

Para los navegadores que admiten URLSearchParamspero no el FormData(formElement)constructor, use este polyfill FormData y este código (funciona en todas partes excepto IE):

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

Ejemplo

Compatible con IE 10

Para navegadores incluso más antiguos (por ejemplo, IE 10), use el polyfill FormData , un Array.frompolyfill si es necesario y este código:

Array.from(
  new FormData(formElement),
  e => e.map(encodeURIComponent).join('=')
).join('&')
glebm
fuente
¿Es .toString()realmente necesario aquí?
Ollie Williams
1
Si quieres una cadena y no URLSearchParams, entonces sí. La conversión de cadenas también ocurre implícitamente si la interpola o agrega a una cadena, en cuyo caso la toStringllamada explícita no es necesaria.
glebm
One-liner no funcionó para mí en iOS Safari a partir de abril de 2018
jchook
¿Qué error obtienes y qué versión de Safari es? ¿Quizás new FormData(formElement)todavía no se admite allí?
glebm
@glebm sí, no es compatible con Safari, ¿encontraste alguna otra solución?
rishiAgar 01 de
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("&");
}

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

Johndave Decano
fuente
1
Esa serialización no parece ser compatible con la serialización de forma estándar, donde los espacios están representados por "+". Lo anterior solo usa encodeURIComponent , que codificará el espacio como "% 20". Si se requiere conformidad, se puede usar una expresión regular al final para convertir "% 20" en "+" antes de la transmisión.
RobG
3
He agregado una versión modificada a gist.github.com/brettz9/7147458 (con algunas otras mejoras)
Brett Zamir
3
Los botones de envío no necesariamente deben enviarse, los botones de reinicio nunca deben enviarse, y los botones solo cuando se usan para enviar y se tratan como un botón de envío en ese caso. Consulte HTML5 4.10.22 Envío de formulario .
RobG
no serialice el tipo de entrada de correo electrónico.
Ivan
25

Aquí hay una versión ligeramente modificada 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, '+');
}

Los campos deshabilitados se descartan y los nombres también se codifican en URL. La sustitución de expresiones regulares de% 20 caracteres se realiza solo una vez, antes de devolver la cadena.

La cadena de consulta tiene una forma idéntica al resultado del método $ .serialize () de jQuery.

Simon Steinberger
fuente
66
+1 por tomarse el tiempo para mejorar el código. Disfruto cuando la gente encuentra mis defectos, ya que es una buena oportunidad de aprendizaje. +1 para que se vea bien también. -1 porque no puedo dar +2 = (
TibTibs
1
podría agregar en form.nodeName.toLowerCase() == "form"lugar deform.nodeName == "FORM"
StefanNch
12

Comencé con la respuesta de Johndave Decano.

Esto debería solucionar algunos de los problemas mencionados en las respuestas a su función.

  1. Reemplace% 20 con un símbolo +.
  2. Los tipos de envío / botón solo se enviarán si se hizo clic para enviar el formulario.
  3. Los botones de reinicio serán ignorados.
  4. El código me pareció redundante ya que está haciendo esencialmente lo mismo independientemente de los tipos de campo. Sin mencionar la incompatibilidad con los tipos de campo HTML5 como 'tel' y 'correo electrónico', por lo que eliminé la mayoría de los detalles con las declaraciones de cambio.

Los tipos de botones seguirán siendo ignorados si no tienen un valor de nombre.

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

Así es como estoy usando actualmente esta función.

<form onsubmit="myAjax('http://example.com/services/email.php', 'POST', serialize(this, event))">
TibTibs
fuente
66
+1 para el código bien refactorizado. -1 para ignorar los campos deshabilitados, que no deberían aparecer en la cadena de consulta. +1 para las declaraciones muy elegantes, que evitan el recuento repetido de elementos de formulario. Total: +1 :-) ¡Gracias!
Simon Steinberger
Buena nota sobre los campos deshabilitados, me encontré con esto recientemente con una nueva función que estaba escribiendo. Un +1 a los dos, porque disfruto leyendo comentarios divertidos. :)
TibTibs
11

Si necesita enviar el formulario "myForm" utilizando POST en formato json, puede hacer lo siguiente:

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 segunda línea se convierte de una matriz como:

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

... en un objeto regular, como:

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

... realiza esta conversión pasando un mapFn a Array.from (). Este mapFn se aplica a cada par ["a", "b"] y los convierte en {"a": "b"} para que la matriz contenga muchos objetos con una sola propiedad en cada uno. MapFn está usando "desestructuración" para obtener nombres de la primera y segunda parte del par, y también está usando un "ComputedPropertyName" ES6 para establecer el nombre de propiedad en el objeto devuelto por mapFn (esta es la razón por la que dice "[ x]: algo "en lugar de simplemente" x: algo ".

Todos estos objetos de propiedad única se pasan a los argumentos de la función Object.assign () que combina todos los objetos de propiedad única en un solo objeto que tiene todas las propiedades.

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

Desestructuración en parámetros: https://simonsmith.io/destructuring-objects-as-function-parameters-in-es6/

Más información sobre los nombres de propiedades calculadas aquí: ¿ Variable como el nombre de propiedad en un objeto literal de JavaScript?

molsson
fuente
Funciona para mí, incluso si no entiendo la segunda línea, ¿puede dar más información al respecto, por favor?
Espoir Murhabazi
Hermosa respuesta utilizando operador de propagación y métodos nativos de objetos y matrices.
Vinny Fonseca
Tenga en cuenta que este enfoque no es compatible con IE (.entries ())
amigo
La página MDN para Object.entries () tiene un polyfill corto que puede usar para IE: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… pero IE tampoco es compatible con el operador de propagación.
molsson
puede serializar el formulario utilizando el nuevo método Object.fromEntries (nuevo FormData (myFormElement)).
miguel savignano
10

Funciona en todos los navegadores.

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
fuente
este hace json, supongo que el autor estaba preguntando sobre la serialización a URI.
jaskmar
Me encantaría ver esto funcionando para múltiples formularios de opciones de selección.
Zach Smith
@ZachSmith Ya funcionó, pero agregué un ejemplo para que lo compruebes
David Lemon el
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 );
}

Para usar así:

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

Espero haberte ayudado.

Eduardo Borges
fuente
3
No funcionará con casillas de verificación. Aquí, debe verificar explícitamente el tipo de entrada.
Adrian Preuss
5

Si está buscando serializar las entradas en un evento. Aquí hay un enfoque de JavaScript puro que uso.

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

Los datos serán un objeto JavaScript de las entradas.

CAOakley
fuente
2
Esto debería funcionar en la mayoría de los elementos. Sin embargo, definitivamente no es textarea / select
jaggedsoft
¿Es ese slice.call lo mismo que Array.from?
user1040495
5

Una versión refactorizada del código de @SimonSteinberger usando menos variables y aprovechando la velocidad de los forEachbucles (que son un poco más rápidos 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
fuente
3

Refactivé la respuesta de TibTibs en algo que es mucho más claro de leer. Es un poco más largo debido al ancho de 80 caracteres y algunos comentarios.

Además, ignora los nombres de campo en blanco y los valores en blanco.

// 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
fuente
Copié esto directamente en mi aplicación y la selección múltiple no parece funcionar (los valores están duplicados)
anastymous
@anastymous Gracias por la captura, se ha solucionado.
Brian Edmonds
Hola Brian, ¿ para qué sirve evt ? ¿Y qué debería pasar por ello? Firefox me dice que no está definido.
anastymous
Hola anastymous, gracias de nuevo por la captura, debe solucionarse cambiando la asignación a evt a evt = evt || window.event || { target: null };(como lo ha hecho la edición) El punto detrás de esto es pasar el evento que desencadenó la serialización, si hay una, como un formulario evento "enviar" o "clic" de un botón. Si un formulario tiene varios botones para enviar, solo desea tener en cuenta el valor del botón que activó el evento e ignorar los demás. He pirateado un ejemplo muy rudimentario de este comportamiento en dump.bedmonds.net/serialize-js
Brian Edmonds el
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
fuente
2

Tomé el método de entradas () de formData de @moison answer y de MDN se dice que:

El método FormData.entries () devuelve un iterador que permite recorrer todos los pares clave / valor contenidos en este objeto. La clave de cada par es un objeto USVString; el valor ya sea un USVString o un Blob.

pero el único problema es que el navegador móvil (Android y Safari no son compatibles) y el escritorio IE y Safari también

pero básicamente aquí está mi enfoque:

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'

};

el código se puede encontrar aquí

Espoir Murhabazi
fuente
2

El uso de la función de reducción de JavaScript debería ser un truco para todos los navegadores, incluido 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;
 },[]);

Ejemplo en vivo abajo.

crashtestxxx
fuente
¿funciona esto para selección múltiple? Parece cuando se utiliza el código que devuelve sólo el primer elemento del valor de las opciones múltiples seleccionado
Zach Smith
@ZachSmith He actualizado mi respuesta para incluir múltiples elementos seleccionados.
crashtestxxx
0

Espero que esto funcione

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
fuente
0

Mejorando la respuesta de David Lemon.

Esto convierte los datos del formulario a JSON y le permite configurar el formulario desde un objeto de datos.

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>

Mr. Polywhirl
fuente
0

Esto podría hacerse mediante una función muy simple como sigue

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>

Añil
fuente
0

Aquí hay un enfoque de JavaScript puro:

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
fuente
-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
fuente
Parece ordenado, pero no tiene en cuenta los botones de opción ni las casillas de verificación
Yvonne Aburrow
-1

Para fines de depuración, esto podría ayudarlo a:

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

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

    return false;
}
tobias47n9e
fuente
-1

Podría estar loco, pero estoy encontrando estas respuestas muy hinchadas. Aquí está mi solución.

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
fuente
basar su formulario para recuperar elementos por tipo de entrada fallará select, y todo
Zach Smith