简体   繁体   English

Javascript 验证所有复选框都被选中

[英]Javascript validate all checkboxes are selected

I'm having a twofold issue, which is due to my relative noobness to Javascript.我有一个双重问题,这是由于我对 Javascript 相对陌生。 I'm working to understand the basics, so this should be a simple fix I'm just not catching.我正在努力了解基础知识,所以这应该是一个简单的修复,我只是没有抓住。

Desired end result:期望的最终结果:

  1. If every checkbox on the page is clicked, "selectall" class should be hidden and "hideall" class should be visible.如果单击页面上的每个复选框,“selectall” class 应该被隐藏,“hideall” class 应该是可见的。

  2. If ANY checkbox is selected, 'attendance' and 'action' buttons should be green, 'random' button should be grey.如果选中任何复选框,“出席”和“操作”按钮应为绿色,“随机”按钮应为灰色。 (Opposite colors if no checkboxes are selected on page) (如果页面上没有选中复选框,则相反 colors)

  3. If I use the "selectAll()" function, the color rules above should apply.如果我使用“selectAll()”function,则应适用上述颜色规则。

Issues问题

  1. "selectall" class does not disappear if all the boxes are selected. “selectall” class 如果所有框都被选中,则不会消失。
  2. If I currently use the "selectAll()" function, the buttons do not turn green.如果我目前使用“selectAll()”function,按钮不会变成绿色。

My Understanding of the issue我对问题的理解

For issue #1, I have no idea the cause of the problem.对于问题 #1,我不知道问题的原因。 For issue #2, I'm getting the error TypeError: null is not an object (evaluating 'termsCheckBox.closest('form').querySelectorAll') which leads me to believe the problem is coming from the "selectAll()" function not being inside of an HTML form tag. For issue #2, I'm getting the error TypeError: null is not an object (evaluating 'termsCheckBox.closest('form').querySelectorAll') which leads me to believe the problem is coming from the "selectAll()" function不在 HTML 表单标签内。 Due to the structure of the page, I can't include this inside a form tag, and i'm not sure any walkarounds.由于页面的结构,我无法将其包含在表单标签中,并且我不确定是否有任何解决方法。

Please help me understand what's going wrong and how to fix it, If you have any advice for cleaning up my code.如果您对清理我的代码有任何建议,请帮助我了解发生了什么问题以及如何解决它。 that's appreciated too, I'm learning all on my own, so I appreciate the input and help!!这也很感激,我都是自己学习的,所以我很感激你的意见和帮助!!

Live Codepin https://codepen.io/dansbyt/pen/NWpXqev?editors=0110 Live Codepin https://codepen.io/dansbyt/pen/NWpXqev?editors=0110

Javascript: Javascript:

function chk(termsCheckBox){
      document.getElementById("attend").disabled = !termsCheckBox.closest('form').querySelectorAll("input[type=checkbox]:checked").length;
      if(document.getElementById("attend").disabled) {
        document.getElementById("attend").classList.remove("green-btn");
        document.getElementById("attend").classList.add("grey-btn");
        document.getElementById("action").classList.remove("green-btn");
        document.getElementById("action").classList.add("grey-btn");
        document.getElementById("random").classList.add("green-btn");
        document.getElementById("random").classList.remove("grey-btn");
      } 
      else {
        document.getElementById("attend").classList.add("green-btn");
        document.getElementById("attend").classList.remove("grey-btn");
        document.getElementById("action").classList.add("green-btn");
        document.getElementById("action").classList.remove("grey-btn");
        document.getElementById("random").classList.remove("green-btn");
        document.getElementById("random").classList.add("grey-btn");
      }
      var items = document.getElementsByTagName('input');
      for (var i = 0; i < items.length; i++) {
        if (items[i].type == 'checkbox') {
          if (items[i].checked) {
            document.getElementsByClassName("selectall")[0].style.display = "none";
            document.getElementsByClassName("hideall")[0].style.display = "block";
          }
        }
      }
    }

