Bagaimana cara menggunakan form.serialize jQuery tetapi mengecualikan bidang kosong

107

Saya memiliki formulir pencarian dengan sejumlah input teks & drop down yang dikirimkan melalui GET. Saya ingin memiliki url pencarian yang lebih bersih dengan menghapus field kosong dari querystring saat pencarian dilakukan.

var form = $("form");  
var serializedFormStr = form.serialize();  
// I'd like to remove inputs where value is '' or '.' here
window.location.href = '/search?' + serializedFormStr

Tahu bagaimana saya bisa melakukan ini menggunakan jQuery?

Tom Viner
sumber

Jawaban:

167

Saya telah melihat-lihat dokumen jQuery dan saya pikir kita bisa melakukan ini dalam satu baris menggunakan penyeleksi :

$("#myForm :input[value!='']").serialize() // does the job!

Jelas #myForm mendapatkan elemen dengan id "myForm" tetapi yang kurang jelas bagi saya pada awalnya adalah bahwa karakter spasi diperlukan antara #myForm dan: input karena ini adalah operator turunan .

: input cocok dengan semua elemen input, textarea, pilih dan tombol.

[nilai! = ''] adalah atribut yang tidak sama dengan filter. Yang aneh (dan membantu) adalah bahwa semua: tipe elemen input memiliki atribut nilai bahkan memilih dan kotak centang dll.

Akhirnya untuk juga menghapus masukan yang nilainya adalah '.' (seperti yang disebutkan dalam pertanyaan):

$("#myForm :input[value!=''][value!='.']").serialize()

Dalam kasus ini penjajaran, yaitu menempatkan dua selektor atribut di samping satu sama lain , berarti DAN. Menggunakan koma menyiratkan OR. Maaf jika itu jelas bagi orang-orang CSS!

Tom Viner
sumber
3
@Mvision, itu karena ada kelalaian kecil tapi signifikan dalam jawaban ini. Untuk pemilih CSS normal / murni di jQuery 1.8 dan sebelumnya, [value]cocokkan elemen apa pun dengan atribut yang value ada , termasuk yang memiliki nilai kosong (atau tidak ada). Hal ini disebabkan oleh bug di versi jQuery sebelumnya yang membuat ketidakkonsistenan antara variasi input[value]dan :input[value]. Ambil, misalnya <input value="foo"><input value=""><input value><input>,; bug diilustrasikan di biola ini .
Noyo
4
Bagi saya, ini berhasil: $form.find(":input[value]")- bidang kosong tidak dipilih. Ini tidak berhasil: $form.find(":input[value!='']")- semua bidang dipilih. Harapan yang membantu seseorang. (jQuery 2.0.0)
Ryan Wheale
1
$form.find(":input[value]")juga bekerja untuk saya (jQuery 1.11.0)
GSTAR
Hanya berfungsi jika valueatribut sudah ada di sana. Ia tidak mengenalinya sebaliknya.
Starcorn
1
Dalam beberapa kasus di mana valuediatur secara terprogram, ini tidak akan berfungsi ( valuetidak akan ada sebagai atribut HTML, tetapi akan sebagai atribut data pada input). Dalam kasus tersebut, coba ini: $('#myForm :input').filter(function(i) { return ($(this).val().length != 0); }).serialize(). EDIT: Baru saja melihat jawaban Rich untuk efek yang sama.
Fateh Khalsa
54

Saya tidak bisa mendapatkan solusi Tom untuk bekerja (?), Tapi saya bisa melakukan ini .filter()dengan menggunakan fungsi singkat untuk mengidentifikasi bidang kosong. Saya menggunakan jQuery 2.1.1.

var formData = $("#formid :input")
    .filter(function(index, element) {
        return $(element).val() != '';
    })
    .serialize();
Kaya
sumber
2
Tidak bisa mendapatkan jawaban yang disetujui untuk berfungsi, tetapi ini berfungsi dengan baik! Terima kasih!
bfritz
Menjawab pertanyaan saya sendiri: " :inputPemilih pada dasarnya memilih semua kontrol bentuk. Memilih semua elemen input, textarea, pilih dan tombol." sumber
Dinei
Ya, Tom rusak . Milikmu lebih bersih daripada usahaku dalam biola itu juga. Up'd
Hashbrown
11

