【问题标题】:Ticking a checkbox, to select all rows, and display number of rows, across multiple tables勾选复选框,以选择所有行,并显示跨多个表的行数
【发布时间】:2022-09-22 21:41:06
【问题描述】:

我在一个页面上有多个表格。 每个表的标题中都有一个“全选”复选框。 在正文中,每行还有一个复选框。

当用户检查每个男孩行时,有一类 active 突出显示标记的行,并且计数器增加/减少。

我正在努力检查所有功能。 当用户在标题中选择全部检查时,它应该选择该表中的所有行。我只能让它检查所有表中的所有行。计数器还计算所有表中的所有行,而不仅仅是那些表。

我哪里错了?

jsfiddle 代码:https://jsfiddle.net/rdqu56x4/3/

// https://gomakethings.com/a-vanilla-js-foreach-helper-method/
var forEach = function forEach(arr, callback) {
  Array.prototype.forEach.call(arr, callback);
};

var tableInputs = document.querySelectorAll(\'.table tbody td .form-check-input\');
var tableSelectAll = document.querySelectorAll(\'.table thead th .form-check-input\');
var count = document.querySelector(\'.output span\')

forEach(tableInputs, function (element) {
    element.addEventListener(\'change\', function () {
      // active class to make row blue
      if (element.checked) {
        element.parentNode.parentNode.classList.add(\'active\');
      } else {
        element.parentNode.parentNode.classList.remove(\'active\');
      }
           
      // set count to -
            var numberSelected = 0;

            // count number of checked
            for (var i = 0; i < tableInputs.length; i++) {
                if (tableInputs[i].checked == true) {
                    numberSelected++;
                }
            }

            // display the count
            count.innerHTML = numberSelected;
    });
});

forEach(tableSelectAll, function (element) {
    element.addEventListener(\'change\', function () {

    if (element.checked == true) {
      forEach(tableInputs, function (input) {
        input.parentNode.parentNode.classList.add(\'active\');
                input.checked = true;
        
         // set count to -
            var numberSelected = 0;

            // count number of checked
            for (var i = 0; i < tableInputs.length; i++) {
                if (tableInputs[i].checked == true) {
                    numberSelected++;
                }
            }

            // display the count
            count.innerHTML = numberSelected;
      });
    } else {
          forEach(tableInputs, function (input) {
        input.parentNode.parentNode.classList.remove(\'active\');
                input.checked = false;
        count.innerHTML = 0;
      });
    }
  });
});
.form-check-input {
  border: solid 1px #000;
  position: relative;
}
tr.active {
  background-color: lightblue;
}

body { margin: 0; zoom: .88; }
p { margin: 0; }
<div class=\"container\">
  <div class=\"row\">
    <div class=\"col-12\">

      <p>Table 1</p>

      <table class=\"table table-sm table-borderless\">
        <thead>
          <tr>
            <th><input class=\"form-check-input\" type=\"checkbox\" value=\"\"></th>
            <th>Request date</th>
            <th>Name</th>
            <th>Organisation/Employer</th>
            <th>Selected Course(s)</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td><input class=\"form-check-input\" type=\"checkbox\" value=\"\"></td>
            <td>10/10/2014</td>
            <td><a href=\"#\">Clark Kent</a></td>
            <td><span>Daily Planet</span></td>
            <td><span>Flight</span></td>
          </tr>
          <tr>
            <td><input class=\"form-check-input\" type=\"checkbox\" value=\"\"></td>
            <td>10/10/2014</td>
            <td><a href=\"#\">Hal Jordan</a></td>
            <td><span>Green Lantern Corps</span></td>
            <td>Lighting</td>
          </tr>
          <tr>
            <td><input class=\"form-check-input\" type=\"checkbox\" value=\"\" checked></td>
            <td>10/10/2014</td>
            <td><a href=\"#\">Arthur Curry</a></td>
            <td><span>Atlantis Water</span></td>
            <td>Aquatics</td>
          </tr>
        </tbody>
      </table>

      <p>Table 2</p>

      <table class=\"table table-sm table-borderless \">
        <thead>
          <tr>
            <th><input class=\"form-check-input\" type=\"checkbox\" value=\"\"></th>
            <th>Request date</th>
            <th>Name</th>
            <th>Organisation/Employer</th>
            <th>Selected Course(s)</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td><input class=\"form-check-input\" type=\"checkbox\" value=\"\" checked></td>
            <td>10/10/2014</td>
            <td><a href=\"#\">Barry Allen</a></td>
            <td><span>Star Labs</span></td>
            <td><span>Speed</span></td>
          </tr>
          <tr>
            <td><input class=\"form-check-input\" type=\"checkbox\" value=\"\"></td>
            <td>10/10/2014</td>
            <td><a href=\"#\">Bruce Wayne</a></td>
            <td><span>Wayne Enterprises</span></td>
            <td>Combat</td>
          </tr>
        </tbody>
      </table>

    </div>
  </div>
</div>

<p class=\"output\">Total selected: <span>0</span></p>
  • 为什么要自定义forEachquerySelectorAll 的返回值是一个静态的NodeList,它具有forEach 方法。
  • 它是网站上需要的遗留 IE 东西
  • 您已通过将 URL 作为代码发布来绕过 SO 要求。请参阅How to Ask 并采取tour,然后进行改进。

标签: javascript dom event-handling selectors-api event-delegation


【解决方案1】:

无论采用哪种方法,都应始终将问题分解为针对 OP 要求的特定任务......

  • 初始化复选框更改处理。
  • 在任何复选框的状态更改时,请更新所有与复选框相关的状态。
  • 在初始化时和复选框状态更改时更新复选框计数器。

技术/工具是Event DelegationSelectors API

在任何复选框状态更改时,处理程序都会检查 event target 是否属于当前表的标题或正文。

基于此检查,对于第一种情况,需要选中/取消选中当前表的所有与正文相关的复选框,或者根据第二种情况,需要更新唯一与标题相关的复选框的状态。

更新复选框计数器是通过正确的选择器和queried node list's length value 来实现的。

function updateCheckboxCounter() {
  document
    .querySelector('.output > span')
    .textContent = document
      .querySelectorAll('table.table tbody [type="checkbox"]:checked')
      .length;
}

function updateCheckboxDependedStates({ target }) {
  const tableNode = target.closest('table.table');

  if (target.matches('thead [type="checkbox"]')) {

    tableNode
      .querySelectorAll('tbody [type="checkbox"]')
      .forEach(elmNode =>

        elmNode.checked = target.checked
      );

  } else if (target.matches('tbody [type="checkbox"]')) {

    tableNode
      .querySelector('thead [type="checkbox"]')
      .checked = Array
        .from(
          target
            .closest('tbody')
            .querySelectorAll('[type="checkbox"]')
        )
        .every(elmNode => elmNode.checked);
  }
  updateCheckboxCounter();
}

function init() {
  document
    .querySelectorAll('table.table')
    .forEach(elmNode =>

      elmNode.addEventListener('change', updateCheckboxDependedStates)
    );
  updateCheckboxCounter();
}
init();
.form-check-input {
  border: solid 1px #000;
  position: relative;
}
tr.active {
  background-color: lightblue;
}

body { margin: 0; zoom: .88; }
p { margin: 0; }
<div class="container">
  <div class="row">
    <div class="col-12">

      <p>Table 1</p>

      <table class="table table-sm table-borderless">
        <thead>
          <tr>
            <th><input class="form-check-input" type="checkbox" value=""></th>
            <th>Request date</th>
            <th>Name</th>
            <th>Organisation/Employer</th>
            <th>Selected Course(s)</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td><input class="form-check-input" type="checkbox" value=""></td>
            <td>10/10/2014</td>
            <td><a href="#">Clark Kent</a></td>
            <td><span>Daily Planet</span></td>
            <td><span>Flight</span></td>
          </tr>
          <tr>
            <td><input class="form-check-input" type="checkbox" value=""></td>
            <td>10/10/2014</td>
            <td><a href="#">Hal Jordan</a></td>
            <td><span>Green Lantern Corps</span></td>
            <td>Lighting</td>
          </tr>
          <tr>
            <td><input class="form-check-input" type="checkbox" value="" checked></td>
            <td>10/10/2014</td>
            <td><a href="#">Arthur Curry</a></td>
            <td><span>Atlantis Water</span></td>
            <td>Aquatics</td>
          </tr>
        </tbody>
      </table>

      <p>Table 2</p>

      <table class="table table-sm table-borderless ">
        <thead>
          <tr>
            <th><input class="form-check-input" type="checkbox" value=""></th>
            <th>Request date</th>
            <th>Name</th>
            <th>Organisation/Employer</th>
            <th>Selected Course(s)</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td><input class="form-check-input" type="checkbox" value="" checked></td>
            <td>10/10/2014</td>
            <td><a href="#">Barry Allen</a></td>
            <td><span>Star Labs</span></td>
            <td><span>Speed</span></td>
          </tr>
          <tr>
            <td><input class="form-check-input" type="checkbox" value=""></td>
            <td>10/10/2014</td>
            <td><a href="#">Bruce Wayne</a></td>
            <td><span>Wayne Enterprises</span></td>
            <td>Combat</td>
          </tr>
        </tbody>
      </table>

    </div>
  </div>
</div>

<p class="output">Total selected: <span>0</span></p>

【讨论】:

    猜你喜欢
    • 2017-10-17
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 2015-02-18
    • 2021-11-23
    • 2014-03-12
    相关资源
    最近更新 更多