Home > Back-end >  How to increment length based on the number of checkboxes in a table to find perecntage?
How to increment length based on the number of checkboxes in a table to find perecntage?

Time:01-04

Trying to make a task manager and implement a circular progress bar that correlates to the checkboxes. I got it to where I have a add row button and it seems to work fine but when I try to link it to the progress bar I usually get an error that the variable is not defined.

Here is my current HTML and JS.

//CHECKING IF THE CHECKBOXES HAVE BEEN CHECKED OR UNCHECKED AND THEN RETURNING THE NUMBER
//AS VALCHECKCOUNT
var valCheckCount = 0;

function update() {

  let checkboxCounter = document.querySelectorAll('input[name="dailyCheck"]:checked');
  valCheckCount = checkboxCounter.length;
  return valCheckCount;
};

let checkboxCounter = document.querySelectorAll('input[name="dailyCheck"]');
checkboxCounter.forEach(function(checkboxD) {
  checkboxD.addEventListener("change", function(e) {
    update();
  });
});

function addRowFunction() {
  var progressLength = document.querySelectorAll('input[name="dailyCheck"]');
  var parentTable = document.getElementById("table1");
  var myTd, myInputCheck, myInputText;
  var myTr = document.createElement('tr');
  myTr.setAttribute('class', 'unit-table');
  for (var j = 0; j < 1; j  ) {
    myTd = document.createElement('td');
    myInputText = document.createElement('input');
    myInputText.setAttribute('type', 'text');
    myTd.appendChild(myInputText);
    myTr.appendChild(myTd);
  }
  for (var i = 0; i < 31; i  ) {
    myTd = document.createElement('td');
    myInputCheck = document.createElement('input');
    myInputCheck.setAttribute('type', 'checkbox');
    myInputCheck.setAttribute('name', 'dailyCheck');
    myInputCheck.addEventListener('change', function(e) {
      update();
    });
    myTd.appendChild(myInputCheck);
    myTr.appendChild(myTd);
  }
  parentTable.appendChild(myTr);
  return progressLength.length;
}



//ALL OF THE CODE USED TO CREATE THE CIRCULAR PROGRESS BAR AND TAKES THE INPUT FROM
//VALCHECKCOUNT AND THE FUNCTION ABOVE.
let circularProgress = document.querySelector(".circular-progress"),
  progressValue = document.querySelector(".progress-value");


let progressStartValue = 0,
  progressEndValue = valCheckCount,
  speed = 20;
let progressLength = document.querySelectorAll('input[name="dailyCheck"]').length;

let progress = setInterval(() => {
  progressStartValue  ;
  let percentageAnswer = Math.round((valCheckCount / progressLength) * 100);

  progressValue.textContent = `${percentageAnswer}%`
  circularProgress.style.background = `conic-gradient(#7d2ae8 ${percentageAnswer * 3.6}deg, #ededed 0deg)`

  if (progressStartValue == percentageAnswer) {
    clearInterval(progress);
  }
}, speed);
<body>
  <h1>Task Manager</h1>
  <!--Table for Weekly Habits-->
  <h2>Weekly Habits</h2>

  <!--Circular Progress Tracker for Daily habits-->
  <div >
    <div >
      <span  onchange="valCheckCount(this)">0%</span>
    </div>
    <span >Daily Habits</span>
  </div>
  <div id="root">


  </div>
  <!--Creating table format for Dialy Tasks-->
  <div id="dailyTable">
    <table id="table1" >

      <!--first table header for title and days-->
      <tr >
        <td>
          <label for="firstRow">Daily Habits</label>
        </td>
        <td>
          <label for="firstRow">1</label>
        </td>
        <td>
          <label for="firstRow">2</label>
        </td>
        <td>
          <label for="firstRow">3</label>
        </td>
        <td>
          <label for="firstRow">4</label>
        </td>
        <td>
          <label for="firstRow">5</label>
        </td>
        <td>
          <label for="firstRow">6</label>
        </td>
        <td>
          <label for="firstRow">7</label>
        </td>
        <td>
          <label for="firstRow">8</label>
        </td>
        <td>
          <label for="firstRow">9</label>
        </td>
        <td>
          <label for="firstRow">10</label>
        </td>
        <td>
          <label for="firstRow">11</label>
        </td>
        <td>
          <label for="firstRow">12</label>
        </td>
        <td>
          <label for="firstRow">13</label>
        </td>
        <td>
          <label for="firstRow">14</label>
        </td>
        <td>
          <label for="firstRow">15</label>
        </td>
        <td>
          <label for="firstRow">16</label>
        </td>
        <td>
          <label for="firstRow">17</label>
        </td>
        <td>
          <label for="firstRow">18</label>
        </td>
        <td>
          <label for="firstRow">19</label>
        </td>
        <td>
          <label for="firstRow">20</label>
        </td>
        <td>
          <label for="firstRow">21</label>
        </td>
        <td>
          <label for="firstRow">22</label>
        </td>
        <td>
          <label for="firstRow">23</label>
        </td>
        <td>
          <label for="firstRow">24</label>
        </td>
        <td>
          <label for="firstRow">25</label>
        </td>
        <td>
          <label for="firstRow">26</label>
        </td>
        <td>
          <label for="firstRow">27</label>
        </td>
        <td>
          <label for="firstRow">28</label>
        </td>
        <td>
          <label for="firstRow">29</label>
        </td>
        <td>
          <label for="firstRow">30</label>
        </td>
        <td>
          <label for="firstRow">31</label>
        </td>
      </tr>

    </table>
    <br>

    <button type="button" id="addRowButton" onClick="addRowFunction()"> </button>

  </div>
</body>

