¿Cómo puedo obtener datos de formulario con JavaScript / jQuery?

404

¿Existe una manera simple y de una línea para obtener los datos de un formulario como lo sería si se presentara en la forma clásica de solo HTML?

Por ejemplo:

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

Salida:

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

Algo como esto es demasiado simple, ya que no incluye (correctamente) áreas de texto, selecciones, botones de opción y casillas de verificación:

$("#form input").each(function () {
    data[theFieldName] = theFieldValue;
});
Bart van Heukelom
fuente
3
Otra pregunta similar a esta: stackoverflow.com/questions/169506/…
Marcelo Rodovalho

Respuestas:

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

manifestación

chelmertz
fuente
15
¿Cerrar, pero tal vez algo que devuelva una matriz con pares clave-valor en lugar de una sola cadena?
Bart van Heukelom
80
Nvm, lo encontré en los comentarios para la función serialize (). Se llama serializeArray. Devuelve una matriz de matrices (que contienen una entrada "nombre" y "valor") pero eso debería ser lo suficientemente fácil de transformar.
Bart van Heukelom
22
Y el uso de la biblioteca de subrayado se puede transformar usando:_.object($("#myform").serializeArray().map(function(v) {return [v.name, v.value];} ))
MhdSyrwan
8
@BartvanHeukelom Sé que esto es 4 años después, pero .serializeArray () devolverá una matriz.
TJ WealthEngine API Evangelist
66
Asegúrese de que cada etiqueta de entrada incluya el atributo de nombre, de lo contrario no devolverá nada.
Eugene Kulabuhov
507

Uso $('form').serializeArray(), que devuelve una matriz :

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

Otra opción es $('form').serialize(), que devuelve una cadena :

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

Echa un vistazo a esta demo jsfiddle

Pablo
fuente
9191
serializeArraysería mucho más útil si devolviera un objeto con pares clave-valor
GetFree
8
Estoy de acuerdo en que un objeto sería ideal. Sin embargo, hay un problema: una clave puede tener múltiples valores. ¿Devolverías un objeto clave- "matriz de valores", o clave- "primer valor" u otra cosa? Creo que los chicos de jQuery no eligieron ninguno de los anteriores :)
Paul
Tenga en cuenta un problema con valores múltiples (como @Paul mencionó anteriormente), las casillas de verificación y las entradas múltiples con name="multiple[]"no funcionan. La solución para el método POST es la misma, solo use $ ('form'). Serialize (). Además, el método POST no tiene un límite de 2000 caracteres como GET en la mayoría de los navegadores, por lo que puede usarse incluso para datos bastante grandes.
Artru
También tenga en cuenta que para registrar un valor de cualquier entrada de formulario, la entrada debe tener un nameatributo.
Chris - Jr
@GetFree ¿por qué no usar la función de mapa jQuery? función getFormData (formulario) {var rawJson = form.serializeArray (); modelo var = {}; $ .map (rawJson, función (n, i) {modelo [n ['nombre']] = n ['valor'];}); modelo de retorno; }
Tom McDonough
196

Respuesta actualizada para 2014: HTML5 FormData hace esto

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

Luego puede publicar formData exactamente como es: contiene todos los nombres y valores utilizados en el formulario.

mikemaccana
fuente
13
Además, uno como FormData es bueno y útil, pero vale la pena señalar que si desea LEER los datos dentro de FormData no es tan fácil (consulte stackoverflow.com/questions/7752188/… )
StackExchange What The Heck
1
Tenga en cuenta que FormData es parte de las características avanzadas de XMLHttpRequest (anteriormente conocido como XMLHttpRequest Level 2), por lo que debe confiar en un polyfill para Internet Explorer <10. caniuse.com/#feat=xhr2
Pier-Luc Gendreau
3
@yochannah, no es así. Claro, uno no puede simplemente acceder y editar los datos como un objeto normal, pero aún es trivial obtener los datos. Consulte el entries()método [página MDN ].
Web and Flow
@Web and Flow gracias por señalar esto! Me encanta cuando los navegadores agregan funciones nuevas y útiles :) veces, están cambiando.
StackExchange What The Heck
Estoy tratando de usar FormData para enviar un objeto a mi script Flask-python, pero no parece venir como un objeto de solicitud normal que pueda descomprimir. ¿Alguien puede señalar una explicación de algún paso especial para manejarlo en el lado del servidor? Ahí es donde me parece vacío.
manisha
181

Basado en jQuery.serializeArray, devuelve pares clave-valor.

