Wordpress Update Javascript Stopwatch - javascript

I have this javascript stopwatch that is working. The function is when user click start button to start and pause button to pause the stopwatch. The variable stopwatch is saved in localStorage and when user refresh the website and click start again the stopwatch continue from the last stopwatch time + 1; The first timer is working, but I will have an array of the same containers, fetching from a Database containing stopwatch time. The problem is with my loop. How can I add the timer for each individual timer container and continue from the time it was last saved + 1 and continue from there. I am providing an example maybe someone can help me.
HTML
<div class="c-add-task-main-container">
<h2 class="c-add-task-title">Time Tracker</h2>
<button class="start">Start</button>
<button class="pause">Pause</button>
<button class="clear">Clear</button>
<div class="output">00:34:21</div>
</div>
<div class="c-add-task-main-container">
<h2 class="c-add-task-title">Time Tracker</h2>
<button class="start">Start</button>
<button class="pause">Pause</button>
<button class="clear">Clear</button>
<div class="output">21:56:22</div>
</div>
<div class="c-add-task-main-container">
<h2 class="c-add-task-title">Time Tracker</h2>
<button class="start">Start</button>
<button class="pause">Pause</button>
<button class="clear">Clear</button>
<div class="output">32:47:35</div>
</div>
<div class="c-add-task-main-container">
<h2 class="c-add-task-title">Time Tracker</h2>
<button class="start">Start</button>
<button class="pause">Pause</button>
<button class="clear">Clear</button>
<div class="output">11:29:03</div>
</div>
<div class="c-add-task-main-container">
<h2 class="c-add-task-title">Time Tracker</h2>
<button class="start">Start</button>
<button class="pause">Pause</button>
<button class="clear">Clear</button>
<div class="output">04:01:14</div>
</div>
JS
let showTime = document.querySelector(".output");
let startTimeButton = document.querySelector(".start")
let pauseTimeButton = document.querySelector(".pause")
let seconds = 0;
let interval = null;
if (localStorage.getItem("stopwatchSeconds") != null) {
seconds = parseInt(localStorage.getItem("stopwatchSeconds"));
}
const timer = () => {
seconds++;
localStorage.setItem("stopwatchSeconds", seconds);
// Get hours
let hours = Math.floor(seconds / 3600);
// Get minutes
let minutes = Math.floor((seconds - hours * 3600) / 60);
// Get seconds
let secs = Math.floor(seconds % 60);
if (hours < 10) {
hours = `0${hours}`;
}
if (minutes < 10) {
minutes = `0${minutes}`;
}
if (secs < 10) {
secs = `0${secs}`;
}
showTime.innerHTML = `${hours}:${minutes}:${secs}`;
};
startTimeButton.addEventListener("click", () => {
pauseTimeButton.style.display = "block";
startTimeButton.style.display = "none";
console.log("START TIME CLICKED");
if (interval) {
return;
}
interval = setInterval(timer, 1000);
});
// Pause function
pauseTimeButton.addEventListener("click", () => {
pauseTimeButton.style.display = "none";
startTimeButton.style.display = "block";
console.log("PAUSE TIME CLICKED");
clearInterval(interval);
interval = null;
});

You can try this snippet
Html
<div class="c-add-task-main-container" data-watch_no="01">
<h2 class="c-add-task-title">Time Tracker 01</h2>
<button class="start">Start</button>
<button class="pause">Pause</button>
<button class="clear">Clear</button>
<div class="output"></div>
</div>
<div class="c-add-task-main-container" data-watch_no="02">
<h2 class="c-add-task-title">Time Tracker 02</h2>
<button class="start">Start</button>
<button class="pause">Pause</button>
<button class="clear">Clear</button>
<div class="output"></div>
</div>
Vanilla JS
let stop_watch_containers = document.querySelectorAll(".c-add-task-main-container");
stop_watch_containers.forEach((container) => {
let start_button = container.querySelector(".start");
let pause_button = container.querySelector(".pause");
let clear_button = container.querySelector(".clear");
let output = container.querySelector(".output");
let localStorageKey = "watch" + container.dataset.watch_no;
let seconds = localStorage.getItem(localStorageKey);
if (isNaN(seconds)) {
seconds = 0;
}
// set old time on page load
output.innerHTML = timer();
let interval;
// start watch
start_button.addEventListener("click", function () {
clearInterval(interval);
interval = setInterval(function () {
output.innerHTML = timer();
seconds++;
}, 1000);
});
// pause watch
pause_button.addEventListener("click", function () {
clearInterval(interval);
localStorage.setItem(localStorageKey, seconds);
});
// clear watch
clear_button.addEventListener("click", function () {
clearInterval(interval);
seconds = 0;
output.innerHTML = timer();
localStorage.setItem(localStorageKey, 0);
});
function timer() {
let hours = Math.floor(seconds / 3600);
// Get minutes
let minutes = Math.floor((seconds - hours * 3600) / 60);
// Get seconds
let secs = Math.floor(seconds % 60);
if (hours < 10) {
hours = `0${hours}`;
}
if (minutes < 10) {
minutes = `0${minutes}`;
}
if (secs < 10) {
secs = `0${secs}`;
}
return `${hours}:${minutes}:${secs}`;
}
});

