Tri-state Kotak centang dalam HTML?

163

Tidak ada cara untuk memiliki tombol centang tri-state (ya, tidak, nol) di HTML, kan?

Apakah ada trik atau penyelesaian sederhana tanpa harus membuat semuanya sendiri?

Pekka
sumber
Secara fungsional, apa perbedaan antara 'tidak' dan 'nol' dalam penggunaan Anda?
David mengatakan mengembalikan Monica
5
Lihatlah jawaban di bawah ini (kecuali untuk saya). "Null" berarti sesuatu seperti "Tidak ada jawaban" ...
Franz
2
Persis. Ini adalah item dengan leluhur dan "null" berarti "gunakan nilai induk".
Pekka
7
Penggunaan alternatif untuk kotak centang tri-state adalah saat mencari / memfilter. Misalnya, mari kita asumsikan saya punya antarmuka untuk mencari daftar mobil bekas. Salah satu opsi pencarian mungkin apakah mobil memiliki sunroof atau tidak. Tiga negara dapat digunakan sebagai berikut: Hanya menunjukkan mobil DENGAN sunroof Hanya menunjukkan mobil tanpa sunroof Tampilkan keduanya Sekarang, tentu saja, ini dapat ditangani dengan beberapa cara ... kita bisa dropdown, atau kita bisa menggunakan satu set dari tiga tombol radio ... tetapi kotak centang tri-state (yang kosong, memiliki centang hijau, atau memiliki x merah di dalamnya) juga merupakan solusi yang bagus.
Mir
2
Akan bermanfaat untuk daftar kotak centang, dengan satu kotak centang di bagian atas daftar untuk mencentang atau menghapus centang semua kotak yang tersisa. Jika semua dicentang, maka kotak centang tajuk dapat mencerminkan hal itu. Jika semua tidak dicentang maka kotak centang tajuk dapat mencerminkan hal itu juga. Jika daftar berisi kombinasi kotak yang dicentang dan tidak dicentang, maka memperlihatkan kotak centang tajuk dalam kondisi perantara akan memberikan umpan balik visual. Kotak centang header itu tidak akan pernah membawa nilai - itu hanya isyarat visual dan bantuan UI. Mampu mengganti kotak centang kepala antara ketiga negara bagian juga akan berguna.
Jason

Jawaban:

119

Sunting - Berkat komentar Janus Troelsen, saya menemukan solusi yang lebih baik:

HTML5 mendefinisikan properti untuk kotak centang yang disebut indeterminate

Lihat panduan referensi w3c . Untuk membuat kotak centang muncul secara tak tentu, setel ke true:

element.indeterminate = true;

Ini biola Janus Troelsen . Perhatikan, bagaimanapun, bahwa:

  • The indeterminatenegara tidak dapat diatur dalam markup HTML, itu hanya bisa dilakukan melalui Javascript (lihat ini tes JSfiddle dan ini artikel rinci dalam trik CSS )

  • Status ini tidak mengubah nilai kotak centang, itu hanya isyarat visual yang menutupi keadaan sebenarnya input.

  • Uji browser: Bekerja untuk saya di Chrome 22, Firefox 15, Opera 12 dan kembali ke IE7. Mengenai peramban seluler, peramban Android 2.0 dan Safari mobile di iOS 3.1 tidak memiliki dukungan untuk itu.

Jawaban sebelumnya

Alternatif lain adalah bermain dengan transparansi kotak centang untuk keadaan "beberapa yang dipilih" (seperti yang biasa dilakukan Gmail di versi sebelumnya). Ini akan memerlukan beberapa javascript dan kelas CSS. Di sini saya menaruh contoh tertentu yang menangani daftar dengan item yang dapat diperiksa dan kotak centang yang memungkinkan untuk memilih semua / tidak ada. Kotak centang ini menunjukkan keadaan "beberapa terpilih" ketika beberapa item daftar dipilih.

Diberikan kotak centang dengan ID #select_alldan beberapa kotak centang dengan kelas .select_one,

Kelas CSS yang memudar kotak centang "pilih semua" adalah sebagai berikut:

.some_selected {
    opacity: 0.5;
    filter: alpha(opacity=50);
}

Dan kode JS yang menangani tri-state dari kotak centang pilih semua adalah sebagai berikut:

$('#select_all').change (function ()
{
    //Check/uncheck all the list's checkboxes
    $('.select_one').attr('checked', $(this).is(':checked'));
    //Remove the faded state
    $(this).removeClass('some_selected');
});

$('.select_one').change (function ()
{
  if ($('.select_one:checked').length == 0)
      $('#select_all').removeClass('some_selected').attr('checked', false);
  else if ($('.select_one:not(:checked)').length == 0)
      $('#select_all').removeClass('some_selected').attr('checked', true);
  else
      $('#select_all').addClass('some_selected').attr('checked', true);
});

