CountUp Function failing to increment from 0 to inputted time - javascript

The details and code of this issue are as follows:
Problem:
The countUp function runs with no errors, but the UI displays the number inputted, and nothing before it.
Current Approach:
const countUp = () => {
let inputTime = document.getElementById("input").value; // 5
console.log(inputTime);
if (inputTime != 0) { // 5 != 0
document.getElementById("countupClock").innerHTML = 0;
let run = run => { // 5 > 0
let clock = document.getElementById("countupClock");
clock.value = clock.value < inputTime ? clock.value++ : inputTime;
clock.innerHTML = clock.value;
}
setInterval(run(), 3000);
} else {
clearInterval(run);
};
}
This is what I have so far for the actual CountUp function.
The Click Event is handled here:
// Begin Countup:
let btn = document.getElementById("enterTime");
btn.addEventListener("click", () => {
console.log("New Time Entered");
countUp();
});
Then this is the HTML:
<html>
<body>
<div class="controls">
<p id="countup">Countup</p>
</div>
<div class="center-controls">
<input type="number" id="input" placeholder="Enter a number">
</input>
</div>
<div class="right-controls">
<button id="enterTime">START</button>
</div>
</div>
</main>
<div class="clocksContainer">
<!-- Displays Time counting down -->
<span id="countupClock"></span>
<!-- A Field that allows you to enter a time to countup from -->
</div>
<script src="script.js"></script>
</body>
</html>
Expected Output:
The Number on the UI should increment from 0, to the users inputted number. In this case, 5.

The clock variable is a span element, it doesn't have value property. Simply doing clock.innerHTML++ will increment the displayed counter value. Also you should be saving the setInterval value and using it inside clearInterval.
const countUp = () => {
let interval;
let inputTime = document.getElementById('input').value; // 5
console.log(inputTime);
if (inputTime != 0) {
document.getElementById('countupClock').innerHTML = 0;
let run = () => {
let clock = document.getElementById('countupClock');
if (clock.innerHTML < inputTime) {
clock.innerHTML++;
console.log('Counter value:', clock.innerHTML);
} else {
clearInterval(interval);
console.log('Cleared interval');
}
};
interval = setInterval(run, 1000);
}
};

Related

How to correct my wpm formula in JavaScript?