Save the interval and timer in array let seconds = [] and I simplified your code, Start and Pause button are merged, if (time < 10) change with .padStart()
run on jsFiddle
let startTimeButtons = document.querySelectorAll(".start")
let seconds = [0, 0];
let interval = [];
if (localStorage.getItem("stopwatchSeconds") != null) {
seconds = JSON.parse(localStorage.getItem("stopwatchSeconds"));
seconds = seconds.map(n => parseInt(n))
}
const timer = (el, i) => {
seconds[i]++;
localStorage.setItem("stopwatchSeconds", JSON.stringify(seconds));
// Get hours
let hours = Math.floor(seconds[i] / 3600).toString().padStart(2, 0);
// Get minutes
let minutes = Math.floor((seconds[i] - hours * 3600) / 60).toString().padStart(2, 0);
// Get seconds
let secs = Math.floor(seconds[i] % 60).toString().padStart(2, 0);
el.parentElement.querySelector('.output').innerHTML = `${hours}:${minutes}:${secs}`;
};
startTimeButtons.forEach((btn, index) => {
timer(btn, index); // update time on page load
btn.addEventListener("click", () => {
if (btn.textContent == 'Start') {
btn.textContent = 'Pause';
interval[index] = setInterval(timer, 1000, btn, index);
} else {
btn.textContent = 'Start';
clearInterval(interval[index]);
}
});
})
<div class="c-add-task-main-container">
<h2 class="c-add-task-title">Time Tracker</h2>
<button class="start">Start</button>
<button class="clear">Clear</button>
<div class="output">00:00:00</div>
</div>
<div class="c-add-task-main-container">
<h2 class="c-add-task-title">Time Tracker</h2>
<button class="start">Start</button>
<button class="clear">Clear</button>
<div class="output">00:00:00</div>
</div>

Related

Trying to compare value of string that are programmatically added with javascript