var data = $('#form').serializeArray().reduce(function(obj, item) {
    obj[item.name] = item.value;
    return obj;
}, {});
neuront
fuente
12
¡Pares clave-valor aquí, muchachos, todos, vengan aquí! Es de oro !!! ¡Gracias! Si quiero un valor de un elemento llamado "minorista", hago esto console.log ($ ('# form'). SerializeArray (). Reduce (function (obj, item) {obj [item.name] = item. valor; return obj;}, {}) ['minorista']);
Yevgeniy Afanasyev
Creé ayer un método JQuery basado en esta respuesta pero trabajando con múltiples selecciones y matrices de entrada (con el nombre 'ejemplo []'). Puedes encontrarlo en mi respuesta a continuación. De todos modos, buen enfoque neuront, gracias! :)
manuman94
¡Esta fue la que más me gustó, de todas las respuestas!
VPetrovic
¡En mi humilde opinión es la mejor respuesta!
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
});

Esta es una respuesta puntual, pero déjame explicarte por qué esta es una mejor solución:

  • Estamos manejando adecuadamente el envío de un formulario en lugar de presionar un botón. A algunas personas les gusta presionar enter en los campos. Algunas personas usan dispositivos de entrada alternativos, como entrada de voz u otros dispositivos de accesibilidad. Maneje el envío del formulario y lo resuelve correctamente para todos.

  • Estamos investigando los datos del formulario para el formulario real que se envió. Si cambia su selector de formulario más adelante, no tiene que cambiar los selectores para todos los campos. Además, puede tener varias formas con los mismos nombres de entrada. No es necesario desambiguar con ID excesivos y lo que no, simplemente haga un seguimiento de las entradas en función del formulario que se envió. Esto también le permite utilizar un único controlador de eventos para múltiples formularios si es apropiado para su situación.

  • La interfaz FormData es bastante nueva, pero está bien soportada por los navegadores. Es una excelente manera de construir esa recopilación de datos para obtener los valores reales de lo que está en el formulario. Sin él, tendrá que recorrer todos los elementos (como con form.elements) y descubrir qué se verifica, qué no, cuáles son los valores, etc. Totalmente posible si necesita soporte antiguo del navegador, pero FormData La interfaz es más simple.

  • Estoy usando ES6 aquí ... no es un requisito de ninguna manera, así que cámbielo de nuevo para que sea compatible con ES5 si necesita soporte de navegador antiguo.

Puntilla
fuente
Para su información, los objetos FormData no exponen sus valores. Para obtener un objeto simple, consulte stackoverflow.com/questions/41431322/…
phil294
2
@Blauhirn Tonterías, por supuesto, exponen los valores. El código en mi respuesta funciona. Deberías probarlo. Aquí, hice un violín para ti: jsfiddle.net/zv9s1xq5 Si quieres un iterador, úsaloformData.entries() .
Brad
Sé que funciona, pero las propiedades no son accesibles por clave. Por ejemplo, formData.foo no está definido. Como se ve en su respuesta, .get() necesita ser llamado para lo que creo que es inconveniente. Tal vez "no expone" se encontró con el camino equivocado. Por lo tanto, para generar algo parecido { foo: 'bar' }a un submitevento, debe iterar sobre ellos manualmente. De ahí el . To get a plain object from it, see [link].
phil294
1
@ Blauhirn Estás equivocado sobre eso. XMLHttpRequest admite FormData directamente. xhr.send(formData);
Brad
1
@Blauhirn JSON.stringify([...formData]) O, si quieres que tus claves / valores se separen ... [...formData].reduce((prev, cur) => { prev[cur[0]] = cur[1]; return prev;}, {})
Brad
25

use .serializeArray () para obtener los datos en formato de matriz y luego convertirlos en un objeto:

function getFormObj(formId) {
    var formObj = {};
    var inputs = $('#'+formId).serializeArray();
    $.each(inputs, function (i, input) {
        formObj[input.name] = input.value;
    });
    return formObj;
}
Nils
fuente
Esto sobrescribe mis casillas de verificación si tengo algo así <input type="checkbox" name="someList" value="one" /> <input type="checkbox" name="someList" value="two" />. Si ambos están marcados, el objeto solo contiene el segundo valor de casilla de verificación.
dmathisen
2
¿No es este un caso donde someListdebería estar type="radio"?
dylanjameswagner
votar porque la respuesta aceptada no devuelve un objeto con las claves como:name:value
Matt-the-Marxist
24

Aquí hay una solución realmente simple y corta que incluso no requiere 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
fuente
1
Esto no funciona con botones de radio: la última opción es siempre la que está almacenada postData.
Kyle Falconer
3
Gracias por darnos una respuesta que no sea jquery.
Glen Pierce
24

Es 2019 y hay una mejor manera de hacer esto:

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

o si quieres un objeto simple en su lugar

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

aunque tenga en cuenta que esto no funcionará con claves duplicadas como las de las casillas de selección múltiple y duplicadas con el mismo nombre.