I am a learning student, Currently I am working on a typing website. I am using codingartist code as base. I have done some modification in this code. At the time variable I am taking value from user with the help of select option menu, so this is my time variable :
let time = parseInt(document.getElementById("time-select").value);
This is my html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Typing Test</title>
<!-- Google Fonts -->
<link
href="https://fonts.googleapis.com/css2?family=Poppins:wght#400;600&display=swap"
rel="stylesheet"
/>
<!-- Stylesheet -->
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<div class="select">
<label for="time-select">Select time:</label>
<select id="time-select">
<option value="60">1 minute</option>
<option value="90" selected>1.5 minutes</option>
<option value="120">2 minutes</option>
<option value="300">5 minutes</option>
<option value="480">8 minutes</option>
<option value="600" >10 minutes</option>
</select>
</div>
<div class="stats">
<p>Time: <span id="timer">0s</span></p>
<p>Mistakes: <span id="mistakes">0</span></p>
</div>
<div
id="quote"
onmousedown="return false"
onselectstart="return false"
></div>
<textarea
rows="3"
id="quote-input"
placeholder="Type here when the test starts.."
></textarea>
<button id="start-test" onclick="startTest()">Start Test</button>
<button id="stop-test" onclick="displayResult()">Stop Test</button>
<div class="result">
<h3>Result</h3>
<div class="wrapper">
<p>Accuracy: <span id="accuracy"></span></p>
<p>Speed: <span id="wpm"></span></p>
</div>
</div>
</div>
<!-- Script -->
<script src="script.js"></script>
</body>
</html>
This is my index.js
//Random Quotes Api URL
const quoteApiUrl = "https://api.quotable.io/random?minLength=80&maxLength=100";
const quoteSection = document.getElementById("quote");
const userInput = document.getElementById("quote-input");
let quote = "";
let time = parseInt(document.getElementById("time-select").value);
let timer = "";
let mistakes = 0;
function updateTime() {
// Get the new time value from the dropdown menu
let time = parseInt(document.getElementById("time-select").value);
// Update the timer display
document.getElementById("timer").innerText = time + "s";
}
// Add an event listener to the dropdown menu to call the updateTime function when the value changes
document.getElementById("time-select").addEventListener("change", updateTime);
//Display random quotes
const renderNewQuote = async () => {
//Fetch contents from url
const response = await fetch(quoteApiUrl);
//Store response
let data = await response.json();
//Access quote
quote = data.content;
//Array of characters in the quote
let arr = quote.split("").map((value) => {
//wrap the characters in a span tag
return "<span class='quote-chars'>" + value + "</span>";
});
//join array for displaying
quoteSection.innerHTML += arr.join("");
};
//Logic for comparing input words with quote
userInput.addEventListener("input", () => {
let quoteChars = document.querySelectorAll(".quote-chars");
//Create an arrat from received span tags
quoteChars = Array.from(quoteChars);
//array of user input characters
let userInputChars = userInput.value.split("");
//loop through each character in quote
quoteChars.forEach((char, index) => {
//Check if char(quote character) = userInputChars[index](input character)
if (char.innerText == userInputChars[index]) {
char.classList.add("success");
}
//If user hasn't entered anything or backspaced
else if (userInputChars[index] == null) {
//Remove class if any
if (char.classList.contains("success")) {
char.classList.remove("success");
} else {
char.classList.remove("fail");
}
}
//If user enter wrong character
else {
//Checks if we alreasy have added fail class
if (!char.classList.contains("fail")) {
//increment and display mistakes
mistakes += 1;
char.classList.add("fail");
}
document.getElementById("mistakes").innerText = mistakes;
}
//Returns true if all the characters are entered correctly
let check = quoteChars.every((element) => {
return element.classList.contains("success");
});
//End test if all characters are correct
if (check) {
displayResult();
}
});
});
//Update Timer on screen
function updateTimer() {
if (time == 0) {
//End test if timer reaches 0
displayResult();
} else {
document.getElementById("timer").innerText = --time + "s";
}
}
//Sets timer
const timeReduce = () => {
time = parseInt(time);
timer = setInterval(updateTimer, 1000);
};
//End Test
const displayResult = () => {
//display result div
document.querySelector(".result").style.display = "block";
clearInterval(timer);
document.getElementById("stop-test").style.display = "none";
userInput.disabled = true;
let timeTaken = 1;
if (time != 0) {
timeTaken = (60 - time) / 60;
}
document.getElementById("wpm").innerText =
(userInput.value.length / 5 / timeTaken).toFixed(2) + " wpm";
document.getElementById("accuracy").innerText =
Math.round(
((userInput.value.length - mistakes) / userInput.value.length) * 100
) + " %";
};
//Start Test
const startTest = () => {
mistakes = 0;
timer = "";
userInput.disabled = false;
timeReduce();
document.getElementById("start-test").style.display = "none";
document.getElementById("stop-test").style.display = "block";
};
window.onload = () => {
userInput.value = "";
document.getElementById("start-test").style.display = "block";
document.getElementById("stop-test").style.display = "none";
userInput.disabled = true;
renderNewQuote();
};
I am trying to create a typing test that measures the words per minute (WPM) of the user's input. However, the WPM calculation is not giving the correct results. When I test the code, the WPM value is always much higher or as same as word typed (even if i take 2min. for typing) than expected.
let timeTaken = 1;
if (time != 0) {
timeTaken = (60 - time) / 60;
}
document.getElementById("wpm").innerText =
(userInput.value.length / 5 / timeTaken).toFixed(2) + " wpm";
I know given code is wrong with 60 default value. so i tried this:
let remainTime = time - parseInt(timer);
let timeTaken = time - remainTime;
but it also gives doesn't give correct wpm value.
Try this I am sure that it will work as per my research:
let timerLengthInput = document.getElementById("time-select");
const timerLength = timerLengthInput.value;
let time = timerLength;
and write the in your displayResult-
let timeTaken = 1;
if (time !== 0) {
timeTaken = (timerLength - time) / 60;
}
document.getElementById("wpm").innerText =
(userInput.value.length / 5 / timeTaken).toFixed(2) + " wpm";
timeReduce function-
const timeReduce = () => {
timer = setInterval(updateTimer, 1000);
};

