Hộp kiểm Tri-bang trong HTML?


163

Không có cách nào để có nút kiểm tra ba trạng thái (có, không, không) trong HTML, phải không?

Có bất kỳ thủ thuật đơn giản hoặc công việc xung quanh mà không cần phải tự hoàn thành mọi thứ?


Về mặt chức năng, sự khác biệt giữa 'không' và 'null' trong cách sử dụng của bạn là gì?
David nói phục hồi Monica

5
Nhìn vào các câu trả lời dưới đây (ngoại trừ của tôi). "Null" có nghĩa là "Không trả lời" ...
Franz

2
Chính xác. Đó là một mục có tổ tiên và "null" có nghĩa là "sử dụng giá trị cha mẹ".
Pekka

7
Một cách sử dụng khác cho hộp kiểm ba trạng thái là khi tìm kiếm / lọc. Ví dụ: giả sử tôi có giao diện để tìm kiếm danh sách những chiếc xe đã qua sử dụng. Một trong những lựa chọn tìm kiếm có thể là chiếc xe có cửa sổ trời hay không. Ba trạng thái có thể được sử dụng như sau: Chỉ hiển thị ô tô có cửa sổ trời Chỉ hiển thị ô tô KHÔNG CÓ cửa sổ trời Hiển thị cả Bây giờ, chắc chắn, điều này có thể được xử lý theo một số cách ... chúng ta có thể thả xuống hoặc chúng ta có thể sử dụng một bộ trong số ba nút radio ... nhưng hộp kiểm ba trạng thái (trống hoặc có kiểm tra màu xanh lá cây hoặc có dấu x màu đỏ trong đó) cũng là một giải pháp hay.
Mir

2
Nó sẽ hữu ích cho một danh sách các hộp kiểm, với một hộp kiểm ở đầu danh sách để kiểm tra hoặc bỏ chọn tất cả các hộp còn lại. Nếu tất cả được chọn, thì hộp kiểm tiêu đề có thể phản ánh điều đó. Nếu tất cả được bỏ chọn thì hộp kiểm tiêu đề cũng có thể phản ánh điều đó. Nếu danh sách chứa kết hợp các hộp được chọn và không được chọn, thì hiển thị hộp kiểm tiêu đề ở trạng thái trung gian sẽ cung cấp phản hồi trực quan. Hộp kiểm tiêu đề đó sẽ không bao giờ mang một giá trị - nó chỉ là một dấu hiệu trực quan và hỗ trợ giao diện người dùng. Có thể chuyển đổi hộp kiểm đầu giữa cả ba trạng thái cũng sẽ có ích.
Jason

Câu trả lời:


119

Biên tập - Nhờ nhận xét của Janus Troelsen, tôi đã tìm thấy một giải pháp tốt hơn:

HTML5 định nghĩa một thuộc tính cho các hộp kiểm được gọi là indeterminate

Xem hướng dẫn tham khảo w3c . Để làm cho hộp kiểm xuất hiện trực quan không xác định, đặt nó thành đúng:

element.indeterminate = true;

Đây là bí ẩn của Janus Troelsen . Lưu ý, tuy nhiên, rằng:

  • Các indeterminatenhà nước không thể được thiết lập trong đánh dấu HTML, nó chỉ có thể được thực hiện thông qua Javascript (xem này kiểm tra JSfiddle và điều này bài viết chi tiết trong thủ thuật CSS )

  • Trạng thái này không thay đổi giá trị của hộp kiểm, nó chỉ là một dấu hiệu trực quan che dấu trạng thái thực của đầu vào.

  • Kiểm tra trình duyệt: Đã hoạt động với tôi trong Chrome 22, Firefox 15, Opera 12 và quay lại IE7. Về trình duyệt di động, trình duyệt Android 2.0 và Safari di động trên iOS 3.1 không hỗ trợ cho trình duyệt này.

Câu trả lời trước