Anda dapat mencobanya di sini: http://jsfiddle.net/98BMK/

Semoga itu bisa membantu!

pau.moreno
sumber
1
Diuji dalam chrome v35 dan kotak centang "semua" hanya memeriksa kotak lain pada saat pertama kali diklik. Setelah ini hanya berfungsi untuk menghapus centang pada kotak centang lainnya. Diperbaiki dalam versi ini: jsfiddle.net/CHRSb/1
rdans
2
.prop('checked', ...)harus digunakan sebagai ganti .attr('checked', ...).
Luna
Saya memperbaiki bug yang ditunjukkan Ross; biola baru di sini .
Mike DeSimone
48

Anda bisa menggunakan indeterminateatribut IDL HTML pada inputelemen.

Ms2ger
sumber
3
Menurut Bert Bos dalam email dari tahun 2002 (< lists.w3.org/Archives/Public/www-dom/2002JMarMar/0014.html> ), IE / Win dan IE / Mac telah mendukungnya sejak versi 4. Firefox muncul untuk telah mengimplementasikannya di versi 3.6. Tampaknya juga telah diterapkan di Safari pada tahun 2008. Saya pikir itu membuat tidak banyak pengguna akhir.
Ms2ger
gunakan url ini ( help.dottoro.com/ljuocesd.php ) sebagai gantinya. Ini menunjukkan siapa yang mendukungnya (semua orang opera bar), sejak kapan, dan secara visual menampilkan apa itu. Orang-orang takut dengan halaman spesifikasi. +1 untuk solusi bukan-plugin ini
Hashbrown
15

Proposal saya akan digunakan

  • tiga karakter unicode yang sesuai untuk tiga status misalnya ❓, ✅, ❌
  • bidang input teks biasa (ukuran = 1)
  • tidak ada batasan
  • baca saja
  • tidak menampilkan kursor
  • penangan onclick untuk beralih melalui tiga negara

Lihat contoh di:

/**
 *  loops thru the given 3 values for the given control
 */
function tristate(control, value1, value2, value3) {
  switch (control.value.charAt(0)) {
    case value1:
      control.value = value2;
    break;
    case value2:
      control.value = value3;
    break;
    case value3:
      control.value = value1;
    break;
    default:
      // display the current value if it's unexpected
      alert(control.value);
  }
}
function tristate_Marks(control) {
  tristate(control,'\u2753', '\u2705', '\u274C');
}
function tristate_Circles(control) {
  tristate(control,'\u25EF', '\u25CE', '\u25C9');
}
function tristate_Ballot(control) {
  tristate(control,'\u2610', '\u2611', '\u2612');
}
function tristate_Check(control) {
  tristate(control,'\u25A1', '\u2754', '\u2714');
}
<input type='text' 
       style='border: none;' 
       onfocus='this.blur()' 
       readonly='true' 
       size='1' 
       value='&#x2753;' onclick='tristate_Marks(this)' />

<input style="border: none;"
       id="tristate" 
       type="text"  
       readonly="true" 
       size="1" 
       value="&#x2753;"  
       onclick="switch(this.form.tristate.value.charAt(0)) { 
     case '&#x2753': this.form.tristate.value='&#x2705;'; break;  
     case '&#x2705': this.form.tristate.value='&#x274C;'; break; 
     case '&#x274C': this.form.tristate.value='&#x2753;'; break; 
       };" />  

Wolfgang Fahl
sumber
3

Anda dapat menggunakan grup radio untuk mencapai fungsi itu:

<input type="radio" name="choice" value="yes" />Yes
<input type="radio" name="choice" value="No" />No
<input type="radio" name="choice" value="null" />null
Franz
sumber
1
Saya tahu itu, terima kasih. :) Saya saat ini menggunakan pilihan, tetapi formulir semakin berantakan.
Pekka
1
Nah, lalu seperti apa keadaan ketiga itu? Sama seperti ketika kotak centang dinonaktifkan? Bagaimana Anda ingin memicu itu?
Franz
3

Saya pikir cara yang paling semantik adalah menggunakan readonlyatribut yang bisa dimiliki oleh kotak centang. Tidak ada css, tidak ada gambar, dll; properti HTML bawaan!

Lihat Fiddle:
http://jsfiddle.net/chriscoyier/mGg85/2/

Seperti dijelaskan di sini dalam trik terakhir: http://css-tricks.com/indeterminate-checkboxes/

Webinan
sumber
Solusi yang bagus tapi sayangnya ini tidak berfungsi di IE (uji dengan versi 11) karena klik yang lebih cepat tidak lagi dikenali.
ViRuSTriNiTy
3

Berikut adalah contoh runnable menggunakan indeterminateatribut yang disebutkan :

