JavaScript counter that continue from where left - javascript

I'm trying to create a countdown counter that should countdown for 24 hours, displaying the days, the hours, the minutes and the seconds. The question is that I want to make it somehow save the progress. For example, I put the countdown to start from now till tomorrow the same time (24 hours) and when a user comes in my site after 2 hours the counter should start from 22 hours for that user and if the user closes the site and then comes back after 2 hours the counter should start from 20 hours for that user. I hope it's clear enough. I found that if that is possible it could be done using cookies, but I'm not sure how it should be done... If anyone could help it will be great! :3
Here is my code so far:
HTML:
<div id="clockdiv">
<span class="days"></span>
<span class="hours"></span>
<span class="minutes"></span>
<span class="seconds"></span>
</div>
JavaScript
// if there's a cookie with the name myClock, use that value as the deadline
if(document.cookie && document.cookie.match('myClock')){
// get deadline value from cookie
var deadline = document.cookie.match(/(^|;)myClock=([^;]+)/)[2];
}
// otherwise, set a deadline 10 minutes from now and
// save it in a cookie with that name
else{
// create deadline 10 minutes from now
var timeInMinutes = 1380;
var currentTime = Date.parse(new Date());
var deadline = new Date(currentTime + timeInMinutes*60*1000);
// store deadline in cookie for future reference
document.cookie = 'myClock=' + deadline + '; path=/; domain=.optic2n.com';
}
function getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.parse(new Date());
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
var days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
function initializeClock(id, endtime) {
var clock = document.getElementById(id);
var daysSpan = clock.querySelector('.days');
var hoursSpan = clock.querySelector('.hours');
var minutesSpan = clock.querySelector('.minutes');
var secondsSpan = clock.querySelector('.seconds');
function updateClock() {
var t = getTimeRemaining(endtime);
daysSpan.innerHTML = t.days;
hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
if (t.total <= 0) {
clearInterval(timeinterval);
}
}
updateClock();
var timeinterval = setInterval(updateClock, 1000);
}
initializeClock('clockdiv', deadline);
Thank you in advance for the help! :3
Best regards,
Tsvetko Krastev

It is possible I have missed something, but your code seems very complex for something so simple. Here is what I came up with:
HTML:
<div id="clockdiv">
<span id="d" class="days"></span>days
<span id="h" class="hours"></span>hrs
<span id="m" class="minutes"></span>mins
<span id="s" class="seconds"></span>secs
</div>
Javascript:
var deadline = localStorage.getItem('dl') ? parseInt(localStorage.getItem('dl')) : (Date.now() + 86400000);
var delay = null;
// Good spot to do checks for 24hrs has passed already here
localStorage.setItem('dl',deadline);
function render() {
if (delay) {
clearTimeout(delay);
delay = null;
}
var diff = (deadline - Date.now()) / 1000;
document.getElementById('d').innerHTML = Math.floor(diff / 86400);
document.getElementById('h').innerHTML = Math.floor(diff / 3600);
document.getElementById('m').innerHTML = Math.floor((diff / 60) % 60);
document.getElementById('s').innerHTML = Math.floor(diff % 60);
delay = setTimeout(render,1000);
}
render();
NOTE: There are no checks for what to do after 24 hours.

Related

How to avoid negative value in clock counter