I'm trying to prevent my laps from counting the same second. So I'm trying to take the current value and evaluate it as != not equal to the previous value before appending it.
Here is the function, and my HTML. Not sure if I can do anything with the ids I set up. I have jquery set up to run in my javascript, so if you have any ideas with that I would be open to listening. There are a couple of things that probably don't have a use that I have not removed yet.
Javascript Function
let seconds = 0;
let minutes = null;
let hours = null;
let startTimer = null;
let time = null;
let isRunning = (false);
let lapContainer = [];
let x;
let outputseconds;
let outputminutes;
let outputhours;
//connection to button
document.getElementById("start").addEventListener("click", start);
document.getElementById("stop").addEventListener("click", stop);
document.getElementById("reset").addEventListener("click", reset);
document.getElementById("lap").addEventListener("click", lap);
document.getElementById("resetLaps").addEventListener("click", resetLaps);
//functions
function start() {
if (isRunning === false) {
isRunning = true;
//interval
startTimer = setInterval(function () {
seconds++;
if (seconds <= 9) {
outputseconds = "0" + seconds;
document.getElementById("seconds").innerHTML = outputseconds;
} else if (seconds <= 60) {
outputseconds = seconds;
document.getElementById("seconds").innerHTML = outputseconds;
} else if (seconds >= 60) {
minutes++;
outputseconds = "00";
outputminutes = "0" + minutes;
document.getElementById("seconds").innerHTML = outputseconds;
document.getElementById("minutes").innerHTML = outputminutes;
seconds = 0;
} else if (minutes >= 9) {
outputminutes = minutes;
document.getElementById("minutes").innerHTML = outputminutes;
} else if (minutes >= 60) {
hours++;
outputminutes = "00";
outputhours = "0" + hours;
document.getElementById("minutes").innerHTML = outputminutes;
document.getElementById("hours").innerHTML = outputhours;
minutes = 0;
} else if (hours > 9) {
outputhours = hours;
document.getElementById("hours").innerHTML = outputhours;
}
}, 1000); //end of interval
} // end of if check
// should this be seperated out as a function???
let startTime = "00";
if (outputseconds > 0) {
if (outputminutes > 0) {
if (outputhours > 0) {
return outputhours + ":" + outputminutes + ":" + outputseconds;
} else {
return startTime + ":" + outputminutes + ":" + outputseconds;
} // hours
} else {
return startTime + ":" + startTime + ":" + outputseconds;
} //minutes
} else {
return startTime + ":" + startTime + ":" + startTime;
} // end of nested if seconds
} //end of start function
function stop() {
clearInterval(startTimer);
isRunning = false;
}
function reset() {
clearInterval(startTimer);
document.getElementById("seconds").innerHTML = "00";
document.getElementById("minutes").innerHTML = "00";
document.getElementById("hours").innerHTML = "00";
seconds = 0;
minutes = 0;
hours = 0;
isRunning = false;
}
function lap() {
if (isRunning === true) {
//initialize time
let lapTime = start();
//create connection to div
lapContainer = document.getElementById("lapContainer");
// how to check if they equal each other
//create element
const para = document.createElement("p");
//how many laps have been created
let i = document.getElementById("lapContainer").childElementCount;
let index = [i];
//create an index that will add an id to paragraph
para.id = index;
//add the lap to text
para.innerText = lapTime;
let laps = [];
laps = document.getElementById("lapContainer").childNodes[1].textContent;
let lastItem = laps[laps.length - 1];
let currentItem = laps[laps.length];
document.getElementById("test").innerHTML = laps;
if (currentItem !== lastItem) {
lapContainer.appendChild(para);
}
}
}
function resetLaps() {
$(lapContainer).empty();
isRunning = false;
}
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Stopwatch</title>
<meta name="description" content="A simple stopwatch application" />
<meta name="author" content="****" />
<link rel="icon" href="/favicon.ico" />
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="stylesheet" href="./css/styles.css" />
</head>
<body>
<!-- your content here... -->
<div class="menu">
Timer
Alarm
</div>
<div class="stopwatch-container">
<div class="stopwatch-wrapper">
<div class="stopwatch-button-container">
<button type="button" id="start">START</button>
<button type="button" id="stop">STOP</button>
<button type="button" id="reset">RESET</button>
<button type="button" id="lap">LAP</button>
<button type="button" id="resetLaps">RESET LAPS</button>
</div>
<div class="rectangle-container">
<div class="rectangle">
<p id="textWrapper">
<span id="hours">00</span>:<span id="minutes">00</span>:<span
id="seconds"
>00</span
>
</p>
</div>
</div>
</div>
</div>
<div class="lineBreak"></div>
<div id="lapContainer" class="lap-container"></div>
<p id="test"></p>
<script src="./scripts/scripts.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</body>
</html>
Few things you might need to do:
1.When you set the laps array you need to get the array of texts of the all nodes, not just a text of the first node:
//laps = document.getElementById("lapContainer").childNodes[1].textContent;
laps = Array.from(document.getElementById("lapContainer").childNodes).map(node => node.textContent);
2.When you set currentItem you can not use laps[laps.length] because your new value not in the array yet and so it will return undefined. Instead you can just use your lapTime value:
let lastItem = laps[laps.length - 1];
//let currentItem = laps[laps.length];
let currentItem = lapTime;
Example:
let isRunning = Boolean(true);
let lapContainer = [];
document.querySelector('#lap').addEventListener('click', () => lap());
function lap() {
if (isRunning === true) {
//initialize time
let lapTime = start();
//create connection to div
lapContainer = document.getElementById("lapContainer");
// how to check if they equal each other
//create element
const para = document.createElement("p");
//how many laps have been created
let i = document.getElementById("lapContainer").childElementCount;
let index = [i];
//create an index that will add an id to paragraph
para.id = index;
//add the lap to text
para.innerText = lapTime;
let laps = [];
//laps = document.getElementById("lapContainer").childNodes[1].textContent;
laps = Array.from(document.getElementById("lapContainer").childNodes).map(node => node.textContent);
let lastItem = laps[laps.length - 1];
//let currentItem = laps[laps.length];
let currentItem = lapTime;
document.getElementById("test").innerHTML = laps;
if (currentItem !== lastItem) {
lapContainer.appendChild(para);
}
}
}
const start = () => new Date().toString();
<body>
<!-- your content here... -->
<div class="menu">
Timer
Alarm
</div>
<div class="stopwatch-container">
<div class="stopwatch-wrapper">
<div class="stopwatch-button-container">
<button type="button" id="start">START</button>
<button type="button" id="stop">STOP</button>
<button type="button" id="reset">RESET</button>
<button type="button" id="lap">LAP</button>
<button type="button" id="resetLaps">RESET LAPS</button>
</div>
<div class="rectangle-container">
<div class="rectangle">
<p id="textWrapper">
<span id="hours">00</span>:<span id="minutes">00</span>:<span
id="seconds"
>00</span
>
</p>
</div>
</div>
</div>
</div>
<div class="lineBreak"></div>
<div id="lapContainer" class="lap-container"></div>
<p id="test"></p>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</body>

