Tengo un formulario con muchos campos de entrada.
Cuando capturo el evento de envío de formulario con jQuery, ¿es posible obtener todos los campos de entrada de ese formulario en una matriz asociativa?
Tengo un formulario con muchos campos de entrada.
Cuando capturo el evento de envío de formulario con jQuery, ¿es posible obtener todos los campos de entrada de ese formulario en una matriz asociativa?
Respuestas:
$('#myForm').submit(function() {
// get all the inputs into an array.
var $inputs = $('#myForm :input');
// not sure if you wanted this, but I thought I'd add it.
// get an associative array of just the values.
var values = {};
$inputs.each(function() {
values[this.name] = $(this).val();
});
});
Gracias al consejo de Simon_Weaver, aquí hay otra forma de hacerlo, usando serializeArray
:
var values = {};
$.each($('#myForm').serializeArray(), function(i, field) {
values[field.name] = field.value;
});
Tenga en cuenta que este fragmento fallará en los <select multiple>
elementos.
Parece que las nuevas entradas de formulario HTML 5 no funcionan con serializeArray
jQuery versión 1.3. Esto funciona en la versión 1.4+
name
y value
. Una mejor solución podría ser procesar la salida de serializeArray en el formato requerido.
<select>
elementos? Lo intenté var $inputs = $('#new-ticket :input, :select');
pero eso no funciona. ¿Alguien sabe la forma correcta de hacer esto porque no creo que lo esté haciendo bien?
$("#new-ticket :input, #new-ticket :select")
, o incluso mejor,$(":input, :select", "#new-ticket")
Tarde a la fiesta en esta pregunta, pero esto es aún más fácil:
$('#myForm').submit(function() {
// Get all the forms elements and their values in one step
var values = $(this).serialize();
});
.serialize()
( api.jquery.com/serialize ) coloca todos los elementos del formulario en una sola cadena lista para agregar a una URL en una cadena de consulta, esencialmente imitando una solicitud de formulario GET. Esto no lograría lo que logra la respuesta de nickf.
.serialize()
también funciona solo con elementos de formulario. Por $('form select').serialize()
lo tanto , serializará los datos solo para las selecciones.
$('#myForm')
, use $ (this).
El complemento jquery.form puede ayudar con lo que otros buscan y que terminan en esta pregunta. No estoy seguro de si hace directamente lo que quieres o no.
También existe la función serializeArray .
A veces encuentro que obtener uno a la vez es más útil. Para eso, hay esto:
var input_name = "firstname";
var input = $("#form_id :input[name='"+input_name+"']");
[0].value
esto, es decir, $(...)[0].value;
me dio el valor de la entrada directamente, ¡gracias!
Aquí hay otra solución, de esta manera puede obtener todos los datos sobre el formulario y usarlo en una llamada del servidor o algo así.
$('.form').on('submit', function( e )){
var form = $( this ), // this will resolve to the form submitted
action = form.attr( 'action' ),
type = form.attr( 'method' ),
data = {};
// Make sure you use the 'name' field on the inputs you want to grab.
form.find( '[name]' ).each( function( i , v ){
var input = $( this ), // resolves to current input element.
name = input.attr( 'name' ),
value = input.val();
data[name] = value;
});
// Code which makes use of 'data'.
e.preventDefault();
}
Luego puede usar esto con llamadas ajax:
function sendRequest(action, type, data) {
$.ajax({
url: action,
type: type,
data: data
})
.done(function( returnedHtml ) {
$( "#responseDiv" ).append( returnedHtml );
})
.fail(function() {
$( "#responseDiv" ).append( "This failed" );
});
}
Espero que esto sea de utilidad para cualquiera de ustedes :)
Tuve un problema similar con un ligero giro y pensé en tirar esto. Tengo una función de devolución de llamada que obtiene el formulario, por lo que ya tenía un objeto de formulario y no podía tener variantes fáciles $('form:input')
. En cambio, se me ocurrió:
var dataValues = {};
form.find('input').each(
function(unusedIndex, child) {
dataValues[child.name] = child.value;
});
Es una situación similar pero no idéntica, pero este hilo me pareció muy útil y pensé en meterlo al final y esperar que alguien más lo encontrara útil.
¿De asociación? No sin un poco de trabajo, pero puede usar selectores genéricos:
var items = new Array();
$('#form_id:input').each(function (el) {
items[el.name] = el;
});
jQuery's serializeArray
no incluye campos deshabilitados, así que si los necesita también, intente:
var data = {};
$('form.my-form').find('input, textarea, select').each(function(i, field) {
data[field.name] = field.value;
});
http://api.jquery.com/serializearray/
$('#form').on('submit', function() {
var data = $(this).serializeArray();
});
Esto también se puede hacer sin jQuery utilizando el objeto XMLHttpRequest Level 2 FormData
http://www.w3.org/TR/2010/WD-XMLHttpRequest2-20100907/#the-formdata-interface
var data = new FormData([form])
No olvide las casillas de verificación y los botones de opción.
var inputs = $("#myForm :input");
var obj = $.map(inputs, function(n, i) {
var o = {};
if (n.type == "radio" || n.type == "checkbox")
o[n.id] = $(n).attr("checked");
else
o[n.id] = $(n).val();
return o;
});
return obj
Este código funcionará en lugar del nombre, ingrese por correo electrónico el nombre de los campos de su formulario
$(document).ready(function(){
$("#form_id").submit(function(event){
event.preventDefault();
var name = $("input[name='name']",this).val();
var email = $("input[name='email']",this).val();
});
});
Parece extraño que nadie haya votado o propuesto una solución concisa para obtener datos de la lista. Casi ninguna forma será un objeto unidimensional.
La desventaja de esta solución es, por supuesto, que tendrá que acceder a sus objetos singleton en el índice [0]. Pero IMO es mucho mejor que usar una de las soluciones de mapeo de docenas de líneas.
var formData = $('#formId').serializeArray().reduce(function (obj, item) {
if (obj[item.name] == null) {
obj[item.name] = [];
}
obj[item.name].push(item.value);
return obj;
}, {});
La misma solución dada por nickf , pero teniendo en cuenta los nombres de entrada de matriz, por ejemplo
<input type="text" name="array[]" />
values = {};
$("#something :input").each(function() {
if (this.name.search(/\[\]/) > 0) //search for [] in name
{
if (typeof values[this.name] != "undefined") {
values[this.name] = values[this.name].concat([$(this).val()])
} else {
values[this.name] = [$(this).val()];
}
} else {
values[this.name] = $(this).val();
}
});
Si necesita obtener múltiples valores de las entradas y está usando [] 's para definir las entradas con múltiples valores, puede usar lo siguiente:
$('#contentform').find('input, textarea, select').each(function(x, field) {
if (field.name) {
if (field.name.indexOf('[]')>0) {
if (!$.isArray(data[field.name])) {
data[field.name]=new Array();
}
data[field.name].push(field.value);
} else {
data[field.name]=field.value;
}
}
});
Inspirado por las respuestas de Lance Rushing y Simon_Weaver , esta es mi solución favorita.
$('#myForm').submit( function( event ) {
var values = $(this).serializeArray();
// In my case, I need to fetch these data before custom actions
event.preventDefault();
});
La salida es una matriz de objetos, p. Ej.
[{name: "start-time", value: "11:01"}, {name: "end-time", value: "11:11"}]
Con el siguiente código,
var inputs = {};
$.each(values, function(k, v){
inputs[v.name]= v.value;
});
su salida final sería
{"start-time":"11:01", "end-time":"11:01"}
Estoy usando este código sin cada bucle:
$('.subscribe-form').submit(function(e){
var arr=$(this).serializeArray();
var values={};
for(i in arr){values[arr[i]['name']]=arr[i]['value']}
console.log(values);
return false;
});
Espero que esto sea útil, así como el más fácil.
$("#form").submit(function (e) {
e.preventDefault();
input_values = $(this).serializeArray();
});
Cuando necesitaba hacer una llamada ajax con todos los campos del formulario, tuve problemas con el : selector de entrada que devuelve todas las casillas de verificación, estén o no marcadas. Agregué un nuevo selector para obtener los elementos de formulario que se pueden enviar:
$.extend($.expr[':'],{
submitable: function(a){
if($(a).is(':checkbox:not(:checked)'))
{
return false;
}
else if($(a).is(':input'))
{
return true;
}
else
{
return false;
}
}
});
uso:
$('#form_id :submitable');
Sin embargo, aún no lo he probado con varios cuadros de selección, pero funciona para obtener todos los campos de formulario de la forma en que lo haría un envío estándar.
Lo utilicé al personalizar las opciones del producto en un sitio de OpenCart para incluir casillas de verificación y campos de texto, así como el tipo de cuadro de selección estándar.
serialize () es el mejor método. @ Christopher Parker dice que la respuesta de Nickf logra más, sin embargo, no tiene en cuenta que el formulario puede contener área de texto y menús seleccionados. Es mucho mejor usar serialize () y luego manipular eso como sea necesario. Los datos de serialize () se pueden usar en una publicación de Ajax o get, por lo que no hay ningún problema allí.
Espero que esto ayude a alguien. :)
// This html:
// <form id="someCoolForm">
// <input type="text" class="form-control" name="username" value="...." />
//
// <input type="text" class="form-control" name="profile.first_name" value="...." />
// <input type="text" class="form-control" name="profile.last_name" value="...." />
//
// <input type="text" class="form-control" name="emails[]" value="..." />
// <input type="text" class="form-control" name="emails[]" value=".." />
// <input type="text" class="form-control" name="emails[]" value="." />
// </form>
//
// With this js:
//
// var form1 = parseForm($('#someCoolForm'));
// console.log(form1);
//
// Will output something like:
// {
// username: "test2"
// emails:
// 0: ".@....com"
// 1: "...@........com"
// profile: Object
// first_name: "..."
// last_name: "..."
// }
//
// So, function below:
var parseForm = function (form) {
var formdata = form.serializeArray();
var data = {};
_.each(formdata, function (element) {
var value = _.values(element);
// Parsing field arrays.
if (value[0].indexOf('[]') > 0) {
var key = value[0].replace('[]', '');
if (!data[key])
data[key] = [];
data[value[0].replace('[]', '')].push(value[1]);
} else
// Parsing nested objects.
if (value[0].indexOf('.') > 0) {
var parent = value[0].substring(0, value[0].indexOf("."));
var child = value[0].substring(value[0].lastIndexOf(".") + 1);
if (!data[parent])
data[parent] = {};
data[parent][child] = value[1];
} else {
data[value[0]] = value[1];
}
});
return data;
};
Todas las respuestas son buenas, pero si hay un campo que le gustaría ignorar en esa función. Fácil, dele al campo una propiedad, por ejemplo ignore_this:
<input type="text" name="some_name" ignore_this>
Y en su función de serialización:
if(!$(name).prop('ignorar')){
do_your_thing;
}
Así es como ignoras algunos campos.
$('.mandatory');
y!$('.mandatory');
ignore_this
a en data-ignore-this="true"
lugar de crear sus propios atributos que no validen w3c
Prueba el siguiente código:
jQuery("#form").serializeArray().filter(obje =>
obje.value!='').map(aobj=>aobj.name+"="+aobj.value).join("&")
Para múltiples elementos seleccionados ( <select multiple="multiple">
), modifiqué la solución de @Jason Norwood-Young para que funcione.
La respuesta (tal como se publicó) solo toma el valor del primer elemento que se seleccionó, no todos . Tampoco se inicializó ni regresó data
, el primero arrojó un error de JavaScript.
Aquí está la nueva versión:
function _get_values(form) {
let data = {};
$(form).find('input, textarea, select').each(function(x, field) {
if (field.name) {
if (field.name.indexOf('[]') > 0) {
if (!$.isArray(data[field.name])) {
data[field.name] = new Array();
}
for (let i = 0; i < field.selectedOptions.length; i++) {
data[field.name].push(field.selectedOptions[i].value);
}
} else {
data[field.name] = field.value;
}
}
});
return data
}
Uso:
_get_values($('#form'))
Nota: Solo necesita asegurarse de que el name
de su selección se haya []
agregado al final, por ejemplo:
<select name="favorite_colors[]" multiple="multiple">
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</select>