How do I count checked checkboxes in list.js that are not currently displayed?

253 views Asked by At

I have a table with checkboxes in list.js. I want to count all checkboxes that are checked, even those hidden due to the search function of the list. The method below works for only the checkboxes that are currently displayed after searching.

<!DOCTYPE html>
<html lang="en">
<head>
<title>Counting checked checkboxes</title>
</head>
<script src="//cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>

<body>
<div id='sample_rows'>
<div id='sample_count'></div>
<input class="search" placeholder="Search" />
<table>
    <tbody class="list">
    <tr>
        <td class='name'>checkbox1</td>
        <td class="checked">
            <input class="sample_checkbox" type="checkbox" name="checkbox1" id="checkbox1" onclick="update_count()">
        </td>
    </tr>
    <tr>
        <td class='name'>checkbox2</td>
        <td class="checked">
            <input class="sample_checkbox" type="checkbox" name="checkbox2" id="checkbox2" onclick="update_count()">
        </td>
    </tr>
    </tbody>
</table>
</div>

<script>
    var list_options = {
        valueNames: ['name', 'checked'],
        searchDelay: 500
    };
    var sample_list = new List('sample_rows', list_options);
    sample_list.on('updated', update_count);
    document.addEventListener("load", update_count());
    
    function update_count(){
        let total = sample_list.size();
        let checked_count = 0;
        let items = sample_list.items;
        for (let i = 0; i < total; i++){
            let item = items[i];
            let checkbox_id = items[i]._values['name'];
            let sample_checkbox = document.getElementById(checkbox_id);
            if(sample_checkbox != null){
                if (sample_checkbox.checked){
                    checked_count += 1;
                }
            }
            else {
                alert('Cannot find state of ' + checkbox_id);
            }
        }
        document.getElementById('sample_count').innerHTML = String(checked_count) + " selected";
    }
</script>

</body>
</html>

The state of checkboxes is preserved while searching, so the count should be available. This is illustrated by:

  1. Check both checkboxes. Count is 2.
  2. Search for "box2". Count is displayed as 1, with alert for the box that fails to get counted.
  3. Clear search box. Count is 2 again because state of undisplayed checkbox is preserved.

How can I count all of the checked checkboxes when a search has been applied?

2

There are 2 answers

0
ikiK On

I just wrote you a new logic for calculation: do your count based on click, no need use list if im not mistaken for some reason, and save result in variable. ...

let res = 0
document.querySelectorAll("input[type=checkbox]").forEach(input => {
  input.addEventListener("click", (e) => {
    e.target.checked ? res = res + 1 : res = res - 1
    document.getElementById('sample_count').innerHTML = res + " selected";
  }) 
})

...

remove

document.getElementById('sample_count').innerHTML

from your function. To be fair not sure whats going on there, looks a bit to much for simple calculation.

let res = 0
document.querySelectorAll("input[type=checkbox]").forEach(input => {
  input.addEventListener("click", (e) => {
    e.target.checked ? res = res + 1 : res = res - 1
    document.getElementById('sample_count').innerHTML = res + " selected";
  }) 
})
<!DOCTYPE html>
<html lang="en">

<head>
  <title>Counting checked checkboxes</title>
</head>
<script src="//cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>

<body>
  <div id='sample_rows'>
    <div id='sample_count'></div>
    <input class="search" placeholder="Search" />
    <table>
      <tbody class="list">
        <tr>
          <td class='name'>checkbox1</td>
          <td class="checked">
            <input class="sample_checkbox" type="checkbox" name="checkbox1" id="checkbox1" onclick="update_count()">
          </td>
        </tr>
        <tr>
          <td class='name'>checkbox2</td>
          <td class="checked">
            <input class="sample_checkbox" type="checkbox" name="checkbox2" id="checkbox2" onclick="update_count()">
          </td>
        </tr>
      </tbody>
    </table>
  </div>

  <script>
    var list_options = {
      valueNames: ['name', 'checked'],
      searchDelay: 500
    };
    var sample_list = new List('sample_rows', list_options);
    sample_list.on('updated', update_count);
    document.addEventListener("load", update_count());

    function update_count() {
      let total = sample_list.size();
      let checked_count = 0;
      let items = sample_list.items;
      for (let i = 0; i < total; i++) {
        let item = items[i];
        let checkbox_id = items[i]._values['name'];
        let sample_checkbox = document.getElementById(checkbox_id);
        if (sample_checkbox != null) {
          if (sample_checkbox.checked) {
            checked_count += 1;
          }
        } else {
          // alert('Cannot find state of ' + checkbox_id);
        }
      }
      //document.getElementById('sample_count').innerHTML = String(checked_count) + " selected";
    }
  </script>

</body>

</html>

0
Rohit Khandelwal On

This code will keep your checked count intact whether your checkboxes are hidden or not

<!DOCTYPE html>
<html lang="en">

<head>
  <title>Counting checked checkboxes</title>
</head>
<script src="//cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js"></script>

<body>
  <div id='sample_rows'>
    <div id='sample_count'></div>
    <input class="search" placeholder="Search" />
    <table>
      <tbody class="list">
        <tr>
          <td class='name'>checkbox1</td>
          <td class="checked">
            <input class="sample_checkbox" type="checkbox" name="checkbox1" id="checkbox1" onclick="update_count('checkbox1')">
          </td>
        </tr>
        <tr>
          <td class='name'>checkbox2</td>
          <td class="checked">
            <input class="sample_checkbox" type="checkbox" name="checkbox2" id="checkbox2" onclick="update_count('checkbox2')">
          </td>
        </tr>
      </tbody>
    </table>
  </div>

  <script>
    var checked_count = 0;
    var list_options = {
      valueNames: ['name', 'checked'],
      searchDelay: 500
    };
    var sample_list = new List('sample_rows', list_options);
    sample_list.on('updated', update_count);
    document.addEventListener("load", update_count_on_load());

    function update_count_on_load() {
      let total = sample_list.size();
      let checked_count = 0;
      let items = sample_list.items;
      for (let i = 0; i < total; i++) {
        let item = items[i];
        let checkbox_id = items[i]._values['name'];
        let sample_checkbox = document.getElementById(checkbox_id);
        if (sample_checkbox != null) {
          if (sample_checkbox.checked) {
            checked_count += 1;
          }
        } else {
          alert('Cannot find state of ' + checkbox_id);
        }
      }
      document.getElementById('sample_count').innerHTML = String(checked_count) + " selected";
    }

    function update_count(checkbox_id) {
      let sample_checkbox = document.getElementById(checkbox_id);
      if (sample_checkbox) {
        if (sample_checkbox.checked) {
          checked_count += 1;
        } else {
          checked_count -= 1;
        }
      }
      document.getElementById('sample_count').innerHTML = checked_count + " selected";
    }
  </script>

</body>

</html>