Is there another way to get a HTML element in javascript other than querySelector and getElementId?

I'm trying to get a HTML element, a button, to my javascript file. I've tried .querySelector and .getElementById and my script file is attached at the bottom of my file just before the closing tag of my body element. but for each of variable I've tried the .addListener function on them but receive the error ' Cannot read properties of null (reading 'addEventListener')'
Here is my HTML Code:
<body>
<div class="whole">
<!-- Navbar -->
<div class="logo">
<img src="/focus-logo.png" alt="logo" width="100" height="100">
</div>
<!-- timer -->
<figure class="timer">
<div class="minsSec">
<span class="mins">0</span>
<span>:</span>
<span class="secs">00</span>
</div>
<svg class="progress-ring" height="240" width="240">
<circle
class="progress-ring__circle"
stroke-width="10"
fill="transparent"
r="110"
cx="120"
cy="120"
/>
</svg>
</figure>
<div class="timer__btn">
<button class="set">Set</button>
<button id="start">start focus</button>
<button id="reset">reset</button>
<button class="pause">pause</button>
</div>
<script src="setTime.js"></script>
<script src="newTimer.js"></script>
<script src="progressBar.js"></script>
</div>
</body>
and
<body>
<form action=".">
<label for="focusTime">Focus Time</label>
<input type="number" id="focusTimeNum" />
<label for="breakTime">Break Time</label>
<input type="number" id="breakTime" />
<button type="submit">Save settings</button>
</form>
<script src="setTime.js"></script>
<script src="newTimer.js"></script>
</body>
Newtimer.js
const el = document.querySelector(".timer");
const mindiv = document.querySelector(".mins");
const secdiv = document.querySelector(".secs");
const startBtn = document.querySelector("#start");
localStorage.setItem("btn", "focus");
let initial, totalsecs, perc, paused, mins, seconds;
** startBtn.addEventListener("click", () => { **
let btn = localStorage.getItem("btn");
if (btn === "focus") {
mins = +localStorage.getItem("focusTime") || 1;
} else {
mins = +localStorage.getItem("breakTime") || 1;
}
seconds = mins * 60;
totalsecs = mins * 60;
setTimeout(decremenT(), 60);
startBtn.style.transform = "scale(0)";
paused = false;
});
function decremenT() {
mindiv.textContent = Math.floor(seconds / 60);
secdiv.textConten
t = seconds % 60 > 9 ? seconds % 60 : `0${seconds % 60}`;
if (circle.classList.contains("danger")) {
circle.classList.remove("danger");
}
if (seconds > 0) {
perc = Math.ceil(((totalsecs - seconds) / totalsecs) * 100);
setProgress(perc);
seconds--;
initial = window.setTimeout("decremenT()", 1000);
if (seconds < 10) {
circle.classList.add("danger");
}
} else {
mins = 0;
seconds = 0;
let btn = localStorage.getItem("btn");
if (btn === "focus") {
startBtn.textContent = "start break";
startBtn.classList.add("break");
localStorage.setItem("btn", "break");
} else {
startBtn.classList.remove("break");
startBtn.textContent = "start focus";
localStorage.setItem("btn", "focus");
}
startBtn.style.transform = "scale(1)";
}
}
and setTimer.js
const focusTimeInput = document.getElementById("focusTimeNum").value;
const breakTimeInput = document.querySelector("#breakTime");
const pauseBtn = document.querySelector(".pause");
focusTimeInput.value = localStorage.getItem("focusTime");
breakTimeInput.value = localStorage.getItem("breakTime");
document.querySelector("form").addEventListener("submit", (e) => {
e.preventDefault();
localStorage.setItem("focusTime", focusTimeInput.value);
localStorage.setItem("breakTime", breakTimeInput.value);
});
document.getElementById("reset").addEventListener("click", () => {
startBtn.style.transform = "scale(1)";
clearTimeout(initial);
setProgress(0);
mindiv.textContent = 0;
secdiv.textContent = 0;
});
pauseBtn.addEventListener("click", () => {
if (paused === undefined) {
return;
}
if (paused) {
paused = false;
initial = setTimeout("decremenT()", 60);
pauseBtn.textContent = "pause";
pauseBtn.classList.remove("resume");
} else {
clearTimeout(initial);
pauseBtn.textContent = "resume";
pauseBtn.classList.add("resume");
paused = true;
}
});
The line from newTimer.js
startBtn.addEventListener("click", () => {
and the line from setTimer.js
document.getElementById("reset").addEventListener("click", () => {
I'm using node and express for the backend side

how to display " backward timer " using JavaScript?

I have my DOM like this :
<input type="number" id="input" value="" placeholder="Enter time in minutes">
<button id="button">Go</button>
<button id="reset">reset</button>
<div class="timer">
<div class="mint" id="mint"></div>
<div class="sec" id="sec"></div>
</div>
And my JavaScript Like this :
let currentTime = 0;
let intervalClear;
let input = document.getElementById('input');
let button = document.getElementById('button')
button.addEventListener('click', ()=>{
let value = input.value * 60000;
function getTime(){
currentTime++
function backcount(currentTime){
let output = value - currentTime
console.log(output);
const mint = document.getElementById('mint'),
sec = document.getElementById('sec');
let minute = Math.floor(output/60000)
let second = ((output % 60000) / 1000).toFixed(0)
mint.innerText = minute;
sec.innerText = second;
if(output == 0){
clearInterval(intervalClear)
}
}
backcount(currentTime);
}
getTime()
intervalClear = setInterval(getTime, 1000)
})
const reset = document.getElementById('reset')
reset.addEventListener('click', ()=>{
clearInterval(intervalClear);
input.value = '';
})
now I want to display value in my web page But it doesn't updating. seems like its freezes. but my "setInterval()" running properly.
How can I resolve this issue? need help!
You need instead of this code
let output = value - currentTime
use this
let output = value - (currentTime * 1000)
let currentTime = 0;
let intervalClear;
let input = document.getElementById('input');
let button = document.getElementById('button')
button.addEventListener('click', ()=>{
let value = input.value * 60000;
function getTime(){
currentTime++
function backcount(currentTime){
let output = value - (currentTime * 1000)
console.log(output);
const mint = document.getElementById('mint'),
sec = document.getElementById('sec');
let minute = Math.floor(output/60000)
let second = ((output % 60000) / 1000).toFixed(0)
mint.innerText = minute;
sec.innerText = second;
if(output == 0){
clearInterval(intervalClear)
}
}
backcount(currentTime);
}
getTime()
intervalClear = setInterval(getTime, 1000)
})
const reset = document.getElementById('reset')
reset.addEventListener('click', ()=>{
clearInterval(intervalClear);
input.value = '';
})
<input type="number" id="input" value="" placeholder="Enter time in minutes">
<button id="button">Go</button>
<button id="reset">reset</button>
<div class="timer">
<div class="mint" id="mint"></div>
<div class="sec" id="sec"></div>
</div>
Based on #Oleg Barabanov's answer I found one bug. If you didn't enter any value in text box or first added value then click on "Reset" and click on "Go" button then counter started with negative value. I fixed that issue with this code.
Script
var intervalClear;
var input = document.querySelector('#input');
var mint = document.querySelector('#mint');
var sec = document.querySelector('#sec');
var go_button = document.querySelector('#button');
var reset_button = document.querySelector('#reset');
go_button?.addEventListener('click', () => {
if (input.value != '' && input.value != 0 && parseInt(input.value) != NaN) {
startTimer(input.value, mint, sec);
}
});
reset_button?.addEventListener('click', () => {
clearInterval(intervalClear);
mint.textContent = '00';
sec.textContent = '00';
});
function startTimer(duration, minElement, secElement) {
clearInterval(intervalClear);
var timer = duration * 60, minutes, seconds;
intervalClear = setInterval(function () {
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
minElement.textContent = minutes;
secElement.textContent = seconds;
if (--timer < 0) {
timer = duration;
}
if (minutes == 0 && seconds == 0) {
clearInterval(intervalClear);
mint.textContent = '00';
sec.textContent = '00';
}
}, 1000);
}
DOM
<input type="number" id="input" placeholder="Enter time in minutes" >
<button id="button">Go</button>
<button id="reset">reset</button>
<div class="timer">
<div class="mint" id="mint">00</div>
<div class="sec" id="sec">00</div>
</div>

how to add a save button in timer

i have no idea how to save and show out put next to stopwatch:
00:01:30 , 00:01:30 something like this.
its not important but can i make stopwatch to stop on some time like 45 min
i created a button "save" was playing whit code but i have no idea how to make it save output and show
i was trying to find in internet but could not find
I appreciate any help.
var ss = document.getElementsByClassName('stopwatch');
[].forEach.call(ss, function(s) {
var currentTimer = 0,
interval = 0,
lastUpdateTime = new Date().getTime(),
start = s.querySelector('button.start'),
stop = s.querySelector('button.stop'),
reset = s.querySelector('button.reset'),
mins = s.querySelector('span.minutes'),
secs = s.querySelector('span.seconds'),
cents = s.querySelector('span.centiseconds');
start.addEventListener('click', startTimer);
stop.addEventListener('click', stopTimer);
reset.addEventListener('click', resetTimer);
function pad(n) {
return ('00' + n).substr(-2);
}
function update() {
var now = new Date().getTime(),
dt = now - lastUpdateTime;
currentTimer += dt;
var time = new Date(currentTimer);
mins.innerHTML = pad(time.getMinutes());
secs.innerHTML = pad(time.getSeconds());
cents.innerHTML = pad(Math.floor(time.getMilliseconds() / 10));
lastUpdateTime = now;
}
function startTimer() {
if (!interval) {
lastUpdateTime = new Date().getTime();
interval = setInterval(update, 1);
}
}
function stopTimer() {
clearInterval(interval);
interval = 0;
}
function resetTimer() {
stopTimer();
currentTimer = 0;
mins.innerHTML = secs.innerHTML = cents.innerHTML = pad(0);
}
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Stopwatch</title>
</head>
<body>
<h1>Stopwatch</h1>
<div class="stopwatch">
<div class="controls">
<button class="start">Start</button>
<button class="stop">Stop</button>
<button class="reset">Reset</button>
<button class="save">save</button>
</div>
<div class="display">
<span class="minutes">00</span>:<span class="seconds">00</span>:<span class="centiseconds">00</span>
</div>
</div>
<script src="stopwatch.js"></script>
</body>
</html>
if i correct understand - here is solution. You still need some validations on input fields, checks on current timer and ithers, but it's worked version if user takes into account all these nuances himself.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Stopwatch</title>
</head>
<body>
<h1>Stopwatch</h1>
<div class="stopwatch">
<div class="controls">
<button class="start">Start</button>
<button class="stop">Stop</button>
<button class="reset">Reset</button>
||stop on:
<input class="min" placeholder="min" type="text" style="width: 30px" />:
<input class="sec" placeholder="sec" type="text" style="width: 30px" />:
<input class="ms" placeholder="ms" type="text" style="width: 30px" />
<button class="save">save</button>
<div class="savedTimeBlock" style="display: none">
saved time:
<div style="display: inline-block" class="time"></div>
</div>
</div>
<div class="display">
<span class="minutes">00</span>:<span class="seconds">00</span>:<span
class="centiseconds"
>00</span
>
</div>
</div>
<script src="stopwatch.js"></script>
</body>
</html>
stopwatch.js
var ss = document.getElementsByClassName("stopwatch");
[].forEach.call(ss, function(s) {
var currentTimer = 0,
interval = 0,
lastUpdateTime = new Date().getTime(),
timeToStop = {
min:null,
sec:null,
ms:null
},
start = s.querySelector("button.start"),
stop = s.querySelector("button.stop"),
reset = s.querySelector("button.reset"),
mins = s.querySelector("span.minutes"),
secs = s.querySelector("span.seconds"),
cents = s.querySelector("span.centiseconds"),
minutes = s.querySelector(".min"),
seconds = s.querySelector(".sec"),
milliseconds = s.querySelector(".ms"),
savedTimeBlock = s.querySelector(".savedTimeBlock"),
time = s.querySelector(".time"),
save = s.querySelector(".save");
start.addEventListener("click", startTimer);
stop.addEventListener("click", stopTimer);
save.addEventListener("click", saveStopTime);
reset.addEventListener("click", resetTimer);
function pad(n) {
return ("00" + n).substr(-2);
}
function saveStopTime() {
let min = timeToStop.min = pad(+minutes.value),
sec = timeToStop.sec = pad(+seconds.value),
ms = timeToStop.ms = pad(+milliseconds.value);
if (+min || +sec || +ms) {
showSavedTimeBlock(min, sec, ms)
} else {
killSavedTimeBlock()
}
}
const showSavedTimeBlock = (min, sec, ms) => {
savedTimeBlock.style.display = 'inline-block';
time.innerText = `${min}:${sec}:${ms}:`
};
const killSavedTimeBlock = () => {
savedTimeBlock.style.display = 'none';
timeToStop.min = null;
timeToStop.sec = null;
timeToStop.ms = null;
time.innerText = ''
};
function update() {
var now = new Date().getTime(),
dt = now - lastUpdateTime;
currentTimer += dt;
var time = new Date(currentTimer);
let min = pad(time.getMinutes());
let sec = pad(time.getSeconds());
let ms = pad(Math.floor(time.getMilliseconds() / 10));
mins.innerHTML = min;
secs.innerHTML = sec;
cents.innerHTML = ms;
let ts = timeToStop;
if (ts.min === min && ts.sec === sec && ts.ms === ms) {
stopTimer()
} else {
lastUpdateTime = now;
}
}
function startTimer() {
if (!interval) {
lastUpdateTime = new Date().getTime();
interval = setInterval(update, 1);
}
}
function stopTimer() {
clearInterval(interval);
interval = 0;
}
function resetTimer() {
stopTimer();
killSavedTimeBlock()
currentTimer = 0;
mins.innerHTML = secs.innerHTML = cents.innerHTML = pad(0);
}
});

Pomodoro Clock Break Buttons not working

I'm building a Pomodoro Clock to improve my JavaScript, but I have a few issues. For starters, the increment/decrement buttons for the break do not update the time in the display. Secondly, the Session time doesn't restart after the first break period. Can anyone, please, advise me of where I went wrong?
The HTML:
<html>
<head>
<title>David Hall - Pomodoro Clock Zipline</title>
<link href="https://fonts.googleapis.com/css?family=Orbitron" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link href="main.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="container">
<h1 class="center">Pomodoro Clock</h1>
<div class="row">
<div class="center">
<div class="col-sm-6">Break Length</div>
<div class="col-sm-6">Work Length</div>
<div class="col-sm-6" id="center">
<div class="btn-group">
<button type="button" class="btn btn-success" id="decreaseBreak"><span class="glyphicon glyphicon-menu-left"></span>
<button type="button" class="btn btn-success"><span id="breakTime">5</span>
<button type="button" class="btn btn-success btn" id="increaseBreak"><span class="glyphicon glyphicon-menu-right"></span></div>
</div>
<div class="col-sm-6">
<div class="btn-group">
<button type="button" class="btn btn-success" id="decreaseWork"><span class="glyphicon glyphicon-menu-left"></span>
<button type="button" class="btn btn-success"><span id="workTime">25:00</span>
<button type="button" class="btn btn-success btn" id="increaseWork"> <span class="glyphicon glyphicon-menu-right"></span></div>
</div>
<br />
<br />
<br />
<br />
<div class="center">
<div class="boxed">
<br />
<span id="boxText">SESSION</span>
<br />
<br />
<br />
<span id="display"></span>
<br />
<span id="timerStatus"></span>
</div>
<br />
<button type="button" class="btn btn-success btn-sm" id="start">Start</button>
<button type="button" class="btn btn-success btn-sm" id="pause">Pause</button>
<button type="button" class="btn btn-success btn-sm" id="reset">Reset</button>
</div>
</div>
<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'> </script>
<script src='http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js'></script>
<script src="script.js"></script>
</body>
</html>
And the JavaScript:
var myInterval;
var workTime = document.getElementById("workTime").innerHTML = 25;
var breakTime = document.getElementById("breakTime").innerHTML = 5;
var remainSec = workTime * 60;
document.getElementById("display").innerHTML = workTime;
function startWork() {
document.getElementById("start").disabled = true;
timer(callback);
}
function pauseTime() {
clearInterval(myInterval);
document.getElementById("start").disabled = false;
}
function displayTime(remainingTime) {
if (remainingTime % 60 >= 10) {
document.getElementById('display').innerHTML = Math.floor(remainingTime / 60) + ':' + Math.floor(remainingTime % 60);
} else {
document.getElementById('display').innerHTML = Math.floor(remainingTime / 60) + ':' + "0" + Math.floor(remainingTime % 60);
}
}
function timer(pomodoro) {
var remainingTime = remainSec;
myInterval = setTimeout(function() {
displayTime(remainingTime);
if (remainingTime >= 0) {
remainSec--;
timer(pomodoro);
} else {
clearInterval();
pomodoro();
}
}, 1000);
}
var callback = function() {
console.log('callback');
document.getElementById('timerStatus').innerHTML = "Take a break!";
remainSec = breakTime * 60;
timer(callbackRest)
};
var callbackRest = function() {
clearInterval(myInterval);
console.log('callbackRest');
document.getElementById('timerStatus').innerHTML = "Begin";
remainSec = workTime * 60;
document.getElementById("start").disabled = false;
};
function resetTime() {
clearInterval(myInterval);
remainSec = workTime * 60;
startWork();
}
function decreaseWork() {
if (workTime >= 1) {
document.getElementById('workTime').innerHTML = --workTime;
remainSec = workTime * 60;
}
}
function decreaseBreak() {
if (breakTime >= 1) {
document.getElementById('breakTime').innerHTML = --breakTime;
}
}
function increaseWork() {
document.getElementById('workTime').innerHTML = ++workTime;
remainSec = workTime * 60;
}
function increaseBreak() {
document.getElementById('breakTime').innerHTML = ++breakTime;
}
document.getElementById('start').addEventListener('click', startWork);
document.getElementById('pause').addEventListener('click', pauseTime);
document.getElementById('reset').addEventListener('click', resetTime);
document.getElementById('decreaseWork').addEventListener('click', decreaseWork);
document.getElementById('decreaseBreak').addEventListener('click', decreaseBreak);
document.getElementById('increaseWork').addEventListener('click', increaseWork);
document.getElementById('increaseBreak').addEventListener('click', increaseBreak);
Any feedback is much appreciated!
I just added a few things.
First two flags were added to know if isPomodoroTime status and if isBreakTime status, maybe you ask why two? because I needed a initial state which is when both were false, with those flags I can incremente and display time without confusing, for that there is a new function callled changeTimeAndDisplay that is being called from all increase and decrease methods. I also put a startWork in the callback where suppose to be called when break time finish.
here is a demo - codepen.io
var myInterval;
var workTime = document.getElementById("workTime").innerHTML = 25;
var breakTime = document.getElementById("breakTime").innerHTML = 5;
var remainSec = workTime * 60;
var isPomodoroTime = false; //new
var isBreakTime = false; //new
//new function
function changeTimeAndDisplay(newTime){
remainSec = newTime * 60;
displayTime(remainSec);
}
document.getElementById("display").innerHTML = workTime;
function startWork() {
isPomodoroTime = true; //new
document.getElementById("start").disabled = true;
timer(callback);
}
function pauseTime() {
clearInterval(myInterval);
document.getElementById("start").disabled = false;
}
function displayTime(remainingTime) {
if (remainingTime % 60 >= 10) {
document.getElementById('display').innerHTML = Math.floor(remainingTime / 60) + ':' + Math.floor(remainingTime % 60);
} else {
document.getElementById('display').innerHTML = Math.floor(remainingTime / 60) + ':' + "0" + Math.floor(remainingTime % 60);
}
}
function timer(pomodoro) {
var remainingTime = remainSec;
myInterval = setTimeout(function() {
displayTime(remainingTime);
if (remainingTime >= 0) {
remainSec--;
timer(pomodoro);
} else {
clearInterval(myInterval); //new
pomodoro();
}
}, 1000);
}
var callback = function() {
isPomodoroTime = false; //new
isBreakTime = true; //new
console.log('callback');
document.getElementById('timerStatus').innerHTML = "Take a break!";
remainSec = breakTime * 60;
timer(callbackRest)
};
var callbackRest = function() {
isPomodoroTime = true; //new
isBreakTime = false; //new
clearInterval(myInterval);
console.log('callbackRest');
document.getElementById('timerStatus').innerHTML = "Begin";
remainSec = workTime * 60;
document.getElementById("start").disabled = false;
startWork(); //new
};
function resetTime() {
clearInterval(myInterval);
remainSec = workTime * 60;
startWork();
}
function decreaseWork() {
if (workTime >= 1) {
document.getElementById('workTime').innerHTML = --workTime;
if(isPomodoroTime || !isPomodoroTime && !isBreakTime){ //new if block
changeTimeAndDisplay(workTime);
}
}
}
function decreaseBreak() {
if (breakTime >= 1) {
document.getElementById('breakTime').innerHTML = --breakTime;
if(!isPomodoroTime && isBreakTime){ //new if block
changeTimeAndDisplay(breakTime);
}
}
}
function increaseWork() {
document.getElementById('workTime').innerHTML = ++workTime;
if(isPomodoroTime || !isPomodoroTime && !isBreakTime){ //new if block
changeTimeAndDisplay(workTime);
}
}
function increaseBreak() {
document.getElementById('breakTime').innerHTML = ++breakTime;
if(!isPomodoroTime && isBreakTime){ //new if block
changeTimeAndDisplay(breakTime);
}
}
document.getElementById('start').addEventListener('click', startWork);
document.getElementById('pause').addEventListener('click', pauseTime);
document.getElementById('reset').addEventListener('click', resetTime);
document.getElementById('decreaseWork').addEventListener('click', decreaseWork);
document.getElementById('decreaseBreak').addEventListener('click', decreaseBreak);
document.getElementById('increaseWork').addEventListener('click', increaseWork);
document.getElementById('increaseBreak').addEventListener('click', increaseBreak);
As advice you could simplify more your code for example make a function for document.getElementById(id).addEventListener(evnName,func);
function addAction(evnName,id,selector){
document.getElementById(id).addEventListener(evnName,func);
}
or
function addValue(id,value){
document.getElementById(id).innerHTML = value;
}
And replace all document.getElementById
regards.

Categories