Một lựa chọn khác sẽ được chơi với tính minh bạch hộp kiểm cho "một số lựa chọn" nhà nước (như Gmail không sử dụng để làm trong các phiên bản trước). Nó sẽ yêu cầu một số javascript và một lớp CSS. Ở đây tôi đặt một ví dụ cụ thể xử lý danh sách với các mục có thể kiểm tra và hộp kiểm cho phép chọn tất cả / không có mục nào trong số đó. Hộp kiểm này hiển thị trạng thái "một số được chọn" khi một số mục trong danh sách được chọn.

Đưa ra một hộp kiểm có ID #select_allvà một số hộp kiểm với một lớp .select_one,

Lớp CSS mờ dần hộp kiểm "chọn tất cả" sẽ như sau:

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

Và mã JS xử lý trạng thái ba của hộp kiểm chọn tất cả là như sau:

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

Bạn có thể dùng thử tại đây: http://jsfiddle.net/98BMK/

Mong rằng sẽ giúp!



1
Đã thử nghiệm trong chrome v35 và hộp kiểm "tất cả" chỉ kiểm tra các hộp khác trong lần nhấp đầu tiên. Sau đó, nó chỉ hoạt động để bỏ chọn các hộp kiểm khác. Đã sửa lỗi trong phiên bản này: jsfiddle.net/CHRSb/1
2014

2
.prop('checked', ...)nên được sử dụng thay vì .attr('checked', ...).
Luna

Tôi đã sửa các lỗi mà Ross chỉ ra; Fiddle mới ở đây .
Mike DeSimone

48

Bạn có thể sử dụng indeterminatethuộc tính IDL của HTML trên inputcác phần tử.


3
Theo Bert Bos trong một email từ năm 2002 (< lists.w3.org/Archives/Public/www-dom/2002JanMar/0014.html> ), IE / Win và IE / Mac đã hỗ trợ nó kể từ phiên bản 4. Firefox xuất hiện đã thực hiện nó trong phiên bản 3.6. Nó cũng dường như đã được triển khai trong Safari vào năm 2008. Tôi nghĩ rằng điều đó không có nhiều người dùng cuối.
Ms2ger

sử dụng url này ( help.dottoro.com/ljuocesd.php ) thay thế. Nó cho thấy ai hỗ trợ nó (mọi người đều hát opera), kể từ khi nào, và hiển thị trực quan nó là gì. Mọi người sợ các trang spec. +1 cho giải pháp không phải là plugin này
Hashbrown

15

Đề xuất của tôi sẽ được sử dụng

  • ba ký tự unicode thích hợp cho ba trạng thái, ví dụ,,
  • trường nhập văn bản thuần túy (size = 1)
  • không biên giới
  • chỉ đọc
  • không hiển thị con trỏ
  • xử lý onclick để chuyển qua ba trạng thái

Xem ví dụ tại:

