Dapatkan kolom input formulir menggunakan jQuery?

412

Saya memiliki formulir dengan banyak kolom input.

Ketika saya menangkap acara ajukan formulir dengan jQuery, apakah mungkin untuk mendapatkan semua bidang input formulir itu dalam array asosiatif?

Vasil
sumber
23
Itu pertanyaan yang bagus; pada kenyataannya, saya merasa sangat aneh bahwa jQuery tidak memiliki fungsi yang melakukan ini. Ada beberapa fungsi untuk mendapatkan data formulir dalam dua format berbeda, tetapi bukan yang paling nyaman untuk, Anda tahu, scripting ... (Mungkin .val () harus mengembalikan array seperti itu jika dipanggil pada elemen formulir?)
Luke Maurer

Jawaban:

524
$('#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();
    });

});

Berkat tip dari Simon_Weaver, berikut adalah cara lain untuk melakukannya, menggunakan serializeArray:

var values = {};
$.each($('#myForm').serializeArray(), function(i, field) {
    values[field.name] = field.value;
});

Perhatikan bahwa cuplikan ini akan gagal pada <select multiple>elemen.

Tampaknya input formulir HTML 5 baru tidak berfungsi dengan serializeArraydi jQuery versi 1.3. Ini berfungsi dalam versi 1.4+

nickf
sumber
1
Di versi jQuery yang lebih baru, jawaban Simon_Weaver lebih kuat dan lebih mudah.
Perkasa
1
@MightyE & @Simon_Weaver - Anda benar, ini adalah metode yang lebih kuat, tetapi tidak melakukan persis apa yang dicari OP. serializeArray mengembalikan array objek dengan properti namedan value. Solusi yang lebih baik mungkin untuk memproses output dari serializeArray ke format apa pun yang diperlukan.
nickf
1
Saya pikir serializeArray () melakukan apa yang Anda inginkan, dan kode jauh lebih sedikit.
slacy
1
Untuk opsi pertama, bagaimana dengan <select>elemen? Saya mencoba var $inputs = $('#new-ticket :input, :select');tetapi itu tidak berhasil. Adakah yang tahu cara yang tepat untuk melakukan ini karena saya pikir saya tidak melakukan itu dengan benar.
Nathan
2
@ Nathan, Anda harus menggunakan $("#new-ticket :input, #new-ticket :select"), atau bahkan lebih baik,$(":input, :select", "#new-ticket")
nickf
252

Terlambat ke pesta tentang pertanyaan ini, tetapi ini bahkan lebih mudah:

$('#myForm').submit(function() {
    // Get all the forms elements and their values in one step
    var values = $(this).serialize();

});
Lance Bergegas
sumber
8
Ini benar-benar jawaban terbaik. Bahkan membuat setiap array format yang Anda miliki untuk bidang input Anda. Saya tidak berpikir jawaban oleh nick akan benar-benar menjaga struktur data Anda tetap utuh jika itu dibentuk menggunakan Zend_Form misalnya, di mana Anda akan memiliki bidang [sesuatu] dan bidang [something_else] sebagai nama input ... setidaknya secara semantik, saya tidak bisa melihat bagaimana itu akan ...
msumme
43
Menurut dokumen API jQuery, .serialize()( api.jquery.com/serialize ) menempatkan semua elemen formulir dalam string tunggal yang siap ditambahkan ke URL dalam string kueri, pada dasarnya meniru permintaan formulir GET. Ini tidak akan mencapai apa yang dicapai jawaban nick.
Christopher Parker
Ini jawaban terbaik!
Daniel Hunter
5
Perlu diketahui: .serialize()juga bekerja pada elemen bentuk saja. Jadi $('form select').serialize()akan membuat serialisasi data hanya untuk pilihan.
antitoksik
3
Daripada mengulangi $('#myForm'), gunakan $ (ini).
Jimothy
23

Bentuk jquery.form Plugin dapat membantu dengan apa yang orang lain mencari akhir bahwa sampai pada pertanyaan ini. Saya tidak yakin apakah itu langsung melakukan apa yang Anda inginkan atau tidak.

Ada juga fungsi serializeArray .

Simon_Weaver
sumber
15

Kadang-kadang saya menemukan satu demi satu lebih bermanfaat. Untuk itu, ini dia:

var input_name = "firstname";
var input = $("#form_id :input[name='"+input_name+"']"); 
Maleakhi
sumber
Menambah [0].valueini yaitu $(...)[0].value;memberi saya nilai input secara langsung, terima kasih!
Pau Coma Ramirez
12
$('#myForm').bind('submit', function () {
  var elements = this.elements;
});

