HTML中的三态复选框?

时间:2009-11-12 23:20:39

标签: html forms checkbox

HTML中无法使用三态检查按钮(是,否,为null),对吗?

是否有任何简单的技巧或解决方法而无需自己呈现整个事物?

17 个答案:

答案 0 :(得分:109)

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

HTML5为名为indeterminate

的复选框定义了一个属性

w3c reference guide。要使复选框显示在视觉上不确定,请将其设置为true:

element.indeterminate = true;

这是Janus Troelsen's fiddle。但请注意:

  • 无法在HTML标记中设置indeterminate状态,只能通过Javascript(请参阅此JSfiddle test和此detailed article in CSS tricks

  • 此状态不会更改复选框的值,它只是一个屏蔽输入实际状态的视觉提示。

  • 浏览器测试:在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);
}
     

处理select all复选框的三态的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 :(得分:46)

您可以在input元素上使用HTML indeterminate IDL attribute

答案 2 :(得分:11)

我的建议是使用

  • 三个状态的三个适当的unicode字符,例如❓,✅,❌
  • 纯文本输入字段(size = 1)
  • 无边框
  • 只读
  • 显示无光标
  • onclick处理程序以切换到三个状态

参见以下示例:

HTML来源:

<input type='text' 
       style='border: none;' 
       onfocus='this.blur()' 
       readonly='true' 
       size='1' 
       value='&#x2753;' onclick='tristate_Marks(this)' />

或作为内联javascript:

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

Javascript源代码:

<script type="text/javascript" charset="utf-8">
  /**
   *  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');
  }

</script>

答案 3 :(得分:4)

您可以使用不确定状态:http://css-tricks.com/indeterminate-checkboxes/。开箱即用的浏览器支持它,并且不需要任何外部js库。

答案 4 :(得分: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

答案 5 :(得分:3)

我认为最具语义性方式是使用复选框输入可以具有的readonly属性。没有CSS,没有图像等;一个内置的HTML属性!

请参阅小提琴:
http://jsfiddle.net/chriscoyier/mGg85/2/

如最后一招所述: http://css-tricks.com/indeterminate-checkboxes/

答案 6 :(得分:2)

与@Franz一样,你也可以选择一个。例如:

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

有了这个你还可以给出一个与表单一起发送的具体值,我认为使用javascript不确定版本的复选框,它会发送复选框的下划线值。

至少,您可以在禁用javascript时将其用作回调。例如,给它一个id,并在load事件中将其更改为具有不确定状态的复选框的javascript版本。

答案 7 :(得分:2)

Besides all cited above, there are jQuery plugins that may help too:

for individual checkboxes:

for tree-like behavior checkboxes:

EDIT Both libraries uses the 'indeterminate' checkbox attribute, since this attribute in Html5 is just for styling (https://www.w3.org/TR/2011/WD-html5-20110113/number-state.html#checkbox-state), the null value is never sent to the server (checkboxes can only have two values).

To be able to submit this value to the server, I've create hidden counterpart fields which are populated on form submission using some javascript. On the server side, you'd need to check those counterpart fields instead of original checkboxes, of course.

I've used the first library (standalone checkboxes) where it's important to:

  • Initialize the checked, unchecked, indeterminate values
  • use .val() function to get the actual value
  • Cannot make work .state (probably my mistake)

Hope that helps.

答案 8 :(得分:1)

由于我需要这样的东西-在表中没有用于脚本生成的复选框的任何插件...我最终得到了以下解决方案:

<!DOCTYPE html>
<html>
<body>

Toto <input type="checkbox" id="myCheck1" onclick="updateChkBx(this)" /><br />
Tutu <input type="checkbox" id="myCheck2" onclick="updateChkBx(this)" /><br />
Tata <input type="checkbox" id="myCheck3" onclick="updateChkBx(this)" /><br />
Tete <input type="checkbox" id="myCheck4" onclick="updateChkBx(this)" /><br />

<script>
var chkBoxState = [];

function updateChkBx(src) {
  var idx = Number(src.id.substring(7)); // 7 to bypass the "myCheck" part in each checkbox id
  if(typeof chkBoxState[idx] == "undefined") chkBoxState[idx] = false; // make sure we can use stored state at first call
  
  // the problem comes from a click on a checkbox both toggles checked attribute and turns inderminate attribute to false
  if(chkBoxState[idx]) {
    src.indeterminate = false;
    src.checked = false;
    chkBoxState[idx] = false;
  }
  else if (!src.checked) { // passing from checked to unchecked
    src.indeterminate = true;
    src.checked = true; // force considering we are in a checked state
    chkBoxState[idx] = true;
  }
}
// to know box state, just test indeterminate, and if not indeterminate, test checked
</script>

</body>
</html>

答案 9 :(得分:1)

这里是其他具有简单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>

答案 10 :(得分:1)

参考@BoltClock answer,这是我对更复杂的递归方法的解决方案:

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

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

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

data-select-all="chapter1"

和元素本身:

data-select-some="chapter1"

两者具有相同的价值。一个复选框内的两个数据对象的组合允许递归扫描的子级别。因此,需要两个“帮助”功能来防止更改触发。

答案 11 :(得分:0)

基于上面使用不确定状态的答案,我想出了一点点来处理单个复选框并使它们成为三态。

MVC razor 无论如何对每个复选框使用 2 个输入(复选框和具有相同名称的隐藏始终强制提交中的值)。 MVC 使用“true”作为复选框值,使用“false”作为同名隐藏;使其适合在 api 调用中使用布尔值。此代码段使用第三个隐藏来在提交中保留最后一个请求值。

用下面初始化的复选框将开始不确定。检查一次打开复选框。检查两次关闭复选框(返回相同名称的隐藏值)。第三次检查将返回不确定(并清除隐藏的,因此提交将产生空白)。

该页面还会使用查询字符串上的任何值填充另一个隐藏(例如 triBox2Orig)以开始,因此可以在提交之间初始化和持久化 3 个状态。

$(document).ready(function () {
    var initCheckbox = function (chkBox)
    {
        var hidden = $('[name="' + $(chkBox).prop("name") + '"][type="hidden"]');
        var hiddenOrig = $('[name="' + $(chkBox).prop("name") + 'Orig"][type="hidden"]').prop("value");
        hidden.prop("origValue", hidden.prop("value"));
        if (!chkBox.prop("checked") && !hiddenOrig) chkBox.prop("indeterminate", true);
        if (chkBox.prop("indeterminate")) hidden.prop("value", null);
        chkBox.change(checkBoxToggleFun);
    }

    var checkBoxToggleFun = function ()
    {
        var isChecked = $(this).prop('checked');
        var hidden = $('[name="' + $(this).prop("name") + '"][type="hidden"]');
        var thirdState = isChecked && hidden.prop("value") === hidden.prop("origValue");
        if (thirdState) {   // on 3rd click of a checkbox, set it back to indeterminate
            $(this).prop("indeterminate", true);
            $(this).prop('checked', false);
        }
        hidden.prop("value", thirdState ? null : hidden.prop("origValue"));
    };

    var chkBox = $('#triBox1');
    initCheckbox(chkBox);

    chkBox = $('#triBox2');
    initCheckbox(chkBox);
});

答案 12 :(得分:0)

以下是使用上述indeterminate attribute的可运行示例:

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>

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

答案 13 :(得分:0)

带有复选框插件的jQuery插件“jstree”可以执行此操作。

http://www.jstree.com/documentation/checkbox

-Matt

答案 14 :(得分:0)

有一个简单的JavaScript三态输入字段实现 https://github.com/supernifty/tristate-checkbox

答案 15 :(得分:0)

可以将HTML表单元素禁用 - 这不是吗?您的用户会在三种状态中看到它,即已选中,未选中和已禁用,这些状态将显示为灰色且无法点击。对我来说,这看起来类似于“无效”或“不适用”或者你在第三个州寻找的任何东西。

答案 16 :(得分:0)

你需要使用javascript / css来伪造它。

请尝试此示例:http://www.dynamicdrive.com/forums/archive/index.php/t-26322.html