My JS timer clock is not stopping when clicked twice on start button [duplicate]

This question already has an answer here:
JavaScript countdown timer with on key press to reset the timer
(1 answer)
Closed 11 months ago.
I have a simple HTML stopwatch logic where I can start and stop the clock with the button click. By clicking on the start button, one can start the timer (shows current time) and update every second. One can stop it by clicking stop button. But if one clicks on start button twice, there is nothing I can do to stop the timer. Below is my code:
var hour = document.getElementById("hoursOut");
var minute = document.getElementById("minsOut");
var second = document.getElementById("secsOut");
var btnStart = document.getElementById("btnStart");
var btnStop = document.getElementById("btnStop");
var waitTimer;
function displayTime() {
var currentTime = new Date();
var currentHour = currentTime.getHours();
var currentMinute = currentTime.getMinutes();
var currentSeconds = currentTime.getSeconds();
hour.innerHTML = twoDigit(currentHour) + ":";
minute.innerHTML = twoDigit(currentMinute) + ":";
second.innerHTML = twoDigit(currentSeconds);
}
function twoDigit(digit) {
if (digit < 10) {
digit = "0" + digit;
}
return digit;
}
function startClock() {
waitTimer = setInterval(displayTime, 1000);
}
function stopClock() {
clearInterval(waitTimer);
}
btnStart.onclick = startClock;
btnStop.onclick = stopClock;
<h1>JavaScript Clock</h1>
<div id="calendarBox">
<!-- OUTPUT TIME VALUES -->
<p class="timeDisplay">
<span id="hoursOut">00:</span>
<span id="minsOut">00:</span>
<span id="secsOut">00</span>
</p>
<!-- BUTTON SET -->
<input id="btnStart" type="button" value="START" />
<input id="btnStop" type="button" value="STOP" />
</div>
I have checked some answers in stackoverflow but most solutions uses a for-loop from 0 to 1000 until it finds the interval id and stop all of them using loop. I am confident there should be an elegant solution than that.
// some stackoverflow suggested answer
for (var i = 1; i < 99999; i++)
window.clearInterval(i);
A possible solution is to prevent the problem before it happens. You can place a check on the running timer (Is there a way to check if a var is using setInterval()?).
In this case you could just have a global timer variable var timer = false the with add a check to the start function. Then the stop function will set the timer variable back to false.
function startClock() {
if(!timer){
timer = true
waitTimer = setInterval(displayTime, 1000);
}
else return
}
function stopClock() {
clearInterval(waitTimer);
timer = false
}
when you double click you start a new setInterval(). So you now have two set intervals running. Only problem is you can't access the first one cause you named the second one the same name. Check if waitTimer exists and if it does stop it. see code:
UPDATE: actually you don't even need an if statement. just call stopClock() before you set waitTimer -- code snippet adjusted
var hour = document.getElementById("hoursOut");
var minute = document.getElementById("minsOut");
var second = document.getElementById("secsOut");
var btnStart = document.getElementById("btnStart");
var btnStop = document.getElementById("btnStop");
var waitTimer;
function displayTime() {
var currentTime = new Date();
var currentHour = currentTime.getHours();
var currentMinute = currentTime.getMinutes();
var currentSeconds = currentTime.getSeconds();
hour.innerHTML = twoDigit(currentHour) + ":";
minute.innerHTML = twoDigit(currentMinute) + ":";
second.innerHTML = twoDigit(currentSeconds);
}
function twoDigit(digit) {
if (digit < 10) {
digit = "0" + digit;
}
return digit;
}
function startClock() {
stopClock();
waitTimer = setInterval(displayTime, 1000);
}
function stopClock() {
clearInterval(waitTimer);
}
btnStart.onclick = startClock;
btnStop.onclick = stopClock;
<h1>JavaScript Clock</h1>
<div id="calendarBox">
<!-- OUTPUT TIME VALUES -->
<p class="timeDisplay">
<span id="hoursOut">00:</span>
<span id="minsOut">00:</span>
<span id="secsOut">00</span>
</p>
<!-- BUTTON SET -->
<input id="btnStart" type="button" value="START" />
<input id="btnStop" type="button" value="STOP" />
</div>