/**
 *  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; 
       };" />  



3

Bạn có thể sử dụng các nhóm radio để đạt được chức năng đó:

<input type="radio" name="choice" value="yes" />Yes
<input type="radio" name="choice" value="No" />No
<input type="radio" name="choice" value="null" />null

1
Tôi biết điều đó, cảm ơn. :) Tôi hiện đang sử dụng các lựa chọn, nhưng hình thức đang có một chút lộn xộn.
Pekka

1
Chà, chính xác thì trạng thái thứ ba sẽ trông như thế nào? Giống như khi hộp kiểm bị vô hiệu hóa? Làm thế nào bạn muốn kích hoạt điều đó?
Franz

3

Tôi nghĩ rằng cách thức ngữ nghĩa nhất là sử dụng readonlythuộc tính mà đầu vào hộp kiểm có thể có. Không css, không hình ảnh, vv; một thuộc tính HTML tích hợp!

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

Như được mô tả ở đây trong thủ thuật cuối cùng: http://css-tricks.com/indeterminate-checkboxes/


Giải pháp tuyệt vời nhưng thật đáng buồn là điều này không hoạt động trong IE (thử nghiệm với phiên bản 11) vì các nhấp chuột nhanh hơn không được nhận ra nữa.
ViRuSTriNiTy

3

Dưới đây là một ví dụ có thể chạy được bằng cách sử dụng indeterminatethuộc tính được đề cập :

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>

Chỉ cần chạy đoạn mã để xem nó trông như thế nào.


2

Giống như @Franz trả lời, bạn cũng có thể làm điều đó với một lựa chọn. Ví dụ:

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

Với điều này, bạn cũng có thể đưa ra một giá trị cụ thể sẽ được gửi cùng với biểu mẫu, tôi nghĩ rằng với phiên bản hộp kiểm không xác định javascript, nó sẽ gửi giá trị gạch chân của hộp kiểm.

Ít nhất, bạn có thể sử dụng nó như một cuộc gọi lại khi javascript bị vô hiệu hóa. Ví dụ: cung cấp cho nó một id và trong sự kiện tải, hãy đổi nó thành phiên bản javascript của hộp kiểm với trạng thái không xác định.


2

Ngoài tất cả các trích dẫn ở trên, còn có các plugin jQuery cũng có thể giúp ích:

cho các hộp kiểm riêng lẻ:

cho các hộp kiểm hành vi giống như cây:

EDIT Cả hai thư viện đều sử dụng thuộc tính hộp kiểm ' không xác định ', vì thuộc tính này trong Html5 chỉ dành cho kiểu dáng ( https://www.w3.org/TR/2011/WD-html5-20110113/number-state.html#checkbox-state ), giá trị null không bao giờ được gửi đến máy chủ (hộp kiểm chỉ có thể có hai giá trị).

Để có thể gửi giá trị này đến máy chủ, tôi đã tạo các trường đối tác ẩn được điền trên biểu mẫu bằng cách sử dụng một số javascript. Về phía máy chủ, dĩ nhiên bạn cần kiểm tra các trường đối tác đó thay vì các hộp kiểm ban đầu.

Tôi đã sử dụng thư viện đầu tiên (hộp kiểm độc lập) trong đó điều quan trọng là:

  • Khởi tạo các giá trị được kiểm tra, không được kiểm tra, không xác định
  • sử dụng hàm .val () để lấy giá trị thực
  • Không thể thực hiện công việc .state (có thể là lỗi của tôi)

Mong rằng sẽ giúp.


2

Ở đây ví dụ khác với jQuery và thuộc tính đơn giản 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>


1

Đề cập đến câu trả lời @BoltClock , đây là giải pháp của tôi cho phương pháp đệ quy phức tạp hơn:

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

Nó có thể không phải là giải pháp đẹp nhất nhưng nó hoạt động tốt với tôi và khá linh hoạt.

Tôi sử dụng hai đối tượng dữ liệu xác định vùng chứa:

data-select-all="chapter1"

và các yếu tố:

data-select-some="chapter1"

Cả hai đều có cùng giá trị. Sự kết hợp của cả hai đối tượng dữ liệu trong một hộp kiểm cho phép các cấp dưới, được quét theo cách đệ quy. Do đó, cần có hai chức năng "trợ giúp" để ngăn chặn trình kích hoạt thay đổi.



0

Có thể tắt các thành phần biểu mẫu HTML - điều đó có xảy ra không? Người dùng của bạn sẽ thấy nó ở một trong ba trạng thái, tức là đã được kiểm tra, không được kiểm tra và bị vô hiệu hóa, sẽ bị mờ đi và không thể nhấp được. Đối với tôi, điều đó có vẻ tương tự như "null" hoặc "không áp dụng" hoặc bất cứ điều gì bạn đang tìm kiếm ở trạng thái thứ ba đó.


Ý tưởng rất tốt, nhưng tôi cần người dùng có thể nhấp lại. Tôi sợ rằng trên một hộp kiểm bị vô hiệu hóa, tôi sẽ gặp khó khăn khi bắn các sự kiện và như vậy.
Pekka

bạn vẫn có thể thấy giá trị của hộp kiểm bị vô hiệu hóa, gây nhầm lẫn cho người dùng nếu giá trị không quan trọng.
Janus Troelsen

Tôi nghĩ 'null' có nghĩa là đại diện cho người dùng không cung cấp câu trả lời cho câu hỏi. Nó không nhất thiết có nghĩa là câu hỏi không được áp dụng.
bdsl


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.