Ini bekerja untuk saya:

data = $( "#my_form input").filter(function () {
        return !!this.value;
    }).serialize();
RMazitov
sumber
Nah, callback membiarkan nilai lulus mengembalikan true, !!mengetik ulang apa pun ke bool, Anda dapat mencoba di konsol. !!('test'), !!(5),!!(0)
Aiphee
2
Dan alih-alih inputpemilih, harus ada :inputuntuk menyertakan pilihan, dll.
Aiphee
Saya menyarankan perubahan ini:data = $( "#my_form :input").filter(function () { return $(this).val() != ""; }).serialize();
Mahoor13
9

Anda dapat melakukannya dengan regex ...

var orig = $('#myForm').serialize();
var withoutEmpties = orig.replace(/[^&]+=\.?(?:&|$)/g, '')

Kasus uji:

orig = "a=&b=.&c=&d=.&e=";
new => ""

orig = "a=&b=bbb&c=.&d=ddd&e=";
new => "b=bbb&d=ddd&"  // dunno if that trailing & is a problem or not
nickf
sumber
.replace (/[^&]+=\.?(& | $) / g, '') mencakup kedua kasus. Tapi saya akan menambahkan .replace (/ & $ /, '') untuk menghapus jejak &
Tom Viner
15
Tidak ada masalah yang tidak bisa diperburuk oleh regex.
Michael Cook
3

Saya telah menggunakan solusi di atas tetapi bagi saya itu tidak berhasil. Jadi saya telah menggunakan kode berikut

$('#searchform').submit(function(){

            var serializedData = $(this).serializeArray();
            var query_str = '';

            $.each(serializedData, function(i,data){
                if($.trim(data['value'])){
                    query_str += (query_str == '') ? '?' + data['name'] + '=' + data['value'] : '&' + data['name'] + '=' + data['value'];
                }
            });
            console.log(query_str);
            return false;
        });

Semoga bermanfaat bagi seseorang

Rajan Rawal
sumber
1

Saya akan melihat kode sumber untuk jQuery. Di baris versi terbaru 3287.

Saya mungkin menambahkan fungsi "serialize2" dan "serializeArray2". tentu saja sebutkan sesuatu yang berarti.

Atau cara yang lebih baik adalah menulis sesuatu untuk menarik vars yang tidak terpakai dari serializedFormStr. Beberapa regex yang mencari = & di tengah string atau diakhiri dengan = Ada penyihir regex?

PEMBARUAN: Saya lebih suka jawaban rogeriopvl (+1) ... terutama karena saya tidak dapat menemukan alat regex yang bagus saat ini.

BuddyJoe
sumber
1

Alternatif untuk solusi Rich :

$('#form').submit(function (e) {
  e.preventDefault();

  var query = $(this).serializeArray().filter(function (i) {
    return i.value;
  });

   window.location.href = $(this).attr('action') + (query ? '?' + $.param(query) : '');
});

Penjelasan:

  • .submit()kait ke form submitacara
  • e.preventDefault() mencegah formulir untuk dikirim
  • .serializeArray() memberi kita representasi array dari string kueri yang akan dikirim.
  • .filter() menghapus nilai-nilai yang salah (termasuk kosong) dalam larik itu.
  • $.param(query) membuat representasi serial dan sesuai URL dari larik yang diperbarui
  • mengatur nilai untuk window.location.hrefmengirimkan permintaan
Kathandrax
sumber
0

Dalam coffeescript, lakukan ini:

serialized_form = $(_.filter($(context).find("form.params input"), (x) -> $(x).val() != '')).serialize()
John Goodsen
sumber
-1

Anda mungkin ingin melihat fungsi .each () jquery, yang memungkinkan Anda melakukan iterasi melalui setiap elemen selektor, jadi dengan cara ini Anda dapat memeriksa setiap bidang masukan dan melihat apakah kosong atau tidak dan kemudian menghapusnya dari formulir menggunakan element.remove (). Setelah itu Anda dapat membuat serial formulir.

rogeriopvl
sumber
1
Satu-satunya masalah dengan itu adalah pengguna akan melihat bagian kosong dari kontrol menghilang tepat sebelum halaman dikirimkan. Akan lebih baik untuk menyetel nama menjadi "" jadi serialize mengabaikannya.
Tom Viner