【问题标题】:selecting all or some parent / child checkboxes in a styled format以样式格式选择所有或部分父/子复选框
【发布时间】:2015-01-08 14:32:56
【问题描述】:

首先:http://jsfiddle.net/1q5st19f/

我有一个复选框组,如果选中所有子复选框(国家/地区),则父复选框(区域)也会被选中。同样,如果父复选框未选中,则子复选框也应取消选中。我找到了一个完美运行的脚本,直到我使用 prettyCheckable(来自 http://arthurgouveia.com/prettyCheckable/)设置复选框的样式。

如果我删除 prettyCheckable,它会起作用。如果我添加它,它的样式正确,但不再起作用。我究竟做错了什么?我试图重命名这些类,但也没有用。

基本的标记是这样的

<fieldset>
    <input type="checkbox" class="parentCheckBox" /> Africa 
    <div class="content">   
    &nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="cntrs[]" class="childCheckBox" data-label=""> Algeria<br />
    &nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="2" name="cntrs[]" class="childCheckBox" data-label=""> Angola<br />
    &nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="3" name="cntrs[]" class="childCheckBox" data-label=""> Benin<br />
</div>
</fieldset> 

【问题讨论】:

  • 看这个页面,arthurgouveia.com/prettyCheckable ...我看到这个类有一个方法来显式地选中或取消选中复选框。可能这个类没有使用“checked”属性来切换它的选中状态?
  • 这是有道理的......但我对 jQuery 了解得不够多,不知道这是否意味着它根本不可能?

标签: javascript jquery checkbox


【解决方案1】:

prettyCheckable 在幕后所做的是隐藏复选框并向页面添加a 标记,并在单击a 标记时更新隐藏的复选框。当复选框被选中时,a 标记也会获得checked 的样式。不过似乎有一个错误,当通过代码操作复选框的状态时,checked 类不会添加到 a 标记中或从标记中删除。无论如何,您的 JavaScript 正确地更新了复选框的状态,但 prettyCheckable 没有检测到这一点并且未能更新其类。

无论如何,我重写了您的脚本,因此所有逻辑都在 1 个事件处理程序中处理,并且我包含了一个针对 prettyCheckable 错误的解决方法,但我留下了您的 HTML,因此您只需要替换您的 JavaScript 代码。请参阅下面的可运行示例:

$('input:checkbox').prettyCheckable();

$("input:checkbox").on("change", function() {
  var checkbox = $(this);
  var parent = checkbox.closest("fieldset");
  if (checkbox.hasClass("parentCheckBox")) {
    //this is a parent, check or uncheck all children
    var isChecked = checkbox.is(":checked");
	
    //add checked attribute in the DOM and add the class for prettyCheckable on all children
    parent.find("input.childCheckBox:checkbox").prop("checked", isChecked).each(function() {
      if (isChecked)
        $(this).next("a").addClass('checked');
      else
        $(this).next("a").removeClass('checked');
    });
  } else {
    //this is a child, check or uncheck the parent
    var parentCheckbox = parent.find("input.parentCheckBox:checkbox");
    var isChecked = !parent.find("input.childCheckBox:checkbox").get().some(function(item) {
      return !$(item).is(":checked");
    });
    
    //add the checked attribute to the dom and add the class for prettyCheckable
    parentCheckbox.prop("checked", isChecked);
    if (isChecked)
      parentCheckbox.next("a").addClass('checked');
    else
      parentCheckbox.next("a").removeClass('checked');
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://qfuse.com/js/utils/prettyCheckable/prettyCheckable.js"></script>
<link href="http://arthurgouveia.com/prettyCheckable/js/prettyCheckable/dist/prettyCheckable.css" rel="stylesheet"/>
<fieldset>
	<input type="checkbox" class="parentCheckBox" /> Africa 
	<div class="content">	
        &nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="cntrs[]" class="childCheckBox" data-label="" /> Algeria<br />
        &nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="2" name="cntrs[]" class="childCheckBox" data-label="" /> Angola<br />
        &nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="3" name="cntrs[]" class="childCheckBox" data-label="" /> Benin<br />
</div>
</fieldset>

【讨论】:

    【解决方案2】:

    这花了我很长时间来调试。有许多问题,其中最重要的是您使用的是非常落后的 prettyCheckable 版本。但是,在更改到最新级别并重新开始后,我为您提供了一个完整的解决方案。看到这个jsFiddle

    我从头开始,但这里是代码:

    HTML

    <fieldset>
        <div class="group">
            <input type="checkbox" class="parentCheckBox" data-label="Africa"/>
            <div class="content">&nbsp;&nbsp;&nbsp;&nbsp;
                <input type="checkbox" value="1" class="childCheckBox" data-label="Algeria" />
                <br />&nbsp;&nbsp;&nbsp;&nbsp;
                <input type="checkbox" value="2" class="childCheckBox" data-label="Angola" />
                <br />&nbsp;&nbsp;&nbsp;&nbsp;
                <input type="checkbox" value="3" class="childCheckBox" data-label="Benin" />
                <br />
            </div>
        </div>
    </fieldset>
    

    JavaScript

    $(function () {
        $('input:checkbox').each(function () {
            $(this).prettyCheckable();
        });
    
        $(".parentCheckBox").change(function (e) {
            var checked = $(this).prop("checked");
            $(".childCheckBox", $(this).closest(".group")).each(function (i, e) {
                $(e).prettyCheckable(checked?"check":"uncheck");
            });
        });
    
        $(".childCheckBox").change(function(e) {
            var checkedCount = unCheckedCount = 0;
            $(e.currentTarget).closest(".content").find(".childCheckBox").each(function(i,e2) {
                if ($(e2).prop("checked")) {
                    checkedCount++;
                } else {
                    unCheckedCount++;
                }
            });
            if (unCheckedCount == 0) {
                $(e.currentTarget).closest(".group").find(".parentCheckBox").prettyCheckable("check");
            } else {
                $(e.currentTarget).closest(".group").find(".parentCheckBox").prettyCheckable("uncheck");
            }
        });
    });
    

    我很乐意回答您的任何问题。

    选中或取消选中所有子项的语义可以在此jsFiddle 中显示替代解决方案。它会根据子项的功能确定何时应选中或取消选中父复选框。

    【讨论】:

      【解决方案3】:

      prettyCheckable 让这有点棘手。它在文档中说您可以使用$('#myInput').prettyCheckable('check');,但我无法让它工作。所以我只是使用了锚类checked来确定是否选中了复选框。

      这可能不是最漂亮的实现,但它正在工作。您应该使代码更加模块化,也许可以重新考虑我快速做出的一些选择。

      首先,我从 HTML 中删除了 childCheckBox,并使用选项初始化了 prettyCheckable,因此我可以将类放入包装器 div:

      // make childCheckboxes prettyCheckable
      $('.content input:checkbox').each(function () {
          $(this).prettyCheckable({
              // add this class to the wrapper div created by prettyCheckable
              customClass: "childCheckBox"
          });
      });
      

      与 parentCheckbox 相同:

      // make parentCheckBox prettyCheckable
      $('input:checkbox.parentInput').prettyCheckable({
          // add this class to the wrapper div created by prettyCheckable
          customClass: "parentCheckBox"
      });
      

      我还更改了 childCheckBox 点击事件以执行您想要的功能

      //clicking the last unchecked or checked checkbox should check or uncheck the parent checkbox
          $('.childCheckBox').click(function () {
              var $parentAnchor = $(this).parents('fieldset:eq(0)').find('.parentCheckBox a');
              var $childAnchors = $(this).parents('fieldset:eq(0)').find('.childCheckBox a');
              var $thisAnchor = $(this).find('a');
      
              var parentIsChecked = $parentAnchor.hasClass('checked');
              var thisIsChecked = $thisAnchor.hasClass('checked');
      
              var isLastOne = true;
              // loop through all childCheckBoxes and determine if this is the last one checked or unchecked
              $childAnchors.each(function (index) {
                  if ((!thisIsChecked && $(this).hasClass('checked'))
                      || (thisIsChecked && !$(this).hasClass('checked'))) {
                      isLastOne = false;
                  }
              });
      
              // if the childCheckBox was the last one, change the state of the parentCheckBox
              if (isLastOne && thisIsChecked) {
                  $parentAnchor.addClass('checked');
              } else if (isLastOne && !thisIsChecked) {
                  $parentAnchor.removeClass('checked');
              }
          });
      

      分叉时我很累,所以我希望我没有犯任何愚蠢的错误。如果您对代码有任何疑问,请提出。

      小提琴:http://jsfiddle.net/1q5st19f/17/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-01
        • 1970-01-01
        • 2013-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多