I have made a countdown clock for quiz module so whenever the counter ends up I get a negative value. After the end of the timer I am getting -1 :-1 and I want it as 00:00.
I thought there would be an error in the total time but I am not able to figure out the error
I have tried this logic but it's not working
<script>
function getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.parse(new Date());
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
var days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
function initializeClock(id, endtime) {
var clock = document.getElementById(id);
var minutesSpan = clock.querySelector('.minutes');
var secondsSpan = clock.querySelector('.seconds');
function updateClock() {
var t = getTimeRemaining(endtime);
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
if($('.minutes').text() == '00' && $('.seconds').text() == '00')
{
if(score == 0)
{
// Wrap every letter in a span
document.getElementById("congrats").innerHTML = "Better Luck Next time"; //When all the words are solved, greeting is displayed
document.getElementById("part1").hidden = false;
document.getElementById("goodjob").hidden = false;
document.getElementById("part2").hidden = false;
document.getElementById("button5").disabled = true;
document.getElementById("totscore").innerHTML = "Total correct answer " + score;
document.getElementById("totcoins").innerHTML = "Total coins achieved " + score;
document.getElementById("coins").hidden = false;
document.getElementById("my_audio").pause();
setTimeout(function(){
document.getElementById("drop").play();
}, 1000)
}
else if(score == 5){
document.getElementById("congrats").innerHTML = "Congratulations You solved all three piece words"; //When all the words are solved, greeting is displayed
document.getElementById("part1").hidden = false;
document.getElementById("goodjob").hidden = false;
document.getElementById("part2").hidden = false;
document.getElementById("totscore").innerHTML = "Total correct answer " + score;
document.getElementById("totcoins").innerHTML = "Total coins achieved " + score;
document.getElementById("coins").hidden = false;
document.getElementById("my_audio").pause();
setTimeout(function(){
document.getElementById("drop").play();
}, 1000)
}
}
if (t.total <= 0) {
clearInterval(timeinterval);
}
}
updateClock();
var timeinterval = setInterval(updateClock, 1000);
}
var deadline = new Date(Date.parse(new Date()) + 20 * 1000);
initializeClock('clockdiv', deadline);
</script>
My HTML Code
<nav class="navbar navbar-light bg-light fixed-top">
<div class="row" style="width:100%">
<div class="col-md-6">
<div id="clockdiv">
<div>
<span class="minutes"></span>
<div class="smalltext">Minutes</div>
</div>
<div>
<span class="seconds"></span>
<div class="smalltext">Seconds</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="score-box" id="scoring">
Your Score is 0
</div>
</div>
</div>
</nav>
Your function runs once more after reaching 0, thus resulting in -1.
You can fix it quickly by making a check in the function to get the remaining time:
function getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.parse(new Date());
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
var days = Math.floor(t / (1000 * 60 * 60 * 24));
minutes = minutes < 0? 0 : minutes; //Check if they are lower than 0, if yes, set them to 0
seconds = seconds < 0? 0 : seconds;
return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
First of all, don't use the string you put in the html to verify a number, use actual numbers. I'm referring to
if($('.minutes').text() == '00' && $('.seconds').text() == '00')
Avoid doing this.
You put a value inside the object you return from getTimeRemaining that represent the actual difference in milliseconds between the dates. Why not use that?
if (t.total <= 0) {
...
}
You need to check this before you put the time in the HTML.
EDIT: you're actually doing this at the end of updateClock, just check it before printing, and if <= 0 manually set the html to read 00:00.
function updateClock() {
var t = getTimeRemaining(endtime);
if (t.total <= 0) {
clearInterval(timeinterval);
minutesSpan.innerHTML = '00';
secondsSpan.innerHTML = '00';
if(score == 0) {
...
}
....
} else {
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
}
}

js countdown clock reloads every time browser is refreshed, how can I prevent this?

The following code produces a countdown clock for 15 days and counts down day, hour, minute, second. But, every time the browser is reloaded the clock restarts? What do I need to to do to change this?
<script>function
getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.parse(new Date());
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
var days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
function initializeClock(id, endtime) {
var clock = document.getElementById(id);
var daysSpan = clock.querySelector('.days');
var hoursSpan = clock.querySelector('.hours');
var minutesSpan = clock.querySelector('.minutes');
var secondsSpan = clock.querySelector('.seconds');
function updateClock() {
var t = getTimeRemaining(endtime);
daysSpan.innerHTML = t.days;
hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
if (t.total <= 0) {
clearInterval(timeinterval);
}
}
updateClock();
var timeinterval = setInterval(updateClock, 1000);
}
var deadline = new Date(Date.parse(new Date()) + 15 * 24 * 60 * 60 * 1000);
initializeClock('clockdiv', deadline);</script>
var deadline = new Date(Date.parse(new Date()) + 15 * 24 * 60 * 60 * 1000); this is not a static/const value. it's changing every time page load. so you have to find a way to have a static endTime value. as #de-bugged said you can get that either server-side or store in local storage or use const variable
like : const endTime = "Thu Jul 26 2018 11:11:38 GMT+0530 (India Standard Time)";
or like : const endTime = 1532583817343 //timestamp
Here is an example of how you can do it. Do not use this code though. Its not meant for production :)
I used localstorage here but you can also use session storage, cookies, server side solutions, and const
<div id="clockdiv">
<span class="days"></span>
<span class="hours"></span>
<span class="minutes"></span>
<span class="seconds"></span>
</div>
<script>function
getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.parse(new Date());
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
var days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
function initializeClock(id, endtime) {
var clock = document.getElementById(id);
var daysSpan = clock.querySelector('.days');
var hoursSpan = clock.querySelector('.hours');
var minutesSpan = clock.querySelector('.minutes');
var secondsSpan = clock.querySelector('.seconds');
function updateClock() {
var t = getTimeRemaining(endtime);
daysSpan.innerHTML = t.days;
hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
if (t.total <= 0) {
clearInterval(timeinterval);
}
}
updateClock();
var timeinterval = setInterval(updateClock, 1000);
}
var deadLineTime = parseInt(localStorage.getItem('deadLineTime')) || false;
if(!deadLineTime){
deadLineTime = Date.parse(new Date()) + 15 * 24 * 60 * 60 * 1000;
localStorage.setItem('deadLineTime', deadLineTime);
}
var deadline = new Date(deadLineTime2);
initializeClock('clockdiv', deadline);
</script>

