HTML中的三态复选框?

197

在HTML中,没有三态复选按钮(是、否、空值),对吗?

有没有简单的技巧或解决方法,而不必自己渲染整个按钮?


在你的使用中,“no”和“null”之间的功能上有什么区别? - David Thomas
5
请看以下答案(除了我的)。"Null" 意思类似于“无回答”... - Franz
2
没错,它是一个带有祖先的项目,“null”意味着“使用父级值”。 - Pekka
9
一种三态复选框的替代用途是在搜索/筛选时使用。例如,假设我有一个界面来搜索一系列二手车。其中一个搜索选项可能是这辆车是否有天窗。可以使用三种状态如下:仅显示拥有天窗的汽车 仅显示没有天窗的汽车 显示两者当然,这可以通过多种方式处理...我们可以使用下拉菜单,或者我们可以使用一组三个单选按钮...但是三态复选框(它可以为空、有一个绿色的勾号或者有一个红色的叉号)也是一个不错的解决方案。 - Mir
4
在一个复选框列表中,添加一个复选框在列表头部,用于勾选或取消勾选所有剩余的复选框,这样做会很有用。如果所有的复选框都被勾选了,那么列表头部的复选框也应该被勾选。如果所有的复选框都没有被勾选,那么列表头部的复选框也应该未被勾选。如果复选框列表同时包含已勾选和未勾选的选项,那么在列表头部显示复选框处于中间状态,可以提供视觉反馈。这个列表头部的复选框不会带有任何值,它只是一种视觉提示和用户界面辅助工具。另外,能够在三种状态之间切换列表头部的复选框也会非常方便。 - Jason
显示剩余2条评论
18个回答

1
使用辅助变量和 indeterminate 的简短代码片段:

cb1.state = 1

function toggle_tristate(cb) {
    cb.state = ++cb.state % 3   // cycle through 0,1,2
    if (cb.state == 0) {
        cb.indeterminate = true;
        cb.checked = true;   // after 'indeterminate' the state 'false' follows 
    }
}
<input id="cb1" type="checkbox" onclick="toggle_tristate(this)">

只有当 state==0 时才会被捕获,其余情况都会被自动处理。

http://jsfiddle.net/6vyek2c5


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>


我在这里找到了相同的示例:https://css-tricks.com/indeterminate-checkboxes/#aa-rotating-amongst-the-states。 - Friedrich -- Слава Україні

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>

0

0

HTML表单元素可以被禁用,这不是可以解决你的问题吗?你的用户会看到它有三种状态:选中、未选中和禁用。禁用状态是灰色的且不可点击。对我而言,这似乎类似于第三种状态中的“null”或“不适用”或任何你在寻找的东西。


非常好的想法,但我需要让用户能够再次单击它。我担心在禁用的复选框上,我将难以触发事件等。 - Pekka
如果禁用的复选框的值不重要,用户仍然可以看到它的值,这会让用户感到困惑。 - Janus Troelsen
我认为“null”表示用户没有回答问题,而不一定意味着该问题不适用。 - bdsl

0

0

在上述使用不定状态的答案的基础上,我想出了一个小技巧,可以处理单个复选框并使它们成为三态。

MVC Razor 每个复选框使用两个输入(复选框和带有相同名称的隐藏输入来始终强制提交值)。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);
});

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接