Bagaimana cara memastikan bidang formulir <select> dikirimkan ketika dinonaktifkan?

180

Saya memiliki selectbidang formulir yang ingin saya tandai sebagai "readonly", karena di pengguna tidak dapat mengubah nilai, tetapi nilainya masih dikirim dengan formulir. Menggunakan disabledatribut mencegah pengguna mengubah nilai, tetapi tidak mengirimkan nilai dengan formulir.

The readonlyatribut hanya tersedia untuk inputdan textareabidang, tapi itu pada dasarnya apa yang saya inginkan. Apakah ada cara untuk membuatnya bekerja?

Dua kemungkinan yang saya pertimbangkan meliputi:

  • Alih-alih menonaktifkan select, nonaktifkan semua optiondan gunakan CSS untuk mengubah pilihan sehingga tampak seperti dinonaktifkan.
  • Tambahkan event handler klik ke tombol kirim sehingga memungkinkan semua menu dropdown yang dinonaktifkan sebelum mengirimkan formulir.
Marquis Wang
sumber
2
maaf karena terlambat bergabung, namun solusi yang disediakan oleh @ trafalmadorianworkest adalah yang terbaik. Ini menonaktifkan semua input yang tidak dipilih. Ini juga akan berfungsi jika itu dipilih memiliki beberapa opsi diaktifkan. $('#toSelect')find(':not(:selected)').prop('disabled',true);
Abhishek Madhani
Atau, Anda bisa membiarkan kontrol sebagai dinonaktifkan di UI tetapi mengambil nilai dalam metode tindakan: publik ActionResult InsertRecord (model MyType) {if (model.MyProperty == null) {model.MyProperty = Permintaan ["MyProperty"]; }}
beastieboy

Jawaban:

118
<select disabled="disabled">
    ....
</select>
<input type="hidden" name="select_name" value="selected value" />

Di mana select_namenama yang biasanya Anda berikan <select>.

Pilihan lain.

<select name="myselect" disabled="disabled">
    <option value="myselectedvalue" selected="selected">My Value</option>
    ....
</select>
<input type="hidden" name="myselect" value="myselectedvalue" />

Sekarang dengan yang ini, saya perhatikan bahwa tergantung pada server web apa yang Anda gunakan, Anda mungkin harus memasukkan hiddeninput baik sebelum, atau setelah <select>.

Jika ingatan saya benar, dengan IIS, Anda letakkan sebelumnya, dengan Apache Anda letakkan setelah itu. Seperti biasa, pengujian adalah kunci.

Jordan S. Jones
sumber
3
Bagaimana ini tergantung pada server web ? Bukankah klien yang merender halaman dengan bidang pilih, dan jika terjadi konflik seperti itu, klienlah yang akan memutuskan apakah akan mengirim nilai ke server atau tidak?
Ilari Kajaste
8
Itu tergantung pada bagaimana server menangani beberapa input dengan nama yang sama.
Jordan S. Jones
1
Anda sebaiknya tidak bergantung pada jenis server tertentu, jadi saya pikir pendekatan pertama lebih bersih dan lebih rentan kesalahan.
Luke
5
@Jordan: Browser tidak mengirim nilai bidang yang dinonaktifkan ke server, itulah sebabnya mereka kosong ketika Anda mencoba menanganinya di sisi server. Jika Anda memiliki bidang tersembunyi dengan nilai yang diinginkan, dan bidang yang terlihat dinonaktifkan, hanya bidang tersembunyi yang akan dikirim ke server. Ergo, bidang tersembunyi hanya boleh dibuat (melalui JS atau kode sisi-server) ketika bidang yang terlihat dinonaktifkan dan tidak ada masalah prioritas.
Matt van Andel
1
Ini hanya opsi jika Anda memerlukan formulir yang berfungsi tanpa javascript.
Andrew
224

Nonaktifkan bidang dan kemudian aktifkan sebelum formulir dikirimkan:

kode jQuery:

