I am having a countdown in javascript and a button which will pause/stop the countdown.
{
"message": "Uncaught ReferenceError: x is not defined",
"filename": "https://stacksnippets.net/js",
"lineno": 57,
"colno": 17
}
function start() {
var table = document.getElementById("test");
var row = table.insertRow(0);
var cell1 = row.insertCell(0);
cell1.colSpan = 2;
var countDownDate = new Date("Apr 30, 2019 11:12:27").getTime();
// Update the count down every 1 second
var x = setInterval(function() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
cell1.innerHTML = seconds;
//document.getElementById("timer").innerHTML = days + "d " + hours + "h "
//+ minutes + "m " + seconds + "s ";
if (distance < 0) {
clearInterval(x);
cell1.innerHTML = "EXPIRED";
}
}, 1000);
}
function stop() {
clearInterval(x);
}
<table id="test" class="table table-bordered table-responsive">
</table>
<button onclick="start()">Start</button>
<button onclick="stop()">Stop</button>
I know it can be stopped in the same function, but it is just an example, in my real code, it has to be stopped outside the function.
How to set x so that it works outside the function too?
Variable x is not defined out the function start, so function stop don't see it.
Easy way to solve it, declare x global.
var x;
function start() {
var table = document.getElementById("test");
var row = table.insertRow(0);
var cell1 = row.insertCell(0);
cell1.colSpan = 2;
var countDownDate = new Date("Apr 30, 2019 11:12:27").getTime();
// Update the count down every 1 second
x = setInterval(function() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
cell1.innerHTML = seconds;
//document.getElementById("timer").innerHTML = days + "d " + hours + "h "
//+ minutes + "m " + seconds + "s ";
if (distance < 0) {
clearInterval(x);
cell1.innerHTML = "EXPIRED";
}
}, 1000);
}
function stop() {
clearInterval(x);
}
<table id="test" class="table table-bordered table-responsive">
</table>
<button onclick="start()">Start</button>
<button onclick="stop()">Stop</button>
Just declare it at the top of the script so that each function can reference it:
var x;
function start() {
var table = document.getElementById("test");
var row = table.insertRow(0);
var cell1 = row.insertCell(0);
cell1.colSpan = 2;
var countDownDate = new Date("Apr 30, 2019 11:12:27").getTime();
// Update the count down every 1 second
x = setInterval(function() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
cell1.innerHTML = seconds;
//document.getElementById("timer").innerHTML = days + "d " + hours + "h "
//+ minutes + "m " + seconds + "s ";
if (distance < 0) {
clearInterval(x);
cell1.innerHTML = "EXPIRED";
}
}, 1000);
}
function stop() {
clearInterval(x);
}
<table id="test" class="table table-bordered table-responsive">
</table>
<button onclick="start()">Start</button>
<button onclick="stop()">Stop</button>
But it would be better to avoid global namespace pollution, so you could achieve that by also wrapping the whole thing in an IIFE and attaching the listeners properly with Javascript rather than in the HTML: (inline event handlers are as bad as eval)
(() => {
let x;
const [startButton, stopButton] = [...document.querySelectorAll('button')];
startButton.onclick = start;
stopButton.onclick = stop;
function start() {
var table = document.getElementById("test");
var row = table.insertRow(0);
var cell1 = row.insertCell(0);
cell1.colSpan = 2;
var countDownDate = new Date("Apr 30, 2019 11:12:27").getTime();
// Update the count down every 1 second
x = setInterval(function() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
cell1.innerHTML = seconds;
//document.getElementById("timer").innerHTML = days + "d " + hours + "h "
//+ minutes + "m " + seconds + "s ";
if (distance < 0) {
clearInterval(x);
cell1.innerHTML = "EXPIRED";
}
}, 1000);
}
function stop() {
clearInterval(x);
}
})();
<table id="test" class="table table-bordered table-responsive">
</table>
<button>Start</button>
<button>Stop</button>
Related
I'm trying to make a count up timer, it has to be counting the time that a ticket is getting solved even if you change or refresh the page, when it is over the user has to click the button stop, but I have a problem, when it is counting I press the button Stop and reset it works but when I refresh my site it is still counting and it doesn't stop.
This is for my site:
var countDownDate = localStorage.getItem('startDate');
if (countDownDate) {
countDownDate = new Date(countDownDate);
} else {
countDownDate = new Date();
localStorage.setItem('startDate', countDownDate);
}
var x = setInterval(function() {
var now = new Date().getTime();
var distance = now - countDownDate.getTime();
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
document.getElementById("demo").innerHTML = days + "d " + hours + "h " + minutes + "m " + seconds + "s ";
}, 1000);
function Reset() {
var countDownDate = localStorage.getItem('startDate');
if (countDownDate == 0, clearInterval(x)) {
countDownDate = new Date(countDownDate);
} else {
countDownDate = new Date();
localStorage.setItem('startDate', countDownDate);
}
}
<button onclick="Reset()">Stop and Reset</button>
<p id="demo"></p>
i want make a local countdown for 1H & i want code to pause the timer & resume it of course! & i searched on web but i found codes that work to count incoming days
PS: code is demo from w3schools (but it's still counting incoming days so yeah)
var countDownDate = new Date("Jan 5, 2019 15:37:25").getTime();
var x = setInterval(function() {
var now = new Date().getTime();
var distance = countDownDate - now;
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
document.getElementById("demo").innerHTML = days + "d " + hours + "h "
+ minutes + "m " + seconds + "s ";
if (distance < 0) {
clearInterval(x);
document.getElementById("demo").innerHTML = "EXPIRED";
}
}, 1000);
expected results: code counting 1h
actual results: code counting incoming days
Starting from your code, you can get what you want with just a few changes:
const ONE_HOUR_ON_MILLIS = 1000 * 60 * 60;
var countDownDate;
var running;
var remainingMillis;
var update;
initCountdown();
function startInterval() {
return setInterval(function () {
var now = new Date().getTime();
remainingMillis = countDownDate - now;
var hours = Math.floor((remainingMillis % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((remainingMillis % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((remainingMillis % (1000 * 60)) / 1000);
var millis = Math.floor((remainingMillis % 1000));
document.getElementById("demo").innerHTML = hours + ":" + minutes + ":" + seconds + "." + millis;
if (remainingMillis < 0) {
clearInterval(update);
document.getElementById("demo").innerHTML = "EXPIRED";
}
}, 10);
}
function stop() {
if (running) {
var now = new Date().getTime();
remainingMillis = countDownDate - now;
running = false;
clearInterval(update);
} else {
alert('cant stop');
}
}
function start() {
if (!running) {
countDownDate = new Date().getTime() + remainingMillis;
update = startInterval();
running = true;
}
}
function initCountdown() {
countDownDate = new Date().getTime() + ONE_HOUR_ON_MILLIS;
update = startInterval();
running = true;
}
function restart() {
initCountdown();
debugger;
}
<span id="demo">COUNTDOWN</span>
<div class="controls">
<button id="start" onclick="start()">Start</button>
<button id="stop" onclick="stop()">Stop</button>
<button id="restart" onclick="restart()">Restart</button>
</div>
This should do what you want.
I have made a countdown that will be displayed in the table column, but it is repeating column instead of the change in the column.
The snippet will help for better understanding the question: (edited)
var countDownDate = new Date("Apr 29, 2019 23:56:26").getTime();
var table = document.getElementById("test");
// Update the count down every 1 second
var x = setInterval(function() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
var row = table.insertRow(0);
var cell1 = row.insertCell(0);
cell1.innerHTML = days + "d " + hours + "h "
if (distance < 0) {
clearInterval(x);
document.getElementById("timer").innerHTML = "EXPIRED";
}
}, 1000);
.timer_bg {
background-color: red;
color: white;
}
<table id="test" class="table table-bordered table-responsive">
</table>
The countdown works well, it is decreasing too, every second it is generating one more column, I don't want that.
UPDATE
Also how to add class timer_bg in that row?
Move row and cell creation outside the setInterval.
var row = table.insertRow(0);
var cell1 = row.insertCell(0);
setInterval(...)
Add class to row as shown below:
row.className = 'timer_bg';
The simplest solution is to create a fixed table and just inject the changed time into a fixed element.
There is no need to create the table row and cell. You can just have it already in your original HTML.
Update 1
If you need really to create the element dynamically you should create this element outside of the setInterval function (Credits to https://stackoverflow.com/a/50089575/2735286 ). There you can also add your class name.
var countDownDate = new Date("Apr 29, 2019 23:56:26").getTime();
var table = document.getElementById("targetTable");
var row = table.insertRow(0);
var cell1 = row.insertCell(0);
// Create a "class" attribute
var att = document.createAttribute("class");
att.value = "timer_bg";
cell1.setAttributeNode(att);
// Update the count down every 1 second
var x = setInterval(function() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
cell1.innerHTML = days + "d " + hours + "h " + minutes + "m " + seconds + "s"
if (distance < 0) {
clearInterval(x);
document.getElementById("timer").innerHTML = "EXPIRED";
}
}, 1000);
<table id="targetTable">
</table>
I have the following code. I want when this timer expires, another timer should start instead of expired text.
var countDownDate = new Date("Oct 25, 2017 15:37:25").getTime();
var x = setInterval(function() {
var now = new Date().getTime();
var distance = countDownDate - now;
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
document.getElementById("demo").innerHTML = days + " Days " + hours + " Hrs "
+ minutes + " Min " + seconds + " Sec ";
if (distance < 0) {
clearInterval(x);
document.getElementById("demo").innerHTML = "T**imer Expired - instead of this another timer**";
}
}, 1000);
Create a function, and call it every time the timer is finished.
$(document).ready(function() {
var i = 1 ;
setTimer(i) ;
}) ;
function setTimer(i) {
var countDownDate = new Date().getTime() + 3000 ;
var x = setInterval(function() {
var now = new Date().getTime() ;
var distance = countDownDate - now ;
if (distance < 0) {
clearInterval(x);
console.log("Timer " + i + " Finished. New Timer Stated!") ;
setTimer(i+1) ;
}
else {
console.log("Timer " + i + " Running") ;
}
}, 1000);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
This code should do the trick. Each time the counter get to 0, you redefined your count down to the same amount of time there was initially between countDownDate and Now. If this amount is variable, you might modify the assignment of distanceToAdd
// Changed the value to reach for the demo
var countDownDate = new Date().getTime() + 20000;
// Fixed Value to add each time the counter get to 0
var distanceToAdd = countDownDate - new Date().getTime();
var x = setInterval(function() {
var now = new Date().getTime();
var distance = countDownDate - now;
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
if (distance < 0) {
//Add Time to your timer goal instead of canceling interval
countDownDate += distanceToAdd;
}
else {
document.getElementById("demo").innerHTML = days + " Days " + hours + " Hrs "
+ minutes + " Min " + seconds + " Sec ";
}
}, 1000);
<html>
<head>
</head>
<body>
<div id="demo"></div>
</body>
</html>
In the following code I want to make a text input field (for a date) which gets executed so that the countdown timer is set to that value and starts counting - for example after clicking "OK" button. I don't really know how to modify the first variable in order to do that.
<script>
// Set the date we're counting down to
var countDownDate = new Date("May 25, 2018 11:30:00").getTime();
// Update the count down every 1 second
var x = setInterval(function() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Display the result in the element with id="demo"
document.getElementById("demo").innerHTML = "Pozostało: </br>" + days + " Dni, </br>" + hours + "g : " + minutes + "m : " + seconds + "s";
document.getElementById("demo").style.fontSize = "45px";
document.getElementById("demo").style.fontWeight = "bold";
document.getElementById("demo").style.color = "white";
document.getElementById("demo").style.backgroundColor = "#4783bf";
document.getElementById("demo").style.textAlign ="center";
// If the count down is finished, write some text
if (distance < 0) {
clearInterval(x);
document.getElementById("demo").innerHTML = "EXPIRED";
}
}, 1000);
</script>
Thank you for all the advice!
Have a look at this fiddle start timer on click of button
I have entered this date in textbox :- May 26, 2017 01:30:00
function startTimer(){
var dateEntered = document.getElementById("txtDate").value;
// Set the date we're counting down to
//May 26, 2017 01:30:00
var countDownDate = new Date(dateEntered).getTime();
// Update the count down every 1 second
var x = setInterval(function() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Display the result in the element with id="demo"
document.getElementById("demo").innerHTML = "Pozostało: </br>" + days + " Dni, </br>" + hours + "g : " + minutes + "m : " + seconds + "s";
document.getElementById("demo").style.fontSize = "45px";
document.getElementById("demo").style.fontWeight = "bold";
document.getElementById("demo").style.color = "white";
document.getElementById("demo").style.backgroundColor = "#4783bf";
document.getElementById("demo").style.textAlign ="center";
// If the count down is finished, write some text
if (distance < 0) {
clearInterval(x);
document.getElementById("demo").innerHTML = "EXPIRED";
}
}, 1000);
}
<input type="text" id="txtDate"/>
<br>
<input type="button" value="Calculate" onclick="startTimer();">
<div id="demo">
</div>
The first, you need to download datetimepicker library.
https://plugins.jquery.com/datetimepicker/
And then, following this. Remember to change the path of css and jquery files.
<link href="~/css/jquery.datetimepicker.css" rel="stylesheet" />
<body>
<input type="text" id="datetimepicker" />
<input type="button" value="Ok" id="btOk" />
<p id="demo" />
</body>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/jquery.datetimepicker.min.js"></script>
<script type="text/javascript">
$('#datetimepicker').datetimepicker();
$(document).ready(function () {
$('#btOk').click(function () {
var currentDate = $('#datetimepicker').val();
var countDownDate = new Date(currentDate).getTime();
// Update the count down every 1 second
var x = setInterval(function () {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Display the result in the element with id="demo"
document.getElementById("demo").innerHTML = "Pozostało: </br>" + days + " Dni, </br>" + hours + "g : " + minutes + "m : " + seconds + "s";
document.getElementById("demo").style.fontSize = "45px";
document.getElementById("demo").style.fontWeight = "bold";
document.getElementById("demo").style.color = "white";
document.getElementById("demo").style.backgroundColor = "#4783bf";
document.getElementById("demo").style.textAlign = "center";
// If the count down is finished, write some text
if (distance < 0) {
clearInterval(x);
document.getElementById("demo").innerHTML = "EXPIRED";
}
}, 1000);
});
});
</script>