cookie in javascript restarts after each refresh

I am using this timer on each of my product pages: http://www.screencast.com/t/hsmzVOLBUJ
and example of product page URL:
https://www.tresor-ethnique.com/collections/celtique/products/pendentif-chene-millenaire
It starts at 12hrs 4mn 26s and then decreases.
I would like it to be set with a cookie so that when the user navigates between different product pages, it keeps decreasing from the value of other pages ; and also if the user comes back in 12hrs, it displays 0hrs 4mn 26s.
So I am a bit unfamiliar with the integration of cookie in javascript, this would appear in the end of my code there:
document.cookie = 'myClock='
So far, the timer resets after each refresh
Do you have any idea to prevent that?
This would be a great help, thank you very much :)
<div id="clockdiv">
<span class="days"></span><div class="smalltext">jours</div>
<span class="hours"></span><div class="smalltext">hrs</div>
<span class="minutes"></span><div class="smalltext">mins</div>
<span class="seconds"></span><div class="smalltext">secs</div>
</div>
<script type="text/javascript">
function getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.parse(new Date());
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
var days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
function initializeClock(id, endtime) {
var clock = document.getElementById(id);
var daysSpan = clock.querySelector('.days');
var hoursSpan = clock.querySelector('.hours');
var minutesSpan = clock.querySelector('.minutes');
var secondsSpan = clock.querySelector('.seconds');
function updateClock() {
var t = getTimeRemaining(endtime);
daysSpan.innerHTML = t.days;
hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
if (t.total <= 0) {
clearInterval(timeinterval);
}
}
updateClock();
var timeinterval = setInterval(updateClock, 1000);
}
var currentTime = Date.parse(new Date());
if(document.cookie && document.cookie.match('myClock')){
var deadline = document.cookie.match(/(^|;)myClock=([^;]+)/)[2];
}
else{
var timeInHours = 12;
var timeInMinutes = 4;
var timeInSeconds = 26;
var currentTime = Date.parse(new Date());
var deadline = new Date(currentTime + timeInHours*60*60*1000 + timeInMinutes*60*1000 + timeInSeconds*1000);
document.cookie = 'myClock=' + deadline + '; path=/; domain= .https://www.tresor-ethnique.com/';
initializeClock('clockdiv', deadline);
}
</script>

Countdown Timer Using the Server Time PHP and Laravel

I have a simple JS code to do countdown on the Client browser but there is a short coming the timer depends on the client machine so i want to get the Current Time and elapsed time from the Server.
Below is my working but it doesn't work.
function getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.parse(current_time);
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
var days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
function initializeClock(id, endtime, current_time) {
var clock = document.getElementById(id);
var daysSpan = clock.querySelector('.days');
var hoursSpan = clock.querySelector('.hours');
var minutesSpan = clock.querySelector('.minutes');
var secondsSpan = clock.querySelector('.seconds');
function updateClock() {
var t = getTimeRemaining(endtime, current_time);
daysSpan.innerHTML = t.days;
hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
if (t.total <= 0) {
clearInterval(timeinterval);
$('#clockdiv').html('You can\'t Reserve anymore')
}
}
updateClock();
var timeinterval = setInterval(updateClock, 1000);
}
var deadline = '2017-02-24 18:12:29';
var current_time = new EventSource('Server/script/example.php');
current_time.onopen = function(event) {
//console.log(event)
current_time.onmessage = function(event)
{
return event.data;
}
current_time.onerror = function (error) {
//console.log('we have an error')
}
}
console.log(current_time)
initializeClock('clockdiv', deadline, current_time);
So am trying to use HTML SSE server Sent Event so as Listen to response instead of making the request.
current_time variable is empty and the output of the Time is NAN NAN NAN
So is there a better of achieving the above or can some work this code for me.

