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 class="container">
<div class="circular-progress">
<span class="progress-value" onchange="valCheckCount(this)">0%</span>
</div>
<span class="text">Daily Habits</span>
</div>
<div id="root">
</div>
<!--Creating table format for Dialy Tasks-->
<div id="dailyTable">
<table id="table1" class="dailyT">
<!--first table header for title and days-->
<tr class="unit-table">
<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>
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 class="container">
<div class="circular-progress">
<span class="progress-value" onchange="valCheckCount(this)">0%</span>
</div>
<span class="text">Daily Habits</span>
</div>
<div id="root">
</div>
<!--Creating table format for Dialy Tasks-->
<div id="dailyTable">
<table id="table1" class="dailyT">
<!--first table header for title and days-->
<tr class="unit-table">
<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.