jQuery(function ($) {        
  $('form').bind('submit', function () {
    $(this).find(':input').prop('disabled', false);
  });
});
Tres
sumber
15
Solusi yang cukup bagus!
Chris
2
Ini yang saya pilih, terutama karena itu yang paling tidak mengganggu.
Jonathan
3
Dokumen jQuery merekomendasikan penggunaan .prop dan .removeProp untuk 'dicentang', 'dipilih' dan 'dinonaktifkan' alih-alih .attr dan .removeAttr lihat http://api.jquery.com/prop/
Jim Bergman
2
Sedikit komentar @ JimBergman yang relevan - "Properti umumnya memengaruhi keadaan dinamis elemen DOM tanpa mengubah atribut HTML serial. Contohnya termasuk properti nilai elemen input, properti yang dinonaktifkan dari input dan tombol, atau properti yang dicentang dari kotak centang. Metode .prop () harus digunakan untuk menetapkan dinonaktifkan dan diperiksa, bukan metode .attr (). Metode .val () harus digunakan untuk mendapatkan dan menetapkan nilai. " - dari api.jquery.com/prop
Joshua Dance
2
Anda genius satu (Y)
TommyDo
13

Saya sudah mencari solusi untuk ini, dan karena saya tidak menemukan solusi di utas ini saya lakukan sendiri.

// With jQuery
$('#selectbox').focus(function(e) {
    $(this).blur();
});

Sederhana, Anda hanya mengaburkan bidang ketika Anda fokus padanya, sesuatu seperti menonaktifkannya, tetapi Anda benar-benar mengirim datanya.

Jean Paul Rumeau
sumber
Wow solusi hebat dan mudah. Terima kasih .. +1 dari saya :)
Naeem Ul Wahhab
Saya sangat suka ini .. tergantung pada interaksi dalam formulir saya, elemen menjadi diaktifkan / dinonaktifkan back-n-sebagainya ... bagaimana saya mengaktifkan kembali bidang 'kabur' dalam skenario ini?
bkwdesign
Dari googling, sepertinya $ ('# selectbox'). Off ('fokus'); akan melakukan trik mengaktifkan kembali
bkwdesign
2
berfungsi untuk kotak teks, tidak berfungsi untuk kotak pilih, ditambah super mudah untuk berkeliling dengan mengklik dan menahan tombol
Andrew
7

Saya dihadapkan dengan skenario yang sedikit berbeda, yaitu saya hanya ingin tidak mengizinkan pengguna untuk mengubah nilai yang dipilih berdasarkan kotak pilih sebelumnya. Apa yang akhirnya saya lakukan hanya menonaktifkan semua opsi yang tidak dipilih lainnya di kotak pilih menggunakan

$('#toSelect')find(':not(:selected)').attr('disabled','disabled');
trafalmadorian
sumber
Terima kasih, saya menemukan milik Anda yang paling logis paling sederhana. Namun attrharus diubah dengan prop, akan terlihat seperti$('#toSelect')find(':not(:selected)').prop('disabled',true);
Abhishek Madhani
6

Solusi yang sama disarankan oleh Tres tanpa menggunakan jQuery

<form onsubmit="document.getElementById('mysel').disabled = false;" action="..." method="GET">

   <select id="mysel" disabled="disabled">....</select>

   <input name="submit" id="submit" type="submit" value="SEND FORM">
</form>

Ini mungkin membantu seseorang memahami lebih banyak, tetapi jelas kurang fleksibel daripada jQuery.

Marco Demaio
sumber
Tapi, itu tidak baik untuk banyak penyeleksi. Mungkin bisa kita gunakan getElementsByTagName('select')?
Lucky
6

itu tidak berfungsi dengan: pemilih input untuk bidang pilih, gunakan ini:

    jQuery(function() {

    jQuery('form').bind('submit', function() {
        jQuery(this).find(':disabled').removeAttr('disabled');
    });

    });
chhalpha
sumber
5

Saya menggunakan kode berikutnya untuk opsi menonaktifkan dalam pilihan

<select class="sel big" id="form_code" name="code" readonly="readonly">
   <option value="user_played_game" selected="true">1 Game</option>
   <option value="coins" disabled="">2 Object</option>
   <option value="event" disabled="">3 Object</option>
   <option value="level" disabled="">4 Object</option>
   <option value="game" disabled="">5 Object</option>
</select>

// Disable selection for options
$('select option:not(:selected)').each(function(){
 $(this).attr('disabled', 'disabled');
});
Aleks
sumber
4

Cara termudah yang saya temukan adalah membuat fungsi javascript kecil yang diikat ke formulir Anda:

function enablePath() {
    document.getElementById('select_name').disabled= "";
}

dan Anda menyebutnya di formulir Anda di sini:

<form action="act.php" method="POST" name="form_name" onSubmit="enablePath();">

Atau Anda dapat menyebutnya di fungsi yang Anda gunakan untuk memeriksa formulir Anda :)

Alex PARISOT
sumber
4

Cukup tambahkan baris sebelum mengirim.

$ ("# XYZ"). RemoveAttr ("dinonaktifkan");

PPB
sumber
2

Atau gunakan beberapa JavaScript untuk mengubah nama pilih dan mengaturnya untuk dinonaktifkan. Dengan cara ini pilih masih dikirimkan, tetapi menggunakan nama yang tidak Anda periksa.

Byron Whitlock
sumber
2

Saya menyiapkan plugin cepat (hanya Jquery), yang menyimpan nilai dalam bidang data saat input dinonaktifkan. Ini hanya berarti selama bidang dinonaktifkan secara terprogram melalui jquery menggunakan .prop () atau .attr () ... lalu mengakses nilainya dengan .val (), .serialize () atau .serializeArra () akan selalu mengembalikan nilai bahkan jika dinonaktifkan :)

Steker tak tahu malu: https://github.com/Jezternz/jq-disabled-inputs

Josh Mc
sumber
2

Berdasarkan solusi dari Jordan, saya membuat fungsi yang secara otomatis membuat input tersembunyi dengan nama yang sama dan nilai yang sama dari pilih yang Anda inginkan menjadi tidak valid. Parameter pertama bisa berupa id atau elemen jquery; yang kedua adalah parameter opsional Boolean di mana "true" menonaktifkan dan "false" memungkinkan input. Jika dihilangkan, parameter kedua mengalihkan pemilihan antara "diaktifkan" dan "dinonaktifkan".

function changeSelectUserManipulation(obj, disable){
    var $obj = ( typeof obj === 'string' )? $('#'+obj) : obj;
    disable = disable? !!disable : !$obj.is(':disabled');

    if(disable){
        $obj.prop('disabled', true)
            .after("<input type='hidden' id='select_user_manipulation_hidden_"+$obj.attr('id')+"' name='"+$obj.attr('name')+"' value='"+$obj.val()+"'>");
    }else{
        $obj.prop('disabled', false)
            .next("#select_user_manipulation_hidden_"+$obj.attr('id')).remove();
    }
}

changeSelectUserManipulation("select_id");
Doglas
sumber
parameter 'obj' harus berupa objek jquery
Doglas
1

Saya menemukan solusi yang bisa diterapkan: hapus semua elemen kecuali yang dipilih. Anda kemudian dapat mengubah gaya menjadi sesuatu yang terlihat dinonaktifkan juga. Menggunakan jQuery:

jQuery(function($) {
    $('form').submit(function(){
        $('select option:not(:selected)', this).remove();
    });
});
Alftheo
sumber
0
<select id="example">
    <option value="">please select</option>
    <option value="0" >one</option>
    <option value="1">two</option>
</select>



if (condition){
    //you can't select
    $("#example").find("option").css("display","none");
}else{
   //you can select
   $("#example").find("option").css("display","block");
}
Terima kasih
sumber
-8

Pilihan lain adalah menggunakan atribut readonly.

<select readonly="readonly">
    ....
</select>

Dengan hanya baca nilai masih dikirimkan, bidang input berwarna abu-abu dan pengguna tidak dapat mengeditnya.

Edit:

Dikutip dari http://www.w3.org/TR/html401/interact/forms.html#adef-readonly :

  • Elemen baca-saja menerima fokus tetapi tidak dapat dimodifikasi oleh pengguna.
  • Elemen baca-saja disertakan dalam navigasi tab.
  • Elemen baca-saja mungkin berhasil.

Ketika dikatakan elemen mungkin berhasil, itu berarti dapat diajukan, seperti yang dinyatakan di sini: http://www.w3.org/TR/html401/interact/forms.html#successful-controls

Phillip Whelan
sumber
6
Kontrol TIDAK berwarna abu-abu dan pengguna BISA mengeditnya. Anda gagal membaca seluruh bagian dan saya kutip: "Elemen-elemen berikut mendukung atribut readonly: INPUT dan TEXTAREA."
Carlos Rendon
3
Saya tahu ini adalah jawaban lama, tetapi ini benar-benar berhasil. Saya tidak tahu alasan banyak downvotes.
Ze Luis