Variabel elemen akan berisi semua input, pilih, textareas dan fieldsets dalam formulir.

Quentin
sumber
9

Berikut ini adalah solusi lain, dengan cara ini Anda dapat mengambil semua data tentang formulir dan menggunakannya dalam panggilan sisi server atau sesuatu.

$('.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();
}

Anda kemudian dapat menggunakan ini dengan panggilan 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" );
       });
}

Semoga ini ada gunanya bagi kalian :)

Ole Aldric
sumber
5

Punya masalah serupa dengan sedikit twist dan saya pikir saya akan membuang ini. Saya memiliki fungsi callback yang mendapatkan formulir jadi saya sudah punya objek bentuk dan tidak bisa dengan mudah varian $('form:input'). Sebaliknya saya datang dengan:

    var dataValues = {};
    form.find('input').each(
        function(unusedIndex, child) {
            dataValues[child.name] = child.value;
        });

Ini mirip tetapi tidak identik situasinya, tetapi saya menemukan utas ini sangat berguna dan saya pikir saya akan menyelipkan ini pada akhirnya dan berharap orang lain menganggapnya berguna.

Chris
sumber
4

Asosiatif? Bukan tanpa pekerjaan, tetapi Anda dapat menggunakan penyeleksi generik:

var items = new Array();

$('#form_id:input').each(function (el) {
    items[el.name] = el;
});
Oli
sumber
sebenarnya, jawaban Lance membuat array asosiatif tetap utuh untuk nilai-nilai POST, dan mengambil satu baris kode.
msumme
mengapa item array? Anda menggunakannya seperti objek biasa. Tidak perlu array di sini
Jonathan Morales Vélez
3
@ JonathanMoralesVélez 2008's Oli tidak lagi ada untuk komentar. 2015 setuju dengan Anda.
Oli
4

jQuery's serializeArraytidak termasuk bidang yang dinonaktifkan, jadi jika Anda membutuhkannya juga, coba:

var data = {};
$('form.my-form').find('input, textarea, select').each(function(i, field) {
    data[field.name] = field.value;
});
Kapal Sarah
sumber
4

Jangan lupa kotak centang dan tombol radio -

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
Man Called Haney
sumber
3

Potongan kode ini akan berfungsi sebagai ganti nama, email masukkan nama bidang formulir Anda

$(document).ready(function(){
  $("#form_id").submit(function(event){
    event.preventDefault();
    var name = $("input[name='name']",this).val();
    var email = $("input[name='email']",this).val();
  });
});
turkane keras
sumber
3

Tampaknya aneh bahwa tidak ada orang yang telah meningkatkan atau mengusulkan solusi singkat untuk mendapatkan data daftar. Hampir tidak ada bentuk yang akan menjadi objek dimensi tunggal.

Kelemahan dari solusi ini adalah, tentu saja, bahwa objek tunggal Anda harus diakses pada indeks [0]. Tapi IMO jauh lebih baik daripada menggunakan salah satu solusi pemetaan selusin baris.

var formData = $('#formId').serializeArray().reduce(function (obj, item) {
    if (obj[item.name] == null) {
        obj[item.name] = [];
    } 
    obj[item.name].push(item.value);
    return obj;
}, {});
Ryanman
sumber
2

Saya memiliki masalah yang sama dan menyelesaikannya dengan cara yang berbeda.

var arr = new Array();
$(':input').each(function() {
 arr.push($(this).val());
});
arr;

Ini mengembalikan nilai dari semua bidang input. Anda bisa mengubahnya $(':input')menjadi lebih spesifik.

suizo
sumber
2

Solusi yang sama seperti yang diberikan oleh nick , tetapi dengan memasukkan nama input array misalnya

<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();
  }
});
Itako
sumber
1

Jika Anda perlu mendapatkan beberapa nilai dari input dan Anda menggunakan [] untuk menentukan input dengan banyak nilai, Anda dapat menggunakan yang berikut:

$('#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;
        }
    }                   
});
Jason Norwood-Young
sumber
1

Terinspirasi oleh jawaban Lance Rushing dan Simon_Weaver , ini adalah solusi favorit saya.

$('#myForm').submit( function( event ) {
    var values = $(this).serializeArray();
    // In my case, I need to fetch these data before custom actions
    event.preventDefault();
});

Outputnya adalah array objek, mis

[{name: "start-time", value: "11:01"}, {name: "end-time", value: "11:11"}]

Dengan kode di bawah ini,