Struggling to count down my text input with the value it is set at

trying to build a little countdown gym program. I'm trying to give the user the ability to input a value from the text input and when the click start it begins to count down from that number. I'm getting my value I set logging to the console but it isn't outputting back into the innerHTML??
thoughts?
let startTimer;
// buttons
const start = document.getElementById('start');
const pause = document.getElementById('pause');
const reset = document.getElementById('reset');
start.addEventListener('click', initTimer);
function initTimer(){
clearInterval(countDown)
setInterval(countDown, 1000);
}
function countDown(){
const work = document.getElementById('work');
var workVal = work.value;
work.innerHTML = workVal
console.log(workVal)
startTimer = workVal
work.innerHTML = `${startTimer}`
startTimer--
}
<div class="timer">
<div class="numb">
<h1 class="timeNum"><input type='text' min="00" id="rounds" value="00">:<input type='text' min="00" id="work" value="00">:<input type='text' min="00" id="rest" value="00">:<input type='text' min="00" id="breaks" value="00"></h1>
</div>
you need to use .value instead of .innerHTML.
then you need to move the counter outside, so you can pause/resume it dynamically.
the same way you should track rounds, and then start rest interval
let startTimer;
// buttons
const start = document.getElementById('start');
const pause = document.getElementById('pause');
const resume = document.getElementById('resume');
const reset = document.getElementById('reset');
start.addEventListener('click', initTimer);
pause.addEventListener('click', pauseTimer);
resume.addEventListener('click', resumeTimer);
reset.addEventListener('click', resetTimer);
let countDownInterval, restInterval, breakInterval;
const work = document.getElementById('work');
const rounds = document.getElementById('rounds');
const rest = document.getElementById('rest');
const breaks = document.getElementById('breaks');
const status = document.getElementById('done');
function initTimer() {
clearInterval(countDownInterval)
countDownInterval = setInterval(countDown, 1000);
status.innerText = '';
}
function pauseTimer() {
clearInterval(countDownInterval);
}
function resumeTimer() {
countDownInterval = setInterval(countDown, 1000);
}
function resetTimer() {
clearInterval(countDownInterval);
work.value = '00';
status.innerText = '';
}
function countDown() {
var workVal = work.value;
startTimer = workVal;
startTimer--;
console.log(workVal)
if (startTimer < 1) {
// check rounds, start breaks etc.
work.value = '00';
clearInterval(countDownInterval);
status.innerText = 'done';
} else {
work.value = startTimer;
}
}
<button id="start">start</button>
<button id="pause">pause</button>
<button id="resume">resume</button>
<button id="reset">reset</button>
<div class="timer">
<div class="numb">
<h1 class="timeNum">
<input type='text' min="00" id="rounds" value="00">:
<input type='text' min="00" id="work" value="00">:
<input type='text' min="00" id="rest" value="00">:
<input type='text' min="00" id="breaks" value="00"></h1>
</div>
</div>
<h1 id="done"></h1>