CodePudding user response:

Move let progressLength = document.querySelectorAll('input[name="dailyCheck"]').length; inside the setInterval function. There is no input[name="dailyCheck"] on page load, so progressLength always is zero.

//CHECKING IF THE CHECKBOXES HAVE BEEN CHECKED OR UNCHECKED AND THEN RETURNING THE NUMBER
//AS VALCHECKCOUNT
var valCheckCount = 0;

function update() {

  let checkboxCounter = document.querySelectorAll('input[name="dailyCheck"]:checked');
  valCheckCount = checkboxCounter.length;
  return valCheckCount;
};

let checkboxCounter = document.querySelectorAll('input[name="dailyCheck"]');
checkboxCounter.forEach(function(checkboxD) {
  checkboxD.addEventListener("change", function(e) {
    update();
  });
});

function addRowFunction() {
  var progressLength = document.querySelectorAll('input[name="dailyCheck"]');
  var parentTable = document.getElementById("table1");
  var myTd, myInputCheck, myInputText;
  var myTr = document.createElement('tr');
  myTr.setAttribute('class', 'unit-table');
  for (var j = 0; j < 1; j  ) {
    myTd = document.createElement('td');
    myInputText = document.createElement('input');
    myInputText.setAttribute('type', 'text');
    myTd.appendChild(myInputText);
    myTr.appendChild(myTd);
  }
  for (var i = 0; i < 31; i  ) {
    myTd = document.createElement('td');
    myInputCheck = document.createElement('input');
    myInputCheck.setAttribute('type', 'checkbox');
    myInputCheck.setAttribute('name', 'dailyCheck');
    myInputCheck.addEventListener('change', function(e) {
      update();
    });
    myTd.appendChild(myInputCheck);
    myTr.appendChild(myTd);
  }
  parentTable.appendChild(myTr);
  return progressLength.length;
}



//ALL OF THE CODE USED TO CREATE THE CIRCULAR PROGRESS BAR AND TAKES THE INPUT FROM
//VALCHECKCOUNT AND THE FUNCTION ABOVE.
let circularProgress = document.querySelector(".circular-progress"),
  progressValue = document.querySelector(".progress-value");


let progressStartValue = 0,
  progressEndValue = valCheckCount,
  speed = 20;
//let progressLength = document.querySelectorAll('input[name="dailyCheck"]').length;

let progress = setInterval(() => {
  let progressLength = document.querySelectorAll('input[name="dailyCheck"]').length;
  
  progressStartValue  ;
  let percentageAnswer = Math.round((valCheckCount / progressLength) * 100);

  progressValue.textContent = `${percentageAnswer}%`
  circularProgress.style.background = `conic-gradient(#7d2ae8 ${percentageAnswer * 3.6}deg, #ededed 0deg)`

  if (progressStartValue == percentageAnswer) {
    clearInterval(progress);
  }
}, speed);
<body>
  <h1>Task Manager</h1>
  <!--Table for Weekly Habits-->
  <h2>Weekly Habits</h2>

  <!--Circular Progress Tracker for Daily habits-->
  <div >
    <div >
      <span  onchange="valCheckCount(this)">0%</span>
    </div>
    <span >Daily Habits</span>
  </div>
  <div id="root">


  </div>
  <!--Creating table format for Dialy Tasks-->
  <div id="dailyTable">
    <table id="table1" >

      <!--first table header for title and days-->
      <tr >
        <td>
          <label for="firstRow">Daily Habits</label>
        </td>
        <td>
          <label for="firstRow">1</label>
        </td>
        <td>
          <label for="firstRow">2</label>
        </td>
        <td>
          <label for="firstRow">3</label>
        </td>
        <td>
          <label for="firstRow">4</label>
        </td>
        <td>
          <label for="firstRow">5</label>
        </td>
        <td>
          <label for="firstRow">6</label>
        </td>
        <td>
          <label for="firstRow">7</label>
        </td>
        <td>
          <label for="firstRow">8</label>
        </td>
        <td>
          <label for="firstRow">9</label>
        </td>
        <td>
          <label for="firstRow">10</label>
        </td>
        <td>
          <label for="firstRow">11</label>
        </td>
        <td>
          <label for="firstRow">12</label>
        </td>
        <td>
          <label for="firstRow">13</label>
        </td>
        <td>
          <label for="firstRow">14</label>
        </td>
        <td>
          <label for="firstRow">15</label>
        </td>
        <td>
          <label for="firstRow">16</label>
        </td>
        <td>
          <label for="firstRow">17</label>
        </td>
        <td>
          <label for="firstRow">18</label>
        </td>
        <td>
          <label for="firstRow">19</label>
        </td>
        <td>
          <label for="firstRow">20</label>
        </td>
        <td>
          <label for="firstRow">21</label>
        </td>
        <td>
          <label for="firstRow">22</label>
        </td>
        <td>
          <label for="firstRow">23</label>
        </td>
        <td>
          <label for="firstRow">24</label>
        </td>
        <td>
          <label for="firstRow">25</label>
        </td>
        <td>
          <label for="firstRow">26</label>
        </td>
        <td>
          <label for="firstRow">27</label>
        </td>
        <td>
          <label for="firstRow">28</label>
        </td>
        <td>
          <label for="firstRow">29</label>
        </td>
        <td>
          <label for="firstRow">30</label>
        </td>
        <td>
          <label for="firstRow">31</label>
        </td>
      </tr>

    </table>
    <br>

    <button type="button" id="addRowButton" onClick="addRowFunction()"> </button>

  </div>
</body>

By the way, the code inside tha setInterval could be inside the update function. Running that code every 20ms when there is no change at all is useless.

  • Related