Eu tenho um formulário com muitos campos de entrada.
Quando eu pego o evento de envio de formulário com o jQuery, é possível obter todos os campos de entrada desse formulário em uma matriz associativa?
Eu tenho um formulário com muitos campos de entrada.
Quando eu pego o evento de envio de formulário com o jQuery, é possível obter todos os campos de entrada desse formulário em uma matriz associativa?
Respostas:
$('#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();
});
});
Graças à dica de Simon_Weaver, aqui está outra maneira de fazer isso, usando serializeArray
:
var values = {};
$.each($('#myForm').serializeArray(), function(i, field) {
values[field.name] = field.value;
});
Observe que este trecho falhará nos <select multiple>
elementos.
Parece que as novas entradas de formulário HTML 5 não funcionam serializeArray
no jQuery versão 1.3. Isso funciona na versão 1.4 ou superior
name
e value
. Uma solução melhor pode ser processar a saída do serializeArray para qualquer formato necessário.
<select>
elementos? Eu tentei, var $inputs = $('#new-ticket :input, :select');
mas isso não funciona. Alguém sabe a maneira correta de fazer isso, porque eu não acho que estou fazendo certo.
$("#new-ticket :input, #new-ticket :select")
, ou até melhor,$(":input, :select", "#new-ticket")
Tarde para a parte sobre esta questão, mas isso é ainda mais 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 os elementos do formulário em uma única sequência pronta para anexar a um URL em uma sequência de consulta, imitando essencialmente uma solicitação de formulário GET. Isso não alcançaria o que a resposta de nickf realiza.
.serialize()
também funciona apenas em elementos de formulário. Então $('form select').serialize()
, serializará os dados apenas para selects.
$('#myForm')
, use $ (this).
O plugin jquery.form pode ajudar com o que os outros estão procurando e acabam nessa questão. Não tenho certeza se ele faz diretamente o que você quer ou não.
Há também a função serializeArray .
Às vezes, acho que conseguir um de cada vez é mais útil. Para isso, existe o seguinte:
var input_name = "firstname";
var input = $("#form_id :input[name='"+input_name+"']");
[0].value
a isto, ou seja, $(...)[0].value;
me deu o valor da entrada diretamente, obrigado!
Aqui está outra solução, desta forma, você pode buscar todos os dados sobre o formulário e usá-los em uma chamada do servidor ou algo assim.
$('.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();
}
Você pode usar isso com chamadas 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 seja útil para qualquer um de vocês :)
Teve um problema semelhante com uma ligeira torção e pensei em jogar isso fora. Eu tenho uma função de retorno de chamada que obtém o formulário, então eu já tinha um objeto de formulário e não podia facilitar as variantes $('form:input')
. Em vez disso, eu vim com:
var dataValues = {};
form.find('input').each(
function(unusedIndex, child) {
dataValues[child.name] = child.value;
});
É uma situação semelhante, mas não idêntica, mas achei esse tópico muito útil e pensei em colocar isso no final e espero que alguém o ache útil.
Associativo? Não sem algum trabalho, mas você pode usar seletores genéricos:
var items = new Array();
$('#form_id:input').each(function (el) {
items[el.name] = el;
});
O jQuery serializeArray
não inclui campos desativados; portanto, se você também precisar deles, tente:
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();
});
Isso também pode ser feito sem jQuery usando o objeto FormData XMLHttpRequest nível 2
http://www.w3.org/TR/2010/WD-XMLHttpRequest2-20100907/#the-formdata-interface
var data = new FormData([form])
Não esqueça as caixas de seleção e os botões de opção -
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 trecho de código funcionará em vez de nome; e-mail, digite o nome dos campos do formulário
$(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 estranho que ninguém tenha votado ou proposto uma solução concisa para obter dados da lista. Dificilmente quaisquer formulários serão objetos de dimensão única.
A desvantagem desta solução é que seus objetos singleton precisarão ser acessados no índice [0]. Mas a IMO é muito melhor do que usar uma das soluções de mapeamento de doze linhas.
var formData = $('#formId').serializeArray().reduce(function (obj, item) {
if (obj[item.name] == null) {
obj[item.name] = [];
}
obj[item.name].push(item.value);
return obj;
}, {});
A mesma solução dada pelo nickf , mas com os nomes de entrada da matriz levados em consideração, por exemplo
<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();
}
});
Se você precisar obter vários valores de entradas e estiver usando [] para definir as entradas com vários valores, poderá usar o seguinte:
$('#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;
}
}
});
Inspirada nas respostas de Lance Rushing e Simon_Weaver , esta é a minha solução favorita.
$('#myForm').submit( function( event ) {
var values = $(this).serializeArray();
// In my case, I need to fetch these data before custom actions
event.preventDefault();
});
A saída é uma matriz de objetos, por exemplo
[{name: "start-time", value: "11:01"}, {name: "end-time", value: "11:11"}]
Com o código abaixo,
var inputs = {};
$.each(values, function(k, v){
inputs[v.name]= v.value;
});
sua produção final seria
{"start-time":"11:01", "end-time":"11:01"}
Eu estou usando esse código sem cada loop:
$('.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 isso seja útil, assim como o mais fácil.
$("#form").submit(function (e) {
e.preventDefault();
input_values = $(this).serializeArray();
});
Quando precisei fazer uma chamada ajax com todos os campos do formulário, tive problemas com o seletor : input retornando todas as caixas de seleção, independentemente de terem sido marcadas ou não. Adicionei um novo seletor para obter apenas os elementos do formulário que podem ser submetidos:
$.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');
Ainda não testei com várias caixas de seleção, mas funciona para obter todos os campos do formulário da maneira que um envio padrão faria.
Usei isso ao personalizar as opções do produto em um site OpenCart para incluir caixas de seleção e campos de texto, além do tipo de caixa de seleção padrão.
serialize () é o melhor método. @ Christopher Parker diz que a resposta de Nickf realiza mais, no entanto, não leva em conta que o formulário pode conter área de texto e selecionar menus. É muito melhor usar serialize () e manipular isso conforme necessário. Os dados de serialize () podem ser usados em uma postagem do Ajax ou em get, portanto, não há problema nisso.
Espero que isso ajude alguém. :)
// 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 as respostas são boas, mas se houver um campo que você gostaria de ignorar nessa função? Fácil, atribua uma propriedade ao campo, por exemplo ignore_this:
<input type="text" name="some_name" ignore_this>
E na sua função Serialize:
if(!$(name).prop('ignorar')){
do_your_thing;
}
É assim que você ignora alguns campos.
$('.mandatory');
E!$('.mandatory');
ignore_this
a data-ignore-this="true"
vez de criar seus próprios atributos que não fazer W3C validar
Tente o seguinte código:
jQuery("#form").serializeArray().filter(obje =>
obje.value!='').map(aobj=>aobj.name+"="+aobj.value).join("&")
Para vários elementos selecionados ( <select multiple="multiple">
), modifiquei a solução de @Jason Norwood-Young para fazê-la funcionar.
A resposta (conforme publicada) assume apenas o valor do primeiro elemento que foi selecionado, nem todos . Também não inicializou ou retornou data
, o primeiro gerando um erro de JavaScript.
Aqui está a nova versão:
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: Você só precisa garantir que o name
seu select foi []
anexado ao final dele, por exemplo:
<select name="favorite_colors[]" multiple="multiple">
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</select>