HTML中的三态复选框?


162

没有办法在HTML中具有三态检查按钮(是,否,空),对吗?

是否有任何简单的技巧或解决方法,而不必自己渲染整个内容?


从功能上讲,您的用法中“ no”和“ null”有什么区别?
大卫说,请

5
查看下面的答案(我的除外)。“空”的意思是“没有答案” ...
弗朗兹(Franz)

2
究竟。这是一个带有祖先的项目,“ null”表示“使用父级值”。
Pekka

7
三态复选框的另一种用法是在搜索/过滤时。例如,假设我有一个搜索二手车列表的界面。搜索选项之一可能是汽车是否装有天窗。可以按以下方式使用这三种状态:仅展示带有天窗的汽车仅展示带有天窗的汽车现在,当然,这可以通过多种方式处理...我们可以使用下拉菜单,也可以使用一组三个单选按钮中的一个...但是一个三态复选框(为空,带有绿色选中标记或带有红色x的标记)也是一个不错的解决方案。
Mir

2
对于一个复选框列表很有用,在列表的顶部有一个复选框可以选中或取消选中所有剩余的复选框。如果全部选中,则标题复选框可以反映出来。如果所有选项都未选中,则标题复选框也可以反映出来。如果列表包含选中框和未选中框的组合,则在中间状态下显示标题复选框将提供视觉反馈。标头复选框永远不会带有值-它只是视觉提示和UI辅助。能够在所有三个状态之间切换head复选框也很方便。
杰森

Answers:


118

编辑 -感谢Janus Troelsen的评论,我找到了一个更好的解决方案:

HTML5为复选框定义了一个属性,称为 indeterminate

请参阅w3c参考指南。要使复选框在视觉上不确定,请将其设置为true:

element.indeterminate = true;

这是Janus Troelsen的小提琴。但是请注意:

  • indeterminate国不能在HTML标记来设置,它只能通过Javascript完成(见本的jsfiddle测试,这在CSS技巧详细的文章

  • 此状态不会更改复选框的值,它只是掩盖输入真实状态的可视提示。

  • 浏览器测试:在Chrome 22,Firefox 15,Opera 12和IE7上为我工作。关于移动浏览器,iOS 3.1上的Android 2.0浏览器和Safari移动不支持它。

先前的答案

另一种方法是使用复选框透明度对于“某些选定的”状态发挥(如Gmail中使用在以前的版本做)。它将需要一些javascript和CSS类。在这里,我举了一个特殊的示例,该示例处理包含可检查项的列表和一个允许选择所有/不选择项的复选框。当某些列表项被选中时,此复选框显示“已选中”状态。

给定一个带有ID的复选框和一个#select_all带有一个类的多个复选框.select_one

淡入“全选”复选框的CSS类如下:

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

处理全选复选框的三态的JS代码如下:

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

您可以在这里尝试:http : //jsfiddle.net/98BMK/

希望有帮助!



1
经过chrome v35测试,“ all”复选框仅在首次单击时选中其他复选框。此后,仅取消选中其他复选框即可。在此版本中已修复:jsfiddle.net/CHRSb/1
rdans

2
.prop('checked', ...)应该代替.attr('checked', ...)
露娜2015年

我修正了罗斯指出的错误;这里有新提琴
Mike DeSimone

48

您可以在元素上使用HTML的indeterminateIDL属性input


3
根据Bert Bos在2002年发送的电子邮件中的消息(< list.w3.org/Archives/Public/www-dom/2002JanMar/0014.html>),IE / Win和IE / Mac自版本4开始就支持它。已在3.6版中实现。它似乎还于2008年在Safari中实现。我认为最终用户并不多。
Ms2ger

请改用此网址(help.dottoro.com/ljuocesd.php)。它显示了支持它的人(每个人的歌剧),从何时开始,并直观地显示了它是什么。人们对规格页面感到害怕。此非插件解决方案+1
Hashbrown

15

我的建议将使用

  • 三个状态的三个适当的unicode字符,例如❓,✅,❌
  • 纯文本输入字段(大小= 1)
  • 无边界
  • 只读
  • 不显示光标
  • onclick处理程序可通过三种状态进行切换

请参阅以下示例:

/**
 *  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

您可以使用广播组来实现该功能:

<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
我知道,谢谢。:)我目前正在使用selects,但是表单有点混乱。
Pekka

1
好吧,那么第三种状态到底会是什么样?就像禁用复选框一样?您想如何触发它?
Franz


3

这是一个使用上述indeterminate属性的可运行示例:

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>

只需运行代码片段即可查看其外观。


2

像@Franz答案一样,您也可以选择一个。例如:

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

有了这个,您还可以给出将随表格发送的具体值,我认为使用javascript不确定版本的复选框,它将发送复选框的下划线值。

至少,您可以在禁用javascript时将其用作回调。例如,为其提供一个ID,并在加载事件中将其更改为状态不确定的复选框的javascript版本。


2

除了上面引用的所有内容外,还有一些jQuery插件可能也有帮助:

对于单个复选框:

对于树状行为复选框:

编辑 这两个库都使用' indeterminate '复选框属性,因为Html5中的此属性仅用于样式设置(https://www.w3.org/TR/2011/WD-html5-20110113/number-state.html#checkbox-state),则永远不会将null值发送到服务器(复选框只能有两个值)。

为了能够将此值提交到服务器,我创建了隐藏的对应字段,这些字段使用一些JavaScript填充到表单提交中。当然,在服务器端,您需要检查那些对应字段而不是原始复选框。

我使用了第一个库(独立的复选框),其中重要的是:

  • 初始化选中,未选中,不确定的值
  • 使用.val()函数获取实际值
  • 无法执行状态(可能是我的错误)

希望有帮助。


2

这是其他具有简单jQuery和属性的示例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

引用@BoltClock 答案,这是我对更复杂的递归方法的解决方案:

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

它可能不是最漂亮的解决方案,但对我来说很好用,而且非常灵活。

我使用两个定义容器的数据对象:

data-select-all="chapter1"

以及元素本身:

data-select-some="chapter1"

两者具有相同的值。一个复选框中两个数据对象的组合允许子级别,这些子级别以递归方式进行扫描。因此,需要两个“辅助”功能来防止更改触发。



0

可以禁用 HTML表单元素-这样做不是吗?您的用户将以三种状态之一查看它,即选中,未选中和禁用,它们将显示为灰色且不可单击。对我来说,这似乎类似于“空”或“不适用”,或者您在该第三状态下正在寻找的任何东西。


很好,但我需要用户再次单击它。我担心在禁用的复选框上,我将无法触发事件等。
Pekka

您仍然可以看到已禁用复选框的值,如果该值不重要,则会使用户感到困惑。
Janus Troelsen

我认为“空”表示用户未提供问题的答案。这并不一定意味着该问题不适用。
bdsl


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.