fringd
fuente
Totalmente. Sin embargo, no he tenido una matriz para una lista de entradas que todos tienen el mismo nombre que significaba que tenía que usar document.getElementsByClassNamey un bucle pero bueno, todavía más bonito que requiere jQuery etc
alphanumeric0101
1
Esta respuesta es mi favorita. Pero debería leer en document.querySelectorlugar de solo querySelector.
adabru
Nota "FormData solo usará campos de entrada que usan el atributo de nombre" - de MDN
binaryfunt
17
$('#myform').serialize();
Andy Baird
fuente
13
$("#form input, #form select, #form textarea").each(function() {
 data[theFieldName] = theFieldValue;
});

Aparte de eso, es posible que desee mirar serialize () ;

pixeline
fuente
13

Yo uso esto:

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

Formulario HTML

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

Obtenga los datos

var myData = $("#myForm").getFormData();
Dustin Poissant
fuente
Tenga en cuenta que este complemento no funciona para casos en los que hay múltiples entradas de entrada de formulario con el mismo nombre. La última entrada reemplazaría a la anterior, mientras que el comportamiento esperado sería obtener todos los valores como unArray
Milli
1
Solo una nota de que un año después ahora creo que esta es una respuesta terrible y nadie debería usarla. Como dice el comentario anterior, cosas como los botones de opción no funcionarían. Hay mejores respuestas anteriores, use una de ellas en su lugar.
Dustin Poissant
11

Aquí hay una implementación de JavaScript que funciona y que maneja correctamente casillas de verificación, botones de opción y controles deslizantes (probablemente también otros tipos de entrada, pero solo los he probado).

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

Ejemplo de trabajo:

    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>

editar:

Si está buscando una implementación más completa, eche un vistazo a esta sección del proyecto para el que hice esto . Eventualmente actualizaré esta pregunta con la solución completa que se me ocurrió, pero tal vez esto sea útil para alguien.

Kyle Falconer
fuente
1
Buena solución :) Sin embargo, encontré un error, con la función setOrPush. No incluye una comprobación para ver si el destino ya es una matriz, lo que provoca la creación de una matriz anidada profunda en caso de múltiples casillas marcadas con el mismo nombre.
Wouter van Dam
@KyleFalconer ¡Agradable! ¿Por qué no fusionó las cajas del interruptor para la radio y la casilla de verificación? Funcionarán correctamente (supongo).
Ethan
@Ethan Es porque una casilla de verificación puede tener múltiples valores seleccionados y una radio solo puede tener un valor seleccionado, por lo que cambia la forma en que almaceno el valor.
Kyle Falconer
@KyleFalconer Sí, lo entiendo. El código para manejar 'checkbox' también se encarga de la única opción posible para 'radio', en virtud de la rutina 'SetOrPush'.
Ethan
@ Ethan Oh, creo que sé lo que estás diciendo. Podría hacerse de cualquier manera, pero creo que lo hice de esta manera solo porque quería un solo valor, no una matriz de valores.
Kyle Falconer
9

Si está utilizando jQuery, aquí hay una pequeña función que hará lo que está buscando.