const indeterminates = document.getElementsByClassName('indeterminate');
indeterminates['0'].indeterminate  = true;
<form>
  <div>
    <input type="checkbox" checked="checked" />True
  </div>
  <div>
    <input type="checkbox" />False
  </div>
  <div>
    <input type="checkbox" class="indeterminate" />Indeterminate
  </div>
</form>

Jalankan cuplikan kode untuk melihat tampilannya.

gil.fernandes
sumber
2

Seperti jawaban @Franz, Anda juga dapat melakukannya dengan memilih. Sebagai contoh:

<select>
  <option></option>
  <option value="Yes">Yes</option>
  <option value="No">No</option>
</select>

Dengan ini Anda juga dapat memberikan nilai konkret yang akan dikirim dengan formulir, saya pikir bahwa dengan versi centang kotak centang tak tentu javascript, itu akan mengirim nilai garis bawah kotak centang.

Paling tidak, Anda dapat menggunakannya sebagai panggilan balik ketika javascript dinonaktifkan. Misalnya, berikan id dan dalam acara muat ubahlah ke versi javascript pada kotak centang dengan status tak tentu.

PhoneixS
sumber
2

Selain semua yang dikutip di atas, ada plugin jQuery yang dapat membantu juga:

untuk masing-masing kotak centang:

untuk kotak centang perilaku mirip pohon:

EDIT Kedua perpustakaan menggunakan atribut kotak centang ' tak tentu ', karena atribut ini di Html5 hanya untuk styling ( https://www.w3.org/TR/2011/WD-html5-20110113/number-state.html#checkbox-state ), nilai nol tidak pernah dikirim ke server (kotak centang hanya dapat memiliki dua nilai).

Untuk dapat mengirimkan nilai ini ke server, saya telah membuat bidang rekanan tersembunyi yang diisi pada pengiriman formulir menggunakan beberapa javascript. Di sisi server, tentu saja Anda perlu memeriksa bidang rekanan itu alih-alih kotak centang asli.

Saya telah menggunakan perpustakaan pertama (kotak centang mandiri) tempat penting untuk:

  • Inisialisasi nilai yang dicentang, tidak dicentang, tak tentu
  • gunakan fungsi .val () untuk mendapatkan nilai aktual
  • Tidak dapat membuat .state kerja (mungkin kesalahan saya)

Semoga itu bisa membantu.

Frank Sebastià
sumber
2

Berikut Contoh lain dengan jQuery dan properti sederhana data-checked:

 $("#checkbox")
  .click(function(e) {
    var el = $(this);

    switch (el.data('checked')) {

      // unchecked, going indeterminate
      case 0:
        el.data('checked', 1);
        el.prop('indeterminate', true);
        break;

        // indeterminate, going checked
      case 1:
        el.data('checked', 2);
        el.prop('indeterminate', false);
        el.prop('checked', true);
        break;

        // checked, going unchecked
      default:
        el.data('checked', 0);
        el.prop('indeterminate', false);
        el.prop('checked', false);

    }
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label><input type="checkbox" name="checkbox" value="" checked id="checkbox"> Tri-State Checkbox </label>

Ravi Makwana
sumber
1

Mengacu pada jawaban @BoltClock , berikut adalah solusi saya untuk metode rekursif yang lebih kompleks:

http://jsfiddle.net/gx7so2tq/2/

Ini mungkin bukan solusi yang paling cantik tetapi berfungsi dengan baik untuk saya dan cukup fleksibel.

Saya menggunakan dua objek data yang mendefinisikan wadah:

data-select-all="chapter1"

dan elemen-elemen itu sendiri:

data-select-some="chapter1"

Keduanya memiliki nilai yang sama. Kombinasi kedua objek data dalam satu kotak centang memungkinkan sublevel, yang dipindai secara rekursif. Oleh karena itu diperlukan dua fungsi "pembantu" untuk mencegah pemicu perubahan.

MFH
sumber
0

Dimungkinkan untuk menonaktifkan elemen form HTML - bukankah itu bisa? Pengguna Anda akan melihatnya di salah satu dari tiga negara, yaitu dicentang, tidak dicentang, dan dinonaktifkan, yang akan diklik dan tidak dapat diklik. Bagi saya, itu mirip dengan "null" atau "tidak berlaku" atau apa pun yang Anda cari di negara ketiga itu.

AmbroseChapel
sumber
Ide yang sangat bagus, tetapi saya perlu pengguna untuk dapat mengkliknya lagi. Saya khawatir bahwa pada kotak centang yang dinonaktifkan, saya akan mengalami kesulitan memecat acara dan sebagainya.
Pekka
Anda masih dapat melihat nilai kotak centang yang dinonaktifkan, yang membingungkan pengguna jika nilainya tidak penting.
Janus Troelsen
Saya pikir 'null' dimaksudkan untuk mewakili pengguna yang tidak memberikan jawaban atas pertanyaan. Itu tidak selalu berarti bahwa pertanyaan itu tidak berlaku.
bdsl