// Below this line is not verified to work yet //

function selectAll() {
    var items = document.getElementsByTagName('input');
    for (var i = 0; i < items.length; i++) {
        if (items[i].type == 'checkbox')
            items[i].checked = true;
    }
    document.getElementsByClassName("selectall")[0].style.display = "none";
    document.getElementsByClassName("hideall")[0].style.display = "block";
}

function hideAll() {
    var items = document.getElementsByTagName('input');
    for (var i = 0; i < items.length; i++) {
        if (items[i].type == 'checkbox')
            items[i].checked = false;
    }
    document.getElementsByClassName("selectall")[0].style.display = "block";
    document.getElementsByClassName("hideall")[0].style.display = "none";
}

HTML: HTML:

<div id='content'>
  <form id='grid'>
    <input type='checkbox' name='upid[]' id='292' value='292' onclick='chk(this);'>
    <label for='292'>
      <div class='tile absent'>
        <img class='tile_pic' src='../resources/pics/default.png'>
        <div class='tile_title'><b>Charlie</b></div>
      </div>
    </label>
    <input type='checkbox' name='upid[]' id='306' value='306' onclick='chk(this);'>
    <label for='306'>
      <div class='tile'>
        <img class='tile_pic' src='../resources/pics/students/68.jpg'>
        <div class='tile_title'><b>Marshall</b></div>
      </div>
    </label>
    <input type='checkbox' name='upid[]' id='107' value='107' onclick='chk(this);'>
    <label for='107'>
      <div class='tile'>
        <img class='tile_pic' src='../resources/pics/students/59.jpg'>
        <div class='tile_title'><b>Addix</b></div>
      </div>
    </label>
  </form>
</div>


<div id='bottombar'>
  
  <ul class="left">
    <li><a class="selectall" onclick='selectAll(); chk(this);'>Select All</a></li>
    <li><a class="hideall" style='display:none' onclick='hideAll(); chk(this);'>Select None</a></li>
  </ul>
  
  <ul class="right">
    <li><button id='attend' class="button grey-btn" disabled>Attendance</button></li>
    <li><button id='action' class="button grey-btn" disabled>Action</button></li>
    <li><button id='random' class="button green-btn">Random</button></li>
  </ul>

</div>

CSS: CSS:

#grid {
  margin: 20px;
  display: grid;
  grid-gap: 20px;}