How do you integrate a javascript timer to countdown to count from a ruby variable?

I am working on a really simple ruby on rails app. I am trying to build a workout timer. There is a Workout resource with a duration attribute. The user can choose to set the workout to 15 or 30 minutes.
I have a Javascript code that counts down for the duration. I can't figure out how to set the timer to countdown from the workout.duration.
This is the Ruby that will put out a duration in minutes.
Total workout time: <%= #workout.duration %>
Where or how do I pass this variable in the Javascript code? This is the Javascript that counts down:
<script>
function getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.parse(new Date());
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
return {
'total': t,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
function initializeClock(id, endtime) {
var clock = document.getElementById(id);
var hoursSpan = clock.querySelector('.hours');
var minutesSpan = clock.querySelector('.minutes');
var secondsSpan = clock.querySelector('.seconds');
function updateClock() {
var t = getTimeRemaining(endtime);
hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
if (t.total <= 0) {
clearInterval(timeinterval);
}
}
updateClock();
var timeinterval = setInterval(updateClock, 1000);
}
var timeInSeconds = 30;
var currentTime = Date.parse(new Date());
var deadline = new Date(currentTime + timeInSeconds*1000);
initializeClock('clockdiv', deadline);
</script>
And this is the HTML:
<h1>Timer</h1>
<div id="clockdiv">
<div>
<span class="hours"></span>
<div class="smalltext">Hours</div>
</div>
<div>
<span class="minutes"></span>
<div class="smalltext">Minutes</div>
</div>
<div>
<span class="seconds"></span>
<div class="smalltext">Seconds</div>
</div>
</div>
You can rename the .js file to .erb.js to enable embedded ruby templating. Then you can use the <%= %> syntax like you would in an HTML template:
var timeInSeconds = parseInt(<%= 30 %>);
For the purposes of this answer, I'm going to assume that this is called from the WorkoutController, and that this timer applies to the show view.
You can put the static Javascript functions in app/assets/javascripts/workout.js, and it will be included in your asset pipeline:
function getTimeRemaining(endtime) {
var t = Date.parse(endtime) - Date.parse(new Date());
var seconds = Math.floor((t / 1000) % 60);
var minutes = Math.floor((t / 1000 / 60) % 60);
var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
return {
'total': t,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
}
function initializeClock(id, endtime) {
var clock = document.getElementById(id);
var hoursSpan = clock.querySelector('.hours');
var minutesSpan = clock.querySelector('.minutes');
var secondsSpan = clock.querySelector('.seconds');
function updateClock() {
var t = getTimeRemaining(endtime);
hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
if (t.total <= 0) {
clearInterval(timeinterval);
}
}
updateClock();
var timeinterval = setInterval(updateClock, 1000);
}
You can add the dynamic Javascript to the end of the HTML in app/views/workouts/show.html.erb:
<h1>Timer</h1>
<div id="clockdiv">
<div>
<span class="hours"></span>
<div class="smalltext">Hours</div>
</div>
<div>
<span class="minutes"></span>
<div class="smalltext">Minutes</div>
</div>
<div>
<span class="seconds"></span>
<div class="smalltext">Seconds</div>
</div>
</div>
<script>
var timeInSeconds = <%= #workout.duration * 60 %>;
var currentTime = Date.parse(new Date());
var deadline = new Date(currentTime + timeInSeconds*1000);
initializeClock('clockdiv', deadline);
</script>
Technically, since only timeInSeconds is variable, you could convert the other lines into a static Javascript function and include it in app/assets/javascripts/workout.js, as well:
function deadlineFromMinutes(minutes) {
var currentTime = Date.parse(new Date());
return new Date(currentTime + timeInSeconds*1000);
}
and change the <script></script> snippet in app/views/workouts/show.html.erb to look like this:
<script>
initializeClock('clockdiv', deadlineFromMinutes(<%= #workout.duration %>)
</script>
This will keep the dynamic parts cleanly separated from the static parts, which will save a little page render time, and make more of the Javascript code reusable with other parts of the application.
And that's all there is to using a combination of static and dynamic Javascript from within your application.

Categories

Resources