var inputs = {};
$.each(values, function(k, v){
    inputs[v.name]= v.value;
});

hasil akhirnya adalah

{"start-time":"11:01", "end-time":"11:01"}
T.Liu
sumber
1

Saya menggunakan kode ini tanpa setiap 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;
});
Roman Grinev
sumber
1

Saya harap ini bermanfaat, sekaligus yang termudah.

 $("#form").submit(function (e) { 
    e.preventDefault();
    input_values =  $(this).serializeArray();
  });
dipenparmar12
sumber
Anehnya ini tidak bekerja pada versi terbaru jquery 3.4.1
relipse
0

Ketika saya perlu melakukan panggilan ajax dengan semua bidang formulir, saya punya masalah dengan : input selector mengembalikan semua kotak centang apakah mereka diperiksa atau tidak. Saya menambahkan pemilih baru untuk mendapatkan elemen formulir yang dapat dikirimkan:

$.extend($.expr[':'],{
    submitable: function(a){
        if($(a).is(':checkbox:not(:checked)'))
        {
            return false;
        }
        else if($(a).is(':input'))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
});

pemakaian:

$('#form_id :submitable');

Saya belum mengujinya dengan beberapa kotak pilih, tetapi ini berfungsi untuk mendapatkan semua bidang formulir seperti yang akan dikirim oleh standar.

Saya menggunakan ini ketika menyesuaikan opsi produk pada situs OpenCart untuk menyertakan kotak centang dan bidang teks serta jenis kotak pilih standar.

slarti42uk
sumber
0

serialize () adalah metode terbaik. @ Christopher Parker mengatakan bahwa Nickf's anwser mencapai lebih banyak, namun tidak memperhitungkan bahwa formulir tersebut mungkin berisi textarea dan pilih menu. Jauh lebih baik menggunakan serialize () dan kemudian memanipulasinya sesuai kebutuhan. Data dari serialize () dapat digunakan di pos Ajax atau dapatkan, jadi tidak ada masalah di sana.

Billy
sumber
0

Semoga ini bisa membantu seseorang. :)

// 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: "[email protected]"
//   1: "[email protected]"
// 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;
};
Julian
sumber
0

Semua jawaban baik, tetapi jika ada bidang yang ingin Anda abaikan dalam fungsi itu? Mudah, beri bidang properti, misalnya abaikan_ini:

<input type="text" name="some_name" ignore_this>

Dan di Fungsi Serialize Anda:

if(!$(name).prop('ignorar')){
   do_your_thing;
}

Itulah cara Anda mengabaikan beberapa bidang.

Marcelo Rocha
sumber
1
Ini lebih merupakan komentar daripada jawaban karena tidak menjawab pertanyaan awal.
Wai Ha Lee
Mungkin karena dia sudah punya banyak jawaban? Itu melengkapi jawaban yang diterimanya.
Marcelo Rocha
Saya akan menerapkan ini dengan nama kelas seperti wajib jika input harus diisi. Maka saya dapat memeriksa $('.mandatory');dan!$('.mandatory');
lharby
Ubah ignore_thiske data-ignore-this="true"alih-alih membuat atribut Anda sendiri yang tidak memvalidasi w3c
zanderwar
0

Coba kode berikut:

jQuery("#form").serializeArray().filter(obje => 
obje.value!='').map(aobj=>aobj.name+"="+aobj.value).join("&")
Teodor Rautu
sumber
2
Tolong jelaskan jawaban Anda
Ling Vu
0

Untuk beberapa elemen pilih ( <select multiple="multiple">), saya memodifikasi solusi dari @Jason Norwood-Young untuk membuatnya berfungsi.

Jawabannya (seperti yang diposting) hanya mengambil nilai dari elemen pertama yang dipilih, tidak semuanya . Itu juga tidak menginisialisasi atau kembali data, mantan melemparkan kesalahan JavaScript.

Ini versi baru:

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
}

Pemakaian:

_get_values($('#form'))

Catatan: Anda hanya perlu memastikan bahwa pilihan nameAnda telah []ditambahkan ke akhir, misalnya:

<select name="favorite_colors[]" multiple="multiple">
  <option value="red">Red</option>
  <option value="green">Green</option>
  <option value="blue">Blue</option>
</select>
tzazo
sumber
-1
$("#form-id").submit(function (e) { 
  e.preventDefault();
  inputs={};
  input_serialized =  $(this).serializeArray();
  input_serialized.forEach(field => {
    inputs[field.name] = field.value;
  })
  console.log(inputs)
});
Raushan
sumber