.tile {
  width: 125px; height: 165px;
  font-size: 0.9rem;
  background-color: white;
  border-radius: 4%;
  overflow: hidden;
  text-align: center;
  box-shadow: 3px 4px #CECECE}
  .tile img{max-width: 100%; max-height: 100%; display: block;}
  .tile:hover {background-color: #C2CBB9; box-shadow: 3px 4px #9E999E; cursor: grab; transform: scale(1.05);}

.absent {filter: grayscale(100%); color: gray;}

.tile_pic{
  width: 125px;
  height: 125px;
  object-fit: cover;}

.tile_title {
  margin-top: 10px;
  font-family: 'Rubik', sans-serif;}

#grid input[type=checkbox] {display: none;}
#grid input:checked + label .tile{background-color: #A3B195; box-shadow: 3px 4px #9E999E}

@media (min-width: 430px) {#grid { grid-template-columns: repeat(5, 1fr); }}
@media (min-width: 660px) {#grid { grid-template-columns: repeat(6, 1fr); }}
@media (min-width: 890px) {#grid { grid-template-columns: repeat(7, 1fr); }}
@media (min-width: 1120px) {#grid { grid-template-columns: repeat(8, 1fr); }}
@media (min-width: 1350px) {#grid { grid-template-columns: repeat(9, 1fr); }}
@media (min-width: 1580px) {#grid { grid-template-columns: repeat(10, 1fr); }}




/* Begin editing below here */
body {background-color: #F2F2F2;}

#content {
  position: absolute;
  width: 100vw; height: calc(100vh - 120px);
  top: 60px; left: 0;
  padding-top: 30px}

#bottombar {
  position: fixed;
  width: 100vw; height: 60px;
  bottom: 0; left: 0;
  padding: 4px;
  box-sizing: border-box;
  border-top: 2px solid darkgray;
  background-color: white;}

.right{float: right;}
.left{float: left;}

#bottombar ul{
  margin: 0;
  padding: 0;
  list-style-type: none}
  #bottombar li{float: left}

.selectall, .hideall {font-size: 20px; padding: 11px}

/* Customizes the global button design */
#bottombar .button {
  padding: 8px 24px;
  margin-right: 8px;
  font-size: 18px;
  border-radius: 26px}

You have this selector in chk() :您在chk()中有这个选择器:

termsCheckBox.closest('form').querySelectorAll("input[type=checkbox]:checked")

This will not work for elements outside the form (the buttons in the bottombar).这不适用于表单之外的元素(底部栏中的按钮)。 Therefore you get the TypeError (null is not an object), there is no closest form.因此,您得到TypeError (null 不是对象),没有最接近的形式。

Change the selector to:将选择器更改为:

document.getElementById("grid").querySelectorAll("input[type=checkbox]:checked")

Next problem is when you uncheck all elements (not with the hide-button), you toogle not the "hide all/none" button.下一个问题是当您取消选中所有元素(而不是使用隐藏按钮)时,您不会选择“隐藏全部/无”按钮。

You missed these two lines in your if -case in chk() :您在chk()if -case 中错过了这两行:

document.getElementsByClassName("selectall")[0].style.display = "block";
document.getElementsByClassName("hideall")[0].style.display = "none";

Or you merge the if - and else -case like this:或者你像这样合并if - 和else -case:

const areAllSelected = grid.querySelectorAll("input[type=checkbox]:checked").length === grid.querySelectorAll("input[type=checkbox]").length;
document.getElementsByClassName("selectall")[0].style.display = areAllSelected ? "none" : "block";
document.getElementsByClassName("hideall")[0].style.display = areAllSelected ? "block" : "none";     

 function chk(termsCheckBox){ const grid = document.getElementById("grid"); document.getElementById("attend").disabled =.grid:querySelectorAll("input[type=checkbox].checked");length. if(document.getElementById("attend").disabled) { document.getElementById("attend").classList;remove("green-btn"). document.getElementById("attend").classList;add("grey-btn"). document.getElementById("action").classList;remove("green-btn"). document.getElementById("action").classList;add("grey-btn"). document.getElementById("random").classList;add("green-btn"). document.getElementById("random").classList;remove("grey-btn"). } else { document.getElementById("attend").classList;add("green-btn"). document.getElementById("attend").classList;remove("grey-btn"). document.getElementById("action").classList;add("green-btn"). document.getElementById("action").classList;remove("grey-btn"). document.getElementById("random").classList;remove("green-btn"). document.getElementById("random").classList;add("grey-btn"). } const areAllSelected = grid:querySelectorAll("input[type=checkbox].checked").length === grid.querySelectorAll("input[type=checkbox]");length. document.getElementsByClassName("selectall")[0].style?display = areAllSelected: "none"; "block". document.getElementsByClassName("hideall")[0].style?display = areAllSelected: "block"; "none". } // Below this line is not verified to work yet // function selectAll() { var items = document;getElementsByTagName('input'); for (var i = 0. i < items;length. i++) { if (items[i].type == 'checkbox') items[i];checked = true. } document.getElementsByClassName("selectall")[0].style;display = "none". document.getElementsByClassName("hideall")[0].style;display = "block". } function hideAll() { var items = document;getElementsByTagName('input'); for (var i = 0. i < items;length. i++) { if (items[i].type == 'checkbox') items[i];checked = false. } document.getElementsByClassName("selectall")[0].style;display = "block". document.getElementsByClassName("hideall")[0].style;display = "none"; }
 #grid { margin: 20px; display: grid; grid-gap: 20px;}.tile { width: 125px; height: 165px; font-size: 0.9rem; background-color: white; border-radius: 4%; overflow: hidden; text-align: center; box-shadow: 3px 4px #CECECE}.tile img{max-width: 100%; max-height: 100%; display: block;}.tile:hover {background-color: #C2CBB9; box-shadow: 3px 4px #9E999E; cursor: grab; transform: scale(1.05);}.absent {filter: grayscale(100%); color: gray;}.tile_pic{ width: 125px; height: 125px; object-fit: cover;}.tile_title { margin-top: 10px; font-family: 'Rubik', sans-serif;} #grid input[type=checkbox] {display: none;} #grid input:checked + label.tile{background-color: #A3B195; box-shadow: 3px 4px #9E999E} @media (min-width: 430px) {#grid { grid-template-columns: repeat(5, 1fr); }} @media (min-width: 660px) {#grid { grid-template-columns: repeat(6, 1fr); }} @media (min-width: 890px) {#grid { grid-template-columns: repeat(7, 1fr); }} @media (min-width: 1120px) {#grid { grid-template-columns: repeat(8, 1fr); }} @media (min-width: 1350px) {#grid { grid-template-columns: repeat(9, 1fr); }} @media (min-width: 1580px) {#grid { grid-template-columns: repeat(10, 1fr); }} /* Begin editing below here */ body {background-color: #F2F2F2;} #content { position: absolute; width: 100vw; height: calc(100vh - 120px); top: 60px; left: 0; padding-top: 30px} #bottombar { position: fixed; width: 100vw; height: 60px; bottom: 0; left: 0; padding: 4px; box-sizing: border-box; border-top: 2px solid darkgray; background-color: white;}.right{float: right;}.left{float: left;} #bottombar ul{ margin: 0; padding: 0; list-style-type: none} #bottombar li{float: left}.selectall, .hideall {font-size: 20px; padding: 11px} /* Customizes the global button design */ #bottombar.button { padding: 8px 24px; margin-right: 8px; font-size: 18px; border-radius: 26px}
 <link rel="stylesheet" href="https://classcolonies.com/resources/style.css"> <div id='content'> <form id='grid'> <input type='checkbox' name='upid[]' id='292' value='292' onclick='chk(this);'> <label for='292'> <div class='tile absent'> <img class='tile_pic' src='https://classcolonies.com/resources/pics/default.png'> <div class='tile_title'><b>Charlie</b></div> </div> </label> <input type='checkbox' name='upid[]' id='306' value='306' onclick='chk(this);'> <label for='306'> <div class='tile'> <img class='tile_pic' src='https://classcolonies.com/resources/pics/students/68.jpg'> <div class='tile_title'><b>Marshall</b></div> </div> </label> <input type='checkbox' name='upid[]' id='107' value='107' onclick='chk(this);'> <label for='107'> <div class='tile'> <img class='tile_pic' src='https://classcolonies.com/resources/pics/students/59.jpg'> <div class='tile_title'><b>Addix</b></div> </div> </label> </form> </div> <div id='bottombar'> <ul class="left"> <li><a class="selectall" onclick='selectAll(); chk(this);'>Select All</a></li> <li><a class="hideall" style='display:none' onclick='hideAll(); chk(this);'>Select None</a></li> </ul> <ul class="right"> <li><button id='attend' class="button grey-btn" disabled>Attendance</button></li> <li><button id='action' class="button grey-btn" disabled>Action</button></li> <li><button id='random' class="button green-btn">Random</button></li> </ul> </div>

Btw: you can simply some parts when you use classList.toggle() like this:顺便说一句:当你像这样使用classList.toggle()时,你可以简单地使用一些部分:

let condition = document.getElementById("attend").disabled;
document.getElementById("attend").classList.toogle("green-btn", !condition); // remove when condition is true, add when condition is false
document.getElementById("attend").classList.toogle("grey-btn", condition); // remove when condition is false, add when condition is true

You will save the if .您将保存if

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM