【问题标题】:Tri-state Check box in HTML?HTML中的三态复选框?
【发布时间】:2010-12-16 02:44:57
【问题描述】:

没有办法在 HTML 中设置三态检查按钮(是、否、null),对吧?

有没有什么简单的技巧或变通方法,而不必自己渲染整个东西?

【问题讨论】:

  • 在功能上,你的使用中'no'和'null'有什么区别?
  • 看看下面的答案(我的除外)。 “Null”的意思是“No answer”……
  • 没错。这是一个有祖先的项目,“null”表示“使用父值”。
  • 三态复选框的另一种用法是在搜索/过滤时。例如,假设我有一个搜索二手车列表的界面。搜索选项之一可能是汽车是否有天窗。这三种状态可以如下使用: 只显示带天窗的汽车 只显示没有天窗的汽车 两者都显示 现在,当然,这可以通过多种方式处理……我们可以使用下拉菜单,也可以使用集合三个单选按钮......但是一个三态复选框(或者是空的,有一个绿色的复选标记,或者有一个红色的 x)也是一个很好的解决方案。
  • 这对于复选框列表很有用,列表顶部的一个复选框可以选中或取消选中所有剩余的框。如果全部选中,则标题复选框可以反映这一点。如果所有都未选中,那么标题复选框也可以反映这一点。如果列表包含选中框和未选中框的组合,则在中间状态显示标题复选框将提供视觉反馈。该标题复选框永远不会带有值 - 它只是一个视觉提示和 UI 辅助。能够在所有三种状态之间切换 head 复选框也很方便。

标签: html forms checkbox


【解决方案1】:

您可以使用无线电组来实现该功能:

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

【讨论】:

  • 我知道,谢谢。 :) 我目前正在使用选择,但表单有点混乱。
  • 好吧,那么第三个状态究竟会是什么样子呢?就像禁用复选框一样?你想如何触发它?
【解决方案2】:

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

试试这里的例子:http://www.dynamicdrive.com/forums/archive/index.php/t-26322.html

【讨论】:

    【解决方案3】:

    HTML 表单元素是可能的禁用——不是吗?您的用户会看到它处于三种状态之一,即选中、未选中和禁用,这将显示为灰色且不可点击。对我来说,这似乎类似于“空”或“不适用”或您在第三种状态中寻找的任何内容。

    【讨论】:

    • 非常好的主意,但我需要用户能够再次单击它。我担心在禁用的复选框上,我将无法触发事件等等。
    • 您仍然可以看到禁用复选框的值,如果该值不重要,这会让用户感到困惑。
    • 我认为'null'是为了代表用户没有提供问题的答案。这并不一定意味着该问题不适用。
    【解决方案4】:

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

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

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

    element.indeterminate = true;
    

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

    • indeterminate 状态不能在 HTML 标记中设置,只能通过 Javascript 来完成(参见 JSfiddle testdetailed article in CSS tricks

    • 这个状态不会改变复选框的值,它只是一个视觉提示,掩盖了输入的真实状态。

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

    上一个答案

    另一种选择是使用复选框透明度 对于“某些选定”状态(就像 Gmail does 用于 在以前的版本中执行)。它将需要一些 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/

    希望有帮助!

    【讨论】:

    【解决方案5】:

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

    【讨论】:

    • 根据 Bert Bos 在 2002 年的一封电子邮件中 ​​(lists.w3.org/Archives/Public/www-dom/2002JanMar/0014.html>),IE/Win 和 IE/Mac 从版本 4 开始就支持它。Firefox 似乎在版本 3.6 中实现了它。它似乎也已于 2008 年在 Safari 中实现。我认为最终用户并不多。
    • 改用此网址 (help.dottoro.com/ljuocesd.php)。它显示谁支持它(每个人都在酒吧歌剧院),从什么时候开始,并直观地显示它是什么。人们害怕规范页面。为这个非插件解决方案 +1
    【解决方案6】:

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

    【讨论】:

      【解决方案7】:

      带有复选框插件的jQuery插件“jstree”可以做到这一点。

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

      -马特

      【讨论】:

        【解决方案8】:

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

        【讨论】:

        【解决方案9】:

        像@Franz 回答一样,您也可以通过选择来完成。例如:

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

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

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

        【讨论】:

          【解决方案10】:

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

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

          如上一招中所述: http://css-tricks.com/indeterminate-checkboxes/

          【讨论】:

          • 不错的解决方案,但遗憾的是这在 IE 中不起作用(使用版本 11 进行测试),因为不再识别更快的点击。
          【解决方案11】:

          我的建议将使用

          • 三种状态的三个适当的 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; 
                 };" />  

          【讨论】:

            【解决方案12】:

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

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

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

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

            data-select-all="chapter1"
            

            以及元素本身:

            data-select-some="chapter1"
            

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

            【讨论】:

              【解决方案13】:

              除了上面提到的,还有一些 jQuery 插件也可以提供帮助:

              对于单个复选框:

              对于树状行为复选框:

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

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

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

              • 初始化选中、未选中、不确定的值
              • 使用 .val() 函数获取实际值
              • 无法工作 .state(可能是我的错误)

              希望对您有所帮助。

              【讨论】:

                【解决方案14】:

                这是一个使用提到的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>

                只需运行代码 sn-p 即可查看它的外观。

                【讨论】:

                  【解决方案15】:

                  这里有简单的 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>

                  【讨论】:

                    【解决方案16】:

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

                    <!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>
                    

                    【讨论】:

                      【解决方案17】:

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

                      MVC razor 对每个复选框使用 2 个输入(复选框和具有相同名称的隐藏始终强制提交中的值)。 MVC 使用“true”作为复选框值,使用“false”作为同名隐藏;使其可以在 API 调用中使用布尔值。这个 sn-p 使用第三个隐藏状态来保存最后一次提交的请求值。

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

                      该页面还使用查询字符串上的任何值填充另一个隐藏(例如,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);
                      });
                      

                      【讨论】:

                        猜你喜欢
                        • 2010-11-18
                        • 1970-01-01
                        • 1970-01-01
                        • 2016-10-26
                        • 2011-03-07
                        • 1970-01-01
                        • 2011-05-16
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多