Ho un modulo con molti campi di input.
Quando rilevo l'evento di invio modulo con jQuery, è possibile ottenere tutti i campi di input di quel modulo in un array associativo?
Ho un modulo con molti campi di input.
Quando rilevo l'evento di invio modulo con jQuery, è possibile ottenere tutti i campi di input di quel modulo in un array associativo?
Risposte:
$('#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();
});
});
Grazie al suggerimento di Simon_Weaver, ecco un altro modo per farlo, usando serializeArray
:
var values = {};
$.each($('#myForm').serializeArray(), function(i, field) {
values[field.name] = field.value;
});
Nota che questo frammento fallirà sugli <select multiple>
elementi.
Sembra che i nuovi input del modulo HTML 5 non funzionino con serializeArray
jQuery versione 1.3. Funziona con la versione 1.4+
name
e value
. Una soluzione migliore potrebbe essere quella di elaborare l'output di serializeArray in qualunque formato sia richiesto.
<select>
elementi? Ci ho provato var $inputs = $('#new-ticket :input, :select');
ma non funziona. Qualcuno conosce il modo corretto di farlo perché non penso di farlo nel modo giusto.
$("#new-ticket :input, #new-ticket :select")
, o meglio,$(":input, :select", "#new-ticket")
In ritardo alla festa su questa domanda, ma questo è ancora più semplice:
$('#myForm').submit(function() {
// Get all the forms elements and their values in one step
var values = $(this).serialize();
});
.serialize()
( api.jquery.com/serialize ) inserisce tutti gli elementi del modulo in una singola stringa pronta per l'aggiunta a un URL in una stringa di query, essenzialmente imitando una richiesta di modulo GET. Ciò non compirebbe ciò che la risposta di Nickf realizza.
.serialize()
funziona anche solo su elementi di forma. Quindi $('form select').serialize()
serializzerà i dati solo per le selezioni.
$('#myForm')
, usa $ (questo).
Il plugin jquery.form può aiutare con ciò che gli altri stanno cercando che finiscono con questa domanda. Non sono sicuro se fa direttamente quello che vuoi o no.
C'è anche la funzione serializeArray .
A volte trovo che ottenerne uno alla volta sia più utile. Per questo, c'è questo:
var input_name = "firstname";
var input = $("#form_id :input[name='"+input_name+"']");
[0].value
a questo, cioè, $(...)[0].value;
mi ha dato direttamente il valore dell'input, grazie!
Ecco un'altra soluzione, in questo modo è possibile recuperare tutti i dati sul modulo e utilizzarlo in una chiamata sul server o qualcosa del genere.
$('.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();
}
È quindi possibile utilizzare questo con le chiamate 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" );
});
}
Spero che questo sia di qualche utilità per qualcuno di voi :)
Ho avuto un problema simile con una leggera svolta e ho pensato di buttarlo fuori. Ho una funzione di callback che ottiene il modulo, quindi avevo già un oggetto modulo e non potevo scegliere le varianti $('form:input')
. Invece ho trovato:
var dataValues = {};
form.find('input').each(
function(unusedIndex, child) {
dataValues[child.name] = child.value;
});
È una situazione simile ma non identica, ma ho trovato questa discussione molto utile e ho pensato di riporla alla fine e spero che qualcun altro l'abbia trovata utile.
Associativo? Non senza alcun lavoro, ma puoi utilizzare selettori generici:
var items = new Array();
$('#form_id:input').each(function (el) {
items[el.name] = el;
});
jQuery serializeArray
non include campi disabilitati, quindi se hai bisogno anche di quelli, prova:
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();
});
Questo può essere fatto anche senza jQuery usando l'oggetto FormData di livello 2 XMLHttpRequest
http://www.w3.org/TR/2010/WD-XMLHttpRequest2-20100907/#the-formdata-interface
var data = new FormData([form])
Non dimenticare le caselle di controllo e i pulsanti di opzione -
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
Questo pezzo di codice funzionerà invece del nome, e-mail inserisci il nome dei campi del modulo
$(document).ready(function(){
$("#form_id").submit(function(event){
event.preventDefault();
var name = $("input[name='name']",this).val();
var email = $("input[name='email']",this).val();
});
});
Sembra strano che nessuno abbia votato o proposto una soluzione concisa per ottenere i dati dell'elenco. Quasi nessuna forma sarà un oggetto a dimensione singola.
Il rovescio della medaglia di questa soluzione è, ovviamente, che sarà necessario accedere ai tuoi oggetti singleton nell'indice [0]. Ma IMO è molto meglio che usare una delle soluzioni di mappatura a dozzina di linee.
var formData = $('#formId').serializeArray().reduce(function (obj, item) {
if (obj[item.name] == null) {
obj[item.name] = [];
}
obj[item.name].push(item.value);
return obj;
}, {});
Stessa soluzione fornita da nickf , ma con i nomi di input dell'array presi in considerazione, ad es
<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 è necessario ottenere più valori dagli input e si utilizzano [] per definire gli input con più valori, è possibile utilizzare quanto segue:
$('#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;
}
}
});
Ispirata dalle risposte di Lance Rushing e Simon_Weaver , questa è la mia soluzione preferita.
$('#myForm').submit( function( event ) {
var values = $(this).serializeArray();
// In my case, I need to fetch these data before custom actions
event.preventDefault();
});
L'output è una matrice di oggetti, ad es
[{name: "start-time", value: "11:01"}, {name: "end-time", value: "11:11"}]
Con il codice qui sotto,
var inputs = {};
$.each(values, function(k, v){
inputs[v.name]= v.value;
});
il suo risultato finale sarebbe
{"start-time":"11:01", "end-time":"11:01"}
Sto usando questo codice senza ogni ciclo:
$('.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;
});
Spero che sia utile, oltre che più semplice.
$("#form").submit(function (e) {
e.preventDefault();
input_values = $(this).serializeArray();
});
Quando avevo bisogno di fare una chiamata Ajax con tutti i campi del modulo, ho avuto problemi con il selettore di input che restituiva tutte le caselle di controllo, indipendentemente dal fatto che fossero selezionate. Ho aggiunto un nuovo selettore per ottenere solo gli elementi del modulo che possono essere inviati:
$.extend($.expr[':'],{
submitable: function(a){
if($(a).is(':checkbox:not(:checked)'))
{
return false;
}
else if($(a).is(':input'))
{
return true;
}
else
{
return false;
}
}
});
utilizzo:
$('#form_id :submitable');
Non l'ho ancora testato con più caselle di selezione, ma funziona per ottenere tutti i campi del modulo come farebbe un invio standard.
L'ho usato durante la personalizzazione delle opzioni del prodotto su un sito OpenCart per includere caselle di controllo e campi di testo, nonché il tipo di casella di selezione standard.
serialize () è il metodo migliore. @ Christopher Parker afferma che la risposta di Nickf offre di più, tuttavia non tiene conto del fatto che il modulo può contenere textarea e selezionare menu. È molto meglio usare serialize () e quindi manipolarlo come è necessario. I dati di serialize () possono essere utilizzati in un post Ajax o get, quindi non vi è alcun problema.
Spero che questo aiuti qualcuno. :)
// 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;
};
Tutte le risposte sono buone, ma se c'è un campo che ti piace ignorare in quella funzione? Facile, dai al campo una proprietà, ad esempio ignore_this:
<input type="text" name="some_name" ignore_this>
E nella tua funzione Serialize:
if(!$(name).prop('ignorar')){
do_your_thing;
}
Questo è il modo in cui ignori alcuni campi.
$('.mandatory');
e!$('.mandatory');
ignore_this
al data-ignore-this="true"
posto di creare i propri attributi che non lo fanno w3c validate
Prova il seguente codice:
jQuery("#form").serializeArray().filter(obje =>
obje.value!='').map(aobj=>aobj.name+"="+aobj.value).join("&")
Per più elementi di selezione (<select multiple="multiple">
), ho modificato la soluzione da @Jason Norwood-Young per farlo funzionare.
La risposta (come pubblicata) prende solo il valore dal primo elemento che è stato selezionato, non tutti . Inoltre non è stato inizializzato o restituitodata
, il primo ha generato un errore JavaScript.
Ecco la nuova versione:
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: devi solo assicurarti che la name
tua selezione sia stata []
aggiunta alla fine, ad esempio:
<select name="favorite_colors[]" multiple="multiple">
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</select>