嵌套复选框不能使用多个主选项

时间:2017-10-26 14:54:36

标签: javascript jquery html css checkbox

我已使用以下codepen snippet在我的HTML页面中实现嵌套复选框。原始代码仅适用于一组嵌套复选框,因此我尝试将其扩展为多个。但是,它似乎适用于本例Main2中的最后一个Main元素,而不是之前的元素。



function loadExpandableCheckboxes() {
	
	var expandableCheckboxes = document.getElementsByClassName("expandable-checkbox");
	for (var i = 0; i < expandableCheckboxes.length; i++) {
		
		var checkboxMainOption = expandableCheckboxes[i].getElementsByClassName("expandable-checkbox-main-option")[0];
		
		var checkboxSubOptions = expandableCheckboxes[i].getElementsByClassName("expandable-checkbox-sub-option");
		for (var j = 0; j < checkboxSubOptions.length; j++) {
			
			checkboxSubOptions[j].onclick = function() {
				
				var checkedCount = 0;
				for (var k = 0; k < checkboxSubOptions.length; k++) {
					if (checkboxSubOptions[k].checked) {
						checkedCount++;
					}
				}
				
				checkboxMainOption.checked = checkedCount > 0;
				checkboxMainOption.indeterminate = checkedCount > 0 && checkedCount < checkboxSubOptions.length;
			}
		}
		
		checkboxMainOption.onclick = function() {
			
			for (var j = 0; j < checkboxSubOptions.length; j++) {
				checkboxSubOptions[j].checked = checkboxMainOption.checked;
			}
		}
	}
}
onload=loadExpandableCheckboxes;
&#13;
body {
  color: #555;
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

ul {
  list-style: none;
}

li {
  margin-top: 1em;
}

label {
  font-weight: bold;
}
&#13;
<html>
  <head>
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
  </head>
  <body>
    <div class="checkbox-container">
      <ul>
        <li>
		  <div class="expandable-checkbox">
            <label><input type="checkbox" class="expandable-checkbox-main-option">Main 1</label>
            <ul>
              <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 1 Sub 1</label></li>
              <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 1 Sub 2</label></li>
              <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 1 Sub 3</label></li>
            </ul>
		  </div>
        </li>
        <li>
		  <div class="expandable-checkbox">
            <label><input type="checkbox" class="expandable-checkbox-main-option">Main 2</label>
            <ul>
              <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 2 Sub 1</label></li>
              <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 2 Sub 2</label></li>
              <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 2 Sub 3</label></li>
            </ul>
		  </div>
        </li>
      </ul>
    </div>
	  
  </body>
</html>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:4)

这是一个有趣的。因此,基本上停止使用第二组覆盖第一组复选框,您需要使用临时范围来保留变量。在下面的代码段中,您会看到我在l1, l2, l3 = [i.strip('\n') for i in open('filename.txt')] new_lines = ["{} {}".format(l1, l2), l3] print('\n'.join(new_lines)) 循环中添加了IFFE

这样做是将变量i传递给临时函数,该函数立即调用自身。下次循环运行时,会创建一个新的临时函数&#34;从而保留最后一个的范围,而不是覆盖以前的复选框集。

&#13;
&#13;
i
&#13;
$(document).ready(function() {
  //find the wrappers
  var expandableCheckboxes = document.getElementsByClassName("expandable-checkbox");
  //loop through the wrappers, count them one by one
  for (var i = 0; i < expandableCheckboxes.length; i++) (function(i){
  
    //find the the main
    var checkboxMainOption = expandableCheckboxes[i].getElementsByClassName("expandable-checkbox-main-option")[0];
    //find the subs
    var checkboxSubOptions = expandableCheckboxes[i].getElementsByClassName("expandable-checkbox-sub-option");
    //loop through subs
    for (var k = 0; k < checkboxSubOptions.length; k++) {
      
      //add listener fo each sub
      checkboxSubOptions[k].onclick = function() {
        var checkedCount = 0;
        for (var j = 0; j < checkboxSubOptions.length; j++) {
          if (checkboxSubOptions[j].checked) {
            checkedCount++;
          }
        }
        //mark appropriately
        checkboxMainOption.checked = checkedCount > 0;
        checkboxMainOption.indeterminate = checkedCount > 0 && checkedCount < checkboxSubOptions.length;
      }
    }
    //add listener to main
    checkboxMainOption.onclick = function() {
      for (var j = 0; j < checkboxSubOptions.length; j++) {
        checkboxSubOptions[j].checked = checkboxMainOption.checked;
      }
    }
  })(i)
});
&#13;
body {
  color: #555;
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

ul {
  list-style: none;
}

li {
  margin-top: 1em;
}

label {
  font-weight: bold;
}
&#13;
&#13;
&#13;

答案 1 :(得分:3)

如果你不介意使用JQuery,可以在这里缩短你的JS。试试下面的代码:

$(document).ready(function() {
  $('.expandable-checkbox-main-option').change(function() {
    $(this).parent().parent('div').find('.expandable-checkbox-sub-option').prop('checked', $(this).prop('checked'));
  });

  $('.expandable-checkbox-sub-option').change(function() {
    var parentCheckboxDiv = $(this).parent().parent().parent().parent('div');
    var parentCheckbox = parentCheckboxDiv.find('.expandable-checkbox-main-option');
    var checkedSubOptions = parentCheckboxDiv.find('.expandable-checkbox-sub-option:checked');
    var subOptions = parentCheckboxDiv.find('.expandable-checkbox-sub-option');

    parentCheckbox.prop('indeterminate', checkedSubOptions.length && checkedSubOptions.length != subOptions.length);
    parentCheckbox.prop('checked', checkedSubOptions.length == subOptions.length)
  });
});
body {
  color: #555;
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

ul {
  list-style: none;
}

li {
  margin-top: 1em;
}

label {
  font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="checkbox-container">
  <ul>
    <li>
      <div class="expandable-checkbox">
        <label><input type="checkbox" class="expandable-checkbox-main-option">Main 1</label>
        <ul>
          <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 1 Sub 1</label></li>
          <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 1 Sub 2</label></li>
          <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 1 Sub 3</label></li>
        </ul>
      </div>
    </li>
    <li>
      <div class="expandable-checkbox">
        <label><input type="checkbox" class="expandable-checkbox-main-option">Main 2</label>
        <ul>
          <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 2 Sub 1</label></li>
          <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 2 Sub 2</label></li>
          <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 2 Sub 3</label></li>
        </ul>
      </div>
    </li>
    <li>
      <div class="expandable-checkbox">
        <label><input type="checkbox" class="expandable-checkbox-main-option">Main 3 (5 options)</label>
        <ul>
          <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 3 Sub 1</label></li>
          <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 3 Sub 2</label></li>
          <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 3 Sub 3</label></li>
          <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 3 Sub 4</label></li>
          <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 3 Sub 5</label></li>
        </ul>
      </div>
    </li>
  </ul>
</div>