Primero, agregue una ID a su formulario (a menos que sea el único formulario en la página, luego puede usar 'formulario' como la consulta 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 salida se vería así:

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

También puede usar los objetos FormData ; El objeto FormData le permite compilar un conjunto de pares clave / valor para enviar utilizando XMLHttpRequest. Está destinado principalmente para su uso en el envío de datos de formularios, pero puede utilizarse independientemente de los formularios para transmitir datos codificados.

        var formElement = document.getElementById("myform_id");
        var formData = new FormData(formElement);
        console.log(formData);
numediaweb
fuente
Gracias, pero ¿y si no tienes identificación? ¿Qué pasa si tiene un formulario como objeto JQuery? var form = $ (this) .closest ('form'); ? Debe var formElement = document.getElementById (formulario [0]); trabaja en cambio tu primera línea? Bueno, no está funcionando, desafortunadamente. ¿Sabes por qué?
Yevgeniy Afanasyev
En realidad, el FormData no es compatible con todos los navegadores :( así que mejor usar un enfoque diferente
numediaweb
Gracias. Usé el último Chrome y aún no funcionaba. Así que fui con la respuesta #neuront desde arriba.
Yevgeniy Afanasyev
6

Esto agregará todos los campos de formulario al objeto de JavaScript "res":

var res = {};
$("#form input, #form select, #form textarea").each(function(i, obj) {
    res[obj.name] = $(obj).val();
})
gamliela
fuente
Probablemente porque esta misma respuesta exacta ya se publicó en 2010.
nathanvda
No lo sabia. Para una respuesta tan corta, esto no es sorprendente. Y aun así, ¿dónde está la referencia?
gamliela
¿Seriamente? ¿No crees mi comentario sin la referencia y ni siquiera puedes mirar la lista de respuestas para ver si son iguales? stackoverflow.com/a/2276469/216513
nathanvda
Pensé que te referías a una respuesta en otra pregunta. Ahora no recuerdo los detalles y mis razones; tal vez porque no es exactamente lo mismo
gamliela
1
Respuesta perfecta para alguien que quiere que funcione para entrada, seleccione múltiples y área de texto. Porque, al usar serializar no obtendrá todos los elementos seleccionados en la etiqueta de selección. Pero, usando .val () obtendrá exactamente lo que desea como una matriz. Respuesta simple y directa.
Sailesh Kotha
6

He incluido la respuesta para devolver también el objeto requerido.

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

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

return model;
}
Tom McDonough
fuente
Esto no manejará matrices en absoluto; foo[bar][] = 'qux'debe serializar a { foo: { bar: [ 'qux' ] } }.
anfetamáquina
6

Basado en la respuesta de neuront, creé un método JQuery simple que obtiene los datos del formulario en pares clave-valor, pero funciona para selecciones múltiples y para entradas de matriz con name = 'example []'.

Así es como se usa:

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

Puede encontrar un ejemplo a continuación de su definición y cómo funciona.

// 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
fuente
5
var formData = new FormData($('#form-id'));
params   = $('#form-id').serializeArray();

$.each(params, function(i, val) {
    formData.append(val.name, val.value);
});
George John
fuente
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;
}
郭润民
fuente
4

puede usar esta función para tener un objeto o un JSON desde el formulario.

para usarlo:

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
fuente
2
Si bien este enlace puede responder la pregunta, es mejor incluir aquí las partes esenciales de la respuesta y proporcionar el enlace como referencia. Las respuestas de solo enlace pueden volverse inválidas si la página vinculada cambia. - De la opinión
Wahyu Kristianto
Pero este enlace tiene una función para ayudar a su (creo). Pero voy a poner el código la próxima vez.
Marcos Costa
3

Escribí una biblioteca para resolver este mismo problema: JSONForms . Toma una forma, revisa cada entrada y crea un objeto JSON que puede leer fácilmente.

Digamos que tiene el siguiente formulario:

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

Pasar el formulario al método de codificación de JSONForms le devuelve el siguiente objeto:

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

Aquí hay una demostración con su formulario.

Cezary Wojtkowski
fuente
Se ve y funciona bien, gracias. Solo una cosa, la versión minificada llama a un archivo de mapa, debe ser opcional 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

antílope
fuente
2

Para aquellos de ustedes que preferirían una Objectcadena en lugar de una cadena serializada (como la que devuelve $(form).serialize(), y una ligera mejora $(form).serializeArray()), no dude en usar el siguiente código:

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

Para ejecutarlo, solo use Form.serialize(form)y la función devolverá una Objectsimilar a esta:

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

Como beneficio adicional, significa que no tiene que instalar todo el paquete de jQuery solo para una función de serialización.

GROVER
fuente
1

Escribí una función que se encarga de múltiples casillas de verificación y múltiples selecciones. En esos casos, devuelve una matriz.

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

mostrando los campos del elemento de entrada del formulario y el archivo de entrada para enviar su formulario sin actualizar la página y tomar todos los valores con el archivo incluido aquí

<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>
en la página del botón Enviar enviará una solicitud ajax a su archivo 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
fuente
¿Cuál es la necesidad de nuevos FormData aquí?
Sahu V Kumar
1
@VishalKumarSahu Estoy cargando un archivo, por eso uso formData para eso.
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;
}, {});

Solucionará el problema: no podría funcionar con multiselecciones.

ke ke
fuente
0

Todos ustedes no son completamente correctos. No puedes escribir:

formObj[input.name] = input.value;

De esta manera, si tiene una lista de selección múltiple, sus valores se sobrescribirán con el último, ya que se transmite como: "param1": "value1", "param1": "value2".

Entonces, el enfoque correcto es:

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);
}
Alejandro
fuente
0

Este método debería hacerlo. Serializa los datos del formulario y luego los convierte en un objeto. También se encarga de grupos de casillas de verificación.

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;
}
usuario1101791
fuente
Funciona para casillas de verificación, pero no para botones de radio donde los controles comparten el nameatributo.
Kyle Falconer
0

Aquí hay una buena función JS de vainilla que escribí para extraer datos de formulario como un objeto. También tiene opciones para insertar adiciones en el objeto y para borrar los campos de entrada del formulario.

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

Aquí hay un ejemplo de su uso con una solicitud de publicación:

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
fuente