Create Reset button for a counter

I have this counter. It is a counter that uses Javascript Closure. Can you help me with a reset button?
If you can, to this type of "counter" code, not to another...
HTML CODE
<button type="button" onclick="geo()">Count!</button>
<p id="count">0</p>
JAVASCRIPT CODE
<script>
var count= (function () {
var nr = 0;
return function () {nr+= 1; return nr;}
})();
function geo(){
document.getElementById("count").innerHTML = count();
}
</script>
I'm not even sure what you have right now is working.
const addBtn = document.querySelector('#add');
const resetBtn = document.querySelector('#reset');
const pCount = document.querySelector('#count')
let start = 0;
function add(){
start++
pCount.innerHTML = start
}
function reset(){
start = 0;
pCount.innerHTML = start
}
addBtn.addEventListener('click', add)
resetBtn.addEventListener('click', reset)
<button id="add"> Add </button>
<button id="reset" > Reset </button>
<p id="count"></p>
I don't know much about the closure (seems very interesting...) but moving nr variable outside of your function and then call a reset on nr will reset the counter.
var count = (function() {
var nr = 0;
return function(reset = false) {
nr = reset ? 0 : nr + 1
return nr;
}
})();
function geo() {
document.getElementById("count").innerHTML = count();
}
function reset() {
document.getElementById("count").innerHTML = count(true);
}
<button type="button" onclick="geo()">Count!</button>
<button type="button" onclick="reset()">Reset!</button>
<p id="count">0</p>

Can't figure out Javascript Countdown

I need help making a Countdown timer!
The user types a value into a text field, the timer starts when a button is clicked.
The timer text decreases by one every second until it reaches zero.
I have code for the first step, but can't seem to get the second step to work. I know it needs to include a setTimeout and loop.
Heres the code so far :
HTML-
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div id="form">
<h2> COUNTDOWN</h2>
Seconds: <input type="text" name="seconds" id="seconds" /> <input type="button" value="Start!" id="start" /> <input type="button" value="Pause" id="pause" />
</div>
<div id="info">
</div>
<div id="countdown">
</div>
<script src="script.js"></script>
</body>
</html>
JAVASCRIPT-
window.onload = function(){
var startButton = document.getElementById("start");
var form = document.getElementById("seconds");
var pause = document.getElementById("pause");
var secDiv = document.getElementById("countdown");
var editSec = document.createElement("h1");
startButton.onclick = function (){
editSec.innerHTML = form.value;
secDiv.appendChild(editSec);
};
};
Here it goes:
var globalTime = form.value; //receive the timer from the form
var secDiv = document.getElementById("countdown");
function decreaseValue() {
globalTime = globalTime - 1;
secDiv.innerHTML = globalTime;
}
startButton.onclick = function (){
setTimeout(decreasValue(),1000);
};
//clear out the timers once completed
You need to use setInterval, not setTimeout. Add this code to the onclick function:
editSec.id = "editSec";
window.cdint = setInterval(function(){
var origVal = parseInt(document.getElementById("editSec").innerHTML);
document.getElementById("editSec").innerHTML = origVal - 1;
if(origVal - 1 <= 0){
window.cdint = clearInterval(window.cdint);
}
}, 1000);
Use setInterval
var time = 100;
var countdown = function(){
secdiv.innerHTML = time;
time--;
}
setInterval(countdown,1000);
You can use setTimeout if you want :
startButton.onclick = function () {
var value = parseInt(form.value);
editSec.innerHTML = value;
secDiv.appendChild(editSec);
setTimeout(function () {
editSec.innerHTML = --value < 10
? '<span style="color:red">' + value + '</span>'
: value;
if (value) {
setTimeout(arguments.callee, 1000);
}
}, 1000);
};

Categories

Resources