Integrating Timezones into my jquery countdown - javascript

I've searched all over the web, and all I'm getting is results to make new countdowns and not integrate in timezones into my jquery countdown which isn't what I'm looking for, since I'm looking to integrate the new js into my current countdown design.
Below is my js and html code I currently have which counts down from the users computer time, not from a specific timezone time.
Can someone tell me what code to input to make it based on a specified time zone (eg +8:00)
Thanks in advance:
HTML:
<div id="counter" class="counter" data-date="July 13, 2015">
<div class="timer-col"> <span id="days"></span> <span class="timer-type">d</span> </div>
<div class="timer-col"> <span id="hours"></span> <span class="timer-type">h</span> </div>
<div class="timer-col"> <span id="minutes"></span> <span class="timer-type">m</span> </div>
<div class="timer-col"> <span id="seconds"></span> <span class="timer-type">s</span> </div>
</div>
JS:
(function($) {
$.fn.countdown = function(toDate, callback) {
var handlers = ['seconds', 'minutes', 'hours', 'days', 'weeks', 'daysLeft'];
function delegate(scope, method) {
return function() { return method.call(scope) }
}
return this.each(function() {
// Convert
if(!(toDate instanceof Date)) {
if(String(toDate).match(/^[0-9]*$/)) {
toDate = new Date(toDate);
} else if( toDate.match(/([0-9]{1,2})\/([0-9]{1,2})\/([0-9]{2,4})\s([0-9]{1,2})\:([0-9]{2})\:([0-9] {2})/) ||
toDate.match(/([0-9]{2,4})\/([0-9]{1,2})\/([0-9]{1,2})\s([0-9]{1,2})\:([0-9]{2})\:([0-9]{2})/)
) {
toDate = new Date(toDate);
} else if(toDate.match(/([0-9]{1,2})\/([0-9]{1,2})\/([0-9]{2,4})/) ||
toDate.match(/([0-9]{2,4})\/([0-9]{1,2})\/([0-9]{1,2})/)
) {
toDate = new Date(toDate)
} else {
throw new Error("Doesn't seen to be a valid date object or string")
}
}
var $this = $(this),
values = {},
lasting = {},
interval = $this.data('countdownInterval'),
currentDate = new Date(),
secondsLeft = Math.floor((toDate.valueOf() - currentDate.valueOf()) / 1000);
function triggerEvents() {
secondsLeft--;
if(secondsLeft < 0) {
secondsLeft = 0;
}
lasting = {
seconds : secondsLeft % 60,
minutes : Math.floor(secondsLeft / 60) % 60,
hours : Math.floor(secondsLeft / 60 / 60) % 24,
days : Math.floor(secondsLeft / 60 / 60 / 24),
weeks : Math.floor(secondsLeft / 60 / 60 / 24 / 7),
daysLeft: Math.floor(secondsLeft / 60 / 60 / 24) % 7
}
for(var i=0; i<handlers.length; i++) {
var eventName = handlers[i];
if(values[eventName] != lasting[eventName]) {
values[eventName] = lasting[eventName];
dispatchEvent(eventName);
}
}
if(secondsLeft == 0) {
stop();
dispatchEvent('finished');
}
}
triggerEvents();
function dispatchEvent(eventName) {
var event = $.Event(eventName);
event.date = new Date(new Date().valueOf() + secondsLeft);
event.value = values[eventName] || "0";
event.toDate = toDate;
event.lasting = lasting;
switch(eventName) {
case "seconds":
case "minutes":
case "hours":
event.value = event.value < 10 ? '0'+event.value.toString() : event.value.toString();
break;
default:
if(event.value) {
event.value = event.value.toString();
}
break;
}
callback.call($this, event);
}
$this.bind('remove', function() {
stop(); // If the selector is removed clear the interval for memory sake!
dispatchEvent('removed');
});
function stop() {
clearInterval(interval);
}
function start() {
$this.data('countdownInterval', setInterval(delegate($this, triggerEvents), 1000));
interval = $this.data('countdownInterval');
}
if(interval) stop();
start();
});
}
// Wrap the remove method to trigger an event when called
var removeEvent = new $.Event('remove'),
removeFunction = $.fn.remove;
$.fn.remove = function() {
$(this).trigger(removeEvent);
return removeFunction.apply(this, arguments);
}
})(jQuery);

Related

Pause and Resume the counting values from localstorage

I am using this code for countdown timer to a quiz test. Its working Fine. In this I need to add two buttons one is Pause button and another one is Resume button. When I click a Pause button it's stop time and when I click a Resume button it's start from where I pause the time.
I have tried this code. It's not working.
HTML Code
<div class="div__time">
<div style="display: none;" id="overall_time"></div>
<div id="overall_times"></div>
<div class="total_time"></div>
</div>
<input id="pauseButton" type="button" value="Pause">
<input id="resumeButton" type="button" value="Resume">
JS Code
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js" type="text/javascript"></script>
<script>
var speaking_ms = "00:00:10";
var speaking_ms_arr = speaking_ms.split(":");
var speaking_time_min_sec = (+speaking_ms_arr[0]) * 60 * 60 + (+speaking_ms_arr[1]) * 60 + (+speaking_ms_arr[2]);
var speaking_time_min_sec = parseInt(speaking_time_min_sec) + 1;
var speaking_value;
if (localStorage.getItem("speaking_counter")) {
if (localStorage.getItem("speaking_counter") <= 0) {
speaking_value = speaking_time_min_sec;
} else {
speaking_value = localStorage.getItem("speaking_counter");
}
} else {
speaking_value = speaking_time_min_sec;
}
document.getElementById('overall_time').innerHTML = speaking_value;
var speaking_counter = function() {
if (speaking_value <= 0) {
localStorage.setItem("speaking_counter", speaking_time_min_sec);
} else {
speaking_value = parseInt(speaking_value) - 1;
localStorage.setItem("speaking_counter", speaking_value);
}
document.getElementById('overall_time').innerHTML = speaking_value;
if (speaking_value == 0) {
localStorage.setItem("speaking_counter", speaking_value);
setTimeout(function() {
clearInterval(interval);
}, 1000);
}
var hours = Math.floor(speaking_value / 3600);
var minutes = Math.floor(speaking_value % 3600 / 60);
var seconds = Math.floor(speaking_value % 3600 % 60);
var red_time = hours + ' : ' + minutes + ' : ' + seconds;
document.getElementById('overall_times').innerHTML = red_time;
};
var interval = setInterval(function() {
speaking_counter();
}, 1000);
var Clock = {
pause: function() {
clearInterval(this.interval);
delete this.interval;
},
resume: function() {
if (!this.interval) this.start();
}
};
$('#pauseButton').click(function() { Clock.pause(); });
$('#resumeButton').click(function() { Clock.resume(); });
</script>
Fiddle Link
Thanks in Advance.
I changed the end of the code in the fiddle and it worked: https://jsfiddle.net/bohv0j9w/5/
var Clock = {
pause: function() {
clearInterval(interval);
interval = null;
},
resume: function() {
if (!interval) interval = setInterval(speaking_counter, 1000);
}
};
document.querySelector('#pauseButton').addEventListener("click", Clock.pause);
document.querySelector('#resumeButton').addEventListener("click", Clock.resume);
In your version this.internal is undefined you may want to learn about "this" and scopes in js. And $(...) is a syntax that requires the lib jquery (not included in the fiddle), the vanilla js equivalent is "document.querySelector", you should read the MDN article about this function.
Finally, your syntax is a bit old school. If you use localStorage you aren't targeting very old browsers maybe you should avoid jquery and use keywords such as "const".
Following are your mistakes. (Fiddle link)
var Clock = {
pause: function() {
clearInterval(this.interval);//(this.interval is undefined, replace it with interval)
^^^^
delete this.interval;//(this.interval is undefined, replace it with interval)
^^^^
},
resume: function() {
if (!this.interval) this.start();//(this.interval is undefined, replace it typeof interval === undefined to check whether interval exists or not)
^^^^
^^^^^^^^^^^ //(this.start() is also not defined, replace it with start() and move `var interval = setInterval(fun.....` into new start function)
}
};
look at following code.
var speaking_ms = "00:00:10";
var speaking_ms_arr = speaking_ms.split(":");
var speaking_time_min_sec = (+speaking_ms_arr[0]) * 60 * 60 + (+speaking_ms_arr[1]) * 60 + (+speaking_ms_arr[2]);
var speaking_time_min_sec = parseInt(speaking_time_min_sec) + 1;
var speaking_value;
if (localStorage.getItem("speaking_counter")) {
if (localStorage.getItem("speaking_counter") <= 0) {
speaking_value = speaking_time_min_sec;
} else {
speaking_value = localStorage.getItem("speaking_counter");
}
} else {
speaking_value = speaking_time_min_sec;
}
document.getElementById('overall_time').innerHTML = speaking_value;
var speaking_counter = function() {
if (speaking_value <= 0) {
localStorage.setItem("speaking_counter", speaking_time_min_sec);
} else {
speaking_value = parseInt(speaking_value) - 1;
localStorage.setItem("speaking_counter", speaking_value);
}
document.getElementById('overall_time').innerHTML = speaking_value;
if (speaking_value == 0) {
localStorage.setItem("speaking_counter", speaking_value);
setTimeout(function() {
clearInterval(interval);
}, 1000);
}
var hours = Math.floor(speaking_value / 3600);
var minutes = Math.floor(speaking_value % 3600 / 60);
var seconds = Math.floor(speaking_value % 3600 % 60);
var red_time = hours + ' : ' + minutes + ' : ' + seconds;
document.getElementById('overall_times').innerHTML = red_time;
};
var start = function() {
interval = setInterval(function() {
speaking_counter();
}, 1000);
}
var Clock = {
pause: function() {
clearInterval(interval);
delete interval;
},
resume: function() {
if (typeof interval === 'undefined') start();
}
};
$('#pauseButton').click(function() { Clock.pause(); });
$('#resumeButton').click(function() { Clock.resume(); });
start();
I have fixed your solution and implemented what you were trying to implement. There were minor issues with your solution which i fixed.
1. You were using this to access interval variable that was not part of the clock object in which you were accessing the variable.
2. You were using this.start() function in the resume function of clock object which was not part of the clock object.
3. JQuery used to define events was not included in the fiddle. Although it is included in the code pasted in the question.
html:
<html>
<head>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
</head>
<body>
<div class="div__time">
<div style="display: none;" id="overall_time"></div>
<div id="overall_times"></div>
<div class="total_time"></div>
</div>
<input id="pauseButton" type="button" value="Pause">
<input id="resumeButton" type="button" value="Resume">
</body>
js:
var speaking_ms = "00:00:10";
var speaking_ms_arr = speaking_ms.split(":");
var speaking_time_min_sec = (+speaking_ms_arr[0]) * 60 * 60 + (+speaking_ms_arr[1]) * 60 + (+speaking_ms_arr[2]);
var speaking_time_min_sec = parseInt(speaking_time_min_sec) + 1;
var speaking_value;
if (localStorage.getItem("speaking_counter")) {
if (localStorage.getItem("speaking_counter") <= 0) {
speaking_value = speaking_time_min_sec;
} else {
speaking_value = localStorage.getItem("speaking_counter");
}
} else {
speaking_value = speaking_time_min_sec;
}
document.getElementById('overall_time').innerHTML = speaking_value;
var speaking_counter = function() {
if (speaking_value <= 0) {
localStorage.setItem("speaking_counter", speaking_time_min_sec);
} else {
speaking_value = parseInt(speaking_value) - 1;
localStorage.setItem("speaking_counter", speaking_value);
}
document.getElementById('overall_time').innerHTML = speaking_value;
if (speaking_value == 0) {
localStorage.setItem("speaking_counter", speaking_value);
setTimeout(function() {
clearInterval(interval);
}, 1000);
}
var hours = Math.floor(speaking_value / 3600);
var minutes = Math.floor(speaking_value % 3600 / 60);
var seconds = Math.floor(speaking_value % 3600 % 60);
var red_time = hours + ' : ' + minutes + ' : ' + seconds;
document.getElementById('overall_times').innerHTML = red_time;
};
var interval = setInterval(function() {
speaking_counter();
}, 1000);
var Clock = {
pause: function() {
clearInterval(interval);
delete interval;
},
resume: function() {
interval = setInterval(function() {
speaking_counter();
}, 1000);
}
};
$('#pauseButton').click(function() { Clock.pause(); });
$('#resumeButton').click(function() { Clock.resume(); });
Here is the fiddle link: JS Fiddle
You have gotten quite a few answers so far, I wanted to give you another example so that you have an alternative architecture to consider. Definitely read up on scopes and closures and the use of this. Also, you don't need jQuery for this function. Only import a large library like jQuery when you need it. In this case document.getElementById does you well, as does addEventListener.
There are even more exciting ways to handle a countdown (including the use of recursion), but below is an example of envisioning your Clock as a single object. This gives you greater control over the clock and it makes it reusable.
You can define functions on the clock that manage the interval, decrement the countdown, pause, resume, start and reset the clock. I added buttons for each so you can see how it would work. Also note that I commented out localStorage to show that it works without storage, but mainly because the snippets in StackOverflow aren't given permission to use localStorage so it would crash, but you can run this code here as is.
var Clock = {
speaking_value: 10,
interval: -1,
countdown: function() {
speaking_value = this.speaking_value;
if (speaking_value <= 0) {
//localStorage.setItem("speaking_counter", 0);
} else {
speaking_value = parseInt(speaking_value) - 1;
//localStorage.setItem("speaking_counter", speaking_value);
}
document.getElementById('overall_time').innerHTML = speaking_value;
if (speaking_value == 0) {
//localStorage.setItem("speaking_counter", speaking_value);
var self = this;
setTimeout(function() {
clearInterval(self.interval);
}, 1000);
}
this.speaking_value = speaking_value;
this.updateClock();
},
paused: false,
pause: function() {
clearInterval(this.interval);
this.paused = true;
},
resume: function() {
if (this.paused) {
this.paused = false;
this.tick();
}
},
updateClock: function() {
speaking_value = this.speaking_value;
var hours = Math.floor(speaking_value / 3600);
var minutes = Math.floor(speaking_value % 3600 / 60);
var seconds = Math.floor(speaking_value % 3600 % 60);
var red_time = hours + ' : ' + minutes + ' : ' + seconds;
document.getElementById('overall_times').innerHTML = red_time;
},
tick: function() {
var self = this;
this.interval = setInterval(function() {
self.countdown()
}, 1000)
},
start: function() {
this.updateClock();
this.tick();
},
reset: function(){
clearInterval(this.interval);
this.speaking_value = 10;
this.updateClock();
}
};
Clock.updateClock();
document.getElementById('startButton').addEventListener('click', function() { Clock.start(); });
document.getElementById('pauseButton').addEventListener('click', function() { Clock.pause(); });
document.getElementById('resumeButton').addEventListener('click', function() { Clock.resume(); });
document.getElementById('resetButton').addEventListener('click', function() { Clock.reset(); });
<div class="div__time">
<div style="display: none;" id="overall_time"></div>
<div id="overall_times"></div>
<div class="total_time"></div>
</div>
<input id="startButton" type="button" value="Start">
<input id="pauseButton" type="button" value="Pause">
<input id="resumeButton" type="button" value="Resume">
<input id="resetButton" type="button" value="Reset">

How to redirect the countdown of the jCounter plugin after the end only once, without infinite loop?

I'm using the Jcounter plugin http://devingredients.com/jcounter/ on a project, it's perfect for what I need, except for a problem I'm facing. I need it when I finish the countdown, it updates the same page only once, without giving infinite loop. How can I do this?
The callback function seems to give this possibilide, would I need some control? I have little experience in jquery.
<!DOCTYPE html>
<html>
<head>
<title>jCounter - jQuery plugin - devingredients.com</title>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
<link rel="stylesheet" type="text/css" href="css/jquery.jCounter-iosl.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery.jCounter-0.1.4.js"></script>
<script type="text/javascript">
$(document).ready(function() {
//first counter
$(".countdown1").jCounter({
animation: "slide",
date: "2017/10/13 19:53:20",
format: "dd:hh:mm:ss",
twoDigits: 'on',
callback: function() {
window.location.href = "index.php?block=Yes"
}
});
});
</script>
<div class="iosl-theme-wrapper countdown1">
<div class="iosl-theme">
<ul>
<li><p><span><em><b class="days">00</b><i class="daysSlider"><u>00</u><u>00</u></i></em></span></p></li>
<li><p><span><em><b class="hours">00</b><i class="hoursSlider"><u>00</u><u>00</u></i></em></span></p></li>
<li><p><span><em><b class="minutes">00</b><i class="minutesSlider"><u>00</u><u>00</u></i></em></span></p></li>
<li><p><span><em><b class="seconds">00</b><i class="secondsSlider"><u>00</u><u>00</u></i></em></span></p></li>
</ul>
<div class="jC-clear"></div>
<p class="jCtext">
<span><em class="textSeconds">SEGUNDOS</em></span>
<span><em class="textMinutes">MINUTOS</em></span>
<span><em class="textHours">HORAS</em></span>
<span><em class="textDays">DIAS</em></span>
</p>
<div class="jC-clear"></div>
</div>
</div>
**jquery.jCounter-0.1.4.js**
/**********************************
* jCounter Script v0.1.4 (beta)
* Author: Catalin Berta
* Official page and documentation: http://devingredients.com/jcounter
* Licensed under the MIT license
**********************************/
;(function($,document,window,undefined) {
//once upon a time...
$.fn.jCounter = function(options,callback) {
var jCounterDirection = 'down'; // points out whether it should count down or up | handled via customRange setting
var customRangeDownCount; //if true, it will tell countdown_proc() it's a down count and not an up count
var days,hours,minutes,seconds;
var endCounter = false; //stops jCounter if true
var eventDate; //time target (holds a number of seconds)
var pausedTime; //stores the time (in seconds) when pausing
var thisEl = this; //custom 'this' selector
var thisLength = this.length; //number of multiple elements per selector
var pluralLabels = new Array('DAYS','HOURS','MINUTES','SECONDS'); //plural labels - used for localization
var singularLabels = new Array('DAY','HOUR','MINUTE','SECOND'); //singular labels - used for localization
this.options = options; //stores jCounter's options parameter to verify against specified methods
this.version = '0.1.4';
//default settings
var settings = {
animation: null,
callback: null,
customDuration: null,
customRange: null,
date: null,
debugLog: false,
serverDateSource: 'dateandtime.php', //path to dateandtime.php file (i.e. http://my-domain.com/dateandtime.php)
format: 'dd:hh:mm:ss',
timezone: 'Europe/London',
twoDigits: 'on'
};
//merge the settings with the options values
if (typeof options === 'object') {
$.extend(settings,options);
thisEl.data("userOptions", settings); //push the settings to applied elements (they're used by methods)
}
if(thisEl.data('userOptions').debugLog == true && window['console'] !== undefined ) {
var consoleLog = true; //shows debug messages via console.log() if true
}
//METHODS
var jC_methods = {
//initialize
init : function() {
thisEl.each(function(i,el) {
initCounter(el);
});
},
//pause method: $.jCounter('pause')
pause : function() {
if(consoleLog) { console.log("(jC) Activity: Counter paused."); }
endCounter = true;
return thisEl.each(function(i,el) {
clearInterval($(el).data("jC_interval"));
});
},
//stop method: $.jCounter('stop')
stop : function() {
if(consoleLog) { console.log("(jC) Activity: Counter stopped."); }
endCounter = true;
return thisEl.each(function(i,el) {
clearInterval($(el).data("jC_interval"));
$(el).removeData("jC_pausedTime");
resetHTMLCounter(el);
});
},
//reset method: $.jCounter('reset')
reset : function() {
if(consoleLog) { console.log("(jC) Activity: Counter reset."); }
return thisEl.each(function(i,el) {
clearInterval($(el).data("jC_interval"));
resetHTMLCounter(el);
initCounter(el);
});
},
//start method: $.jCounter('start')
start : function() {
if(consoleLog) { console.log("(jC) Activity: Counter started."); }
return thisEl.each(function(i,el) {
pausedTime = $(el).data("jC_pausedTime");
endCounter = false;
clearInterval($(el).data("jC_interval"));
initCounter(el);
});
}
}
//checks whether customDuration is used
if(thisEl.data("userOptions").customDuration) {
if(!isNaN(thisEl.data("userOptions").customDuration)) {
var customDuration = true;
} else {
var customDuration = false;
if(consoleLog) { console.log("(jC) Error: The customDuration value is not a number! NOTE: 'customDuration' accepts a number of seconds."); }
}
}
//checks whether customRange is used
if(thisEl.data("userOptions").customRange) {
var customRangeValues = thisEl.data("userOptions").customRange.split(":");
var rangeVal0 = parseInt(customRangeValues[0]);
var rangeVal1 = parseInt(customRangeValues[1]);
if(!isNaN(rangeVal0) && !isNaN(rangeVal1)) {
var customRange = true;
if(rangeVal0 > rangeVal1) {
var customRangeDownCount = true;
} else {
var customRangeDownCount = false;
jCounterDirection = 'up';
}
} else {
var customRange = false;
if(consoleLog) { console.log("(jC) Error: The customRange value is not a valid range! Example: customRange: '0:30' or '30:0'"); }
}
}
//checks whether animation is set to slide
if(thisEl.data("userOptions").animation == 'slide') {
thisEl.data("jCanimation","slide");
}
//FUNCTIONS
//jCounter initializer
function initCounter(el) {
if(customDuration) {
if (pausedTime) {
if (!isNaN(pausedTime)) {
eventDate = Math.round(pausedTime);
}
} else {
eventDate = Math.round($(el).data("userOptions").customDuration);
}
currentTime = 0;
countdown_proc(currentTime,el);
$(el).data("jC_interval", setInterval(function(){
if(endCounter == false) {
currentTime = parseInt(currentTime) + 1;
countdown_proc(currentTime,el)
}
},1000));
} else if(customRange) {
eventDate = Math.round(customRangeValues[1]);
if (pausedTime) {
if (!isNaN(pausedTime)) {
var currentTime = eventDate - pausedTime;
}
} else {
var currentTime = Math.round(customRangeValues[0]);
}
countdown_proc(currentTime,el);
$(el).data("jC_interval", setInterval(function(){
if(endCounter == false) {
var ifRangeDownCount = (customRangeDownCount) ? currentTime = parseInt(currentTime) - 1 : currentTime = parseInt(currentTime) + 1;
countdown_proc(currentTime,el);
}
},1000));
} else {
eventDate = Date.parse($(el).data("userOptions").date) / 1000;
dateSource = thisEl.data("userOptions").serverDateSource + '?timezone=' + thisEl.data("userOptions").timezone + '&callback=?';
$.ajax({
url: dateSource,
dataType : 'json',
data : {},
success : function(data, textStatus){
var currentDate = Date.parse(data.currentDate) / 1000;
startCounter(currentDate,el);
},
error : function(){
if(consoleLog) { console.log("(jC) Error: Couldn't find dateandtime.php from serverDateSource: " + thisEl.data('userOptions').serverDateSource + "\n(jC) - Make sure the path is correct! \n(jC) - Now using the client-side time (not recommended).") }
var currentDate = Math.floor($.now() / 1000);
startCounter(currentDate,el);
}
});
}
}
function startCounter(currentDate,el) {
countdown_proc(currentDate,el);
if (eventDate > currentDate) {
$(el).data("jC_interval", setInterval(function(){
if(endCounter == false) {
currentDate = parseInt(currentDate) + 1;
countdown_proc(currentDate,el)
}
},1000));
} else {
resetHTMLCounter(el)
}
}
//jCslider - adds the slide effect layer
//Note: this requires a jCounter slide-ready theme! (i.e. iOS dark or iOS light)
function jCslider(el,unitClass,timeUnit,eventDate,duration) {
$(el).find(unitClass + " u").each(function(i,el) {
var twoDigits = (thisEl.data("userOptions").twoDigits == 'on') ? '0' : '';
var newIndex = (jCounterDirection == 'up') ? newIndex = -i : newIndex = i;
currNo = parseInt(timeUnit,10) + (newIndex);
if (String(parseInt(timeUnit,10)).length >= 2) {
$(el).text(parseInt(timeUnit,10) + (newIndex))
} else if(String(parseInt(timeUnit,10)).length == 1 && currNo == 10) {
$(el).text(parseInt(timeUnit,10) + (newIndex))
} else {
$(el).text(twoDigits + (parseInt(timeUnit,10) + (newIndex)));
}
})
$(el).find(unitClass).animate({
top: '0.15em'
},200, function() {
$(el).find(unitClass + " u:eq(1)").remove();
$(el).find(unitClass).prepend('<u></u>');
$(el).find(unitClass).css({'top':'-1.24em'})
});
}
//resets jCounter's HTML values to 0 or 00, based on the twoDigits setting
function resetHTMLCounter(el) {
if(thisEl.data("userOptions").twoDigits == 'on') {
$(el).find(".days,.hours,.minutes,.seconds").text('00');
} else if(thisEl.data("userOptions").twoDigits == 'off') {
$(el).find(".days,.hours,.minutes,.seconds").text('0');
}
if(thisEl.data("jCanimation") == 'slide') {
$(el).find(".daysSlider u,.hoursSlider u,.minutesSlider u,.secondsSlider u").text('00');
}
}
//main jCounter processor
function countdown_proc(duration,el) {
//check if the counter needs to count down or up
if(customRangeDownCount) {
if(eventDate >= duration) {
clearInterval($(el).data("jC_interval"));
if(thisEl.data("userOptions").callback) {
thisEl.data("userOptions").callback.call(this);
}
}
} else {
if(eventDate <= duration) {
clearInterval($(el).data("jC_interval"));
if(thisEl.data("userOptions").callback) {
thisEl.data("userOptions").callback.call(this);
}
}
}
//if customRange is used, update the seconds variable
var seconds = (customRange) ? duration : eventDate - duration;
var thisInstanceFormat = thisEl.data("userOptions").format;
//calculate seconds into days,hours,minutes,seconds
//if dd (days) is specified in the format setting (i.e. format: 'dd:hh:mm:ss')
if(thisInstanceFormat.indexOf('dd') != -1) {
var days = Math.floor(seconds / (60 * 60 * 24)); //calculate the number of days
seconds -= days * 60 * 60 * 24; //update the seconds variable with no. of days removed
}
//if hh (hours) is specified
if(thisInstanceFormat.indexOf('hh') != -1) {
var hours = Math.floor(seconds / (60 * 60));
seconds -= hours * 60 * 60; //update the seconds variable with no. of hours removed
}
//if mm (minutes) is specified
if(thisInstanceFormat.indexOf('mm') != -1) {
var minutes = Math.floor(seconds / 60);
seconds -= minutes * 60; //update the seconds variable with no. of minutes removed
}
//if ss (seconds) is specified
if(thisInstanceFormat.indexOf('ss') == -1) {
seconds -= seconds; //if ss is unspecified in format, update the seconds variable to 0;
}
//conditional Ss
//updates the plural and singular labels accordingly
if (days == 1) { $(el).find(".textDays").text(singularLabels[0]); } else { $(el).find(".textDays").text(pluralLabels[0]); }
if (hours == 1) { $(el).find(".textHours").text(singularLabels[1]); } else { $(el).find(".textHours").text(pluralLabels[1]); }
if (minutes == 1) { $(el).find(".textMinutes").text(singularLabels[2]); } else { $(el).find(".textMinutes").text(pluralLabels[2]); }
if (seconds == 1) { $(el).find(".textSeconds").text(singularLabels[3]); } else { $(el).find(".textSeconds").text(pluralLabels[3]); }
//twoDigits ON setting
//if the twoDigits setting is set to ON, jCounter will always diplay a minimum number of 2 digits
if(thisEl.data("userOptions").twoDigits == 'on') {
days = (String(days).length >= 2) ? days : "0" + days;
hours = (String(hours).length >= 2) ? hours : "0" + hours;
minutes = (String(minutes).length >= 2) ? minutes : "0" + minutes;
seconds = (String(seconds).length >= 2) ? seconds : "0" + seconds;
}
//updates the jCounter's html values
if(!isNaN(eventDate)) {
$(el).find(".days").text(days);
$(el).find(".hours").text(hours);
$(el).find(".minutes").text(minutes);
$(el).find(".seconds").text(seconds);
if(thisEl.data("jCanimation") == 'slide') {
$(el).find(".daysSlider u:eq(1)").text(days);
$(el).find(".hoursSlider u:eq(1)").text(hours);
$(el).find(".minutesSlider u:eq(1)").text(minutes);
$(el).find(".secondsSlider u:eq(1)").text(seconds);
jCslider(el,'.secondsSlider',seconds,eventDate,duration);
if(parseInt(seconds,10) == 59) {
jCslider(el,'.minutesSlider',minutes,eventDate,duration)
if(parseInt(minutes,10) == 59) {
jCslider(el,'.hoursSlider',hours,eventDate,duration)
if(parseInt(hours,10) == 23) {
jCslider(el,'.daysSlider',days,eventDate,duration)
}
}
}
}
} else {
if(consoleLog) { console.log("(jC) Error: Invalid date! Here's an example: 01 January 1970 12:00:00"); }
clearInterval($(el).data("jC_interval"));
}
//stores the remaining time when pausing jCounter
$(el).data("jC_pausedTime", eventDate-duration);
}
//method calling logic
if ( jC_methods[this.options] ) {
return jC_methods[ this.options ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof this.options === 'object' || ! this.options ) {
return jC_methods.init.apply( this, arguments );
} else {
console.log('(jC) Error: Method >>> ' + this.options + ' <<< does not exist.' );
}
}
//the end;
}) (jQuery,document,window);

JavaScript Countdown clock not automattically counting down

Below is my JS and then my HTML . I cannot figure out why my countdown clock doesn't automatically count down. You must refresh every second to see the correct amount of time left. Any ideas? BTW this is for a Christmas countdown website I am working on.
var Countdowns = function(end, elements, timer, callback) {
var _seconds = 1000,
_minutes = _seconds * 60,
_hours = _minutes * 60,
_days = _hours * 24,
end = new Date(end)
timer,
calculate = function() {
var now = new Date(),
remaining = end.getTime() - now.getTime(),
data;
if (isNaN(end)) {
console.log('Invalid date/time')
return;
}
if (remaining <= 0) { // clear timer
clearInterval(timer);
// callback
if (typeof callback === 'function') {
callback()
}
} else {
if (!timer) {
timer = setInterval(calculate, _seconds);
}
data = {
'days': Math.floor(remaining / _days),
'hours': Math.floor((remaining % _days) / _hours),
'minutes': Math.floor((remaining % _hours) / _minutes),
'seconds': Math.floor((remaining % _minutes) / _seconds),
}
if (elements.length) {
for (x in elements) {
var x = elements[x];
data[x] = ('00' + data[x]).slice(-2);
document.getElementById(x).innerHTML = data[x];
}
}
}
};
calculate();
}
<!DOCTYPE html>
<html>
<head>
<title>Countdowns</title>
</head>
<body>
<span id="days">00</span>
<span id="hours">00</span>
<span id="minutes">00</span>
<span id="seconds">00</span>
<script src="Countdowns.js"></script>
<script>
var callbackfunction = function() {
console.log('Done!')
}
Countdowns('12/25/2015 00:00:00 AM', ['days', 'hours', 'minutes', 'seconds']);
callbackfunction);
</script>
</body>
</html>
You have a couple of minor errors. Try this:
var Countdowns = function(end, elements, timer, callback) {
var _seconds = 1000,
_minutes = _seconds * 60,
_hours = _minutes * 60,
_days = _hours * 24,
end = new Date(end)
timer,
calculate = function() {
var now = new Date(),
remaining = end.getTime() - now.getTime(),
data;
if (isNaN(end)) {
console.log('Invalid date/time')
return;
}
if (remaining <= 0) { // clear timer
clearInterval(timer);
// callback
if (typeof callback === 'function') {
callback()
}
} else {
if (!timer) {
timer = setInterval(calculate, _seconds);
}
data = {
'days': Math.floor(remaining / _days),
'hours': Math.floor((remaining % _days) / _hours),
'minutes': Math.floor((remaining % _hours) / _minutes),
'seconds': Math.floor((remaining % _minutes) / _seconds),
}
if (elements.length) {
for (x in elements) {
var x = elements[x];
data[x] = ('00' + data[x]).slice(-2);
document.getElementById(x).innerHTML = data[x];
}
}
}
};
calculate();
};
var callbackfunction = function() {
console.log('Done!')
}
Countdowns('12/25/2015 00:00:00 AM', ['days', 'hours', 'minutes', 'seconds']);
callbackfunction();
<!DOCTYPE html>
<html>
<head>
<title>Countdowns</title>
</head>
<body>
<span id="days">00</span>
<span id="hours">00</span>
<span id="minutes">00</span>
<span id="seconds">00</span>
<script src="Countdowns.js"></script>
</body>
</html>
replace callbackfunction); with callbackfunction();
var Countdowns = function(end, elements, timer, callback) {
var _seconds = 1000,
_minutes = _seconds * 60,
_hours = _minutes * 60,
_days = _hours * 24,
end = new Date(end)
timer,
calculate = function() {
var now = new Date(),
remaining = end.getTime() - now.getTime(),
data;
if (isNaN(end)) {
console.log('Invalid date/time')
return;
}
if (remaining <= 0) { // clear timer
clearInterval(timer);
// callback
if (typeof callback === 'function') {
callback()
}
} else {
if (!timer) {
timer = setInterval(calculate, _seconds);
}
data = {
'days': Math.floor(remaining / _days),
'hours': Math.floor((remaining % _days) / _hours),
'minutes': Math.floor((remaining % _hours) / _minutes),
'seconds': Math.floor((remaining % _minutes) / _seconds),
}
if (elements.length) {
for (x in elements) {
var x = elements[x];
data[x] = ('00' + data[x]).slice(-2);
document.getElementById(x).innerHTML = data[x];
}
}
}
};
calculate();
};
var callbackfunction = function() {
console.log('Done!')
};
Countdowns('12/25/2015 00:00:00 AM', ['days', 'hours', 'minutes', 'seconds']);
<span id="days">00</span>
<span id="hours">00</span>
<span id="minutes">00</span>
<span id="seconds">00</span>

JavaScript countdown timer not working

I am a JavaScript newbie. I am using a template which has the code below. It shows a countdown timer. I can't understand why it does not work. I have provided it the value of 90 days. Please guide. Thanks
// Generated by CoffeeScript 1.4.0
/*
countdown is a simple jquery plugin for countdowns
Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
and GPL-3.0 (http://opensource.org/licenses/GPL-3.0) licenses.
#source: http://github.com/rendro/countdown/
#autor: Robert Fleischmann
#version: 1.0.1
*/
(function () {
(function ($) {
$.countdown = function (el, options) {
var getDateData,
_this = this;
this.el = el;
this.$el = $(el);
this.$el.data("countdown", this);
this.init = function () {
_this.options = $.extend({}, $.countdown.defaultOptions, options);
if (_this.options.refresh) {
_this.interval = setInterval(function () {
return _this.render();
}, _this.options.refresh);
}
_this.render();
return _this;
};
getDateData = function (endDate) {
var dateData, diff;
endDate = Date.parse($.isPlainObject(_this.options.date) ? _this.options.date : new Date(_this.options.date));
diff = (endDate - Date.parse(new Date)) / 1000;
if (diff <= 0) {
diff = 0;
if (_this.interval) {
_this.stop();
}
_this.options.onEnd.apply(_this);
}
dateData = {
years: 90,
days: 90,
hours: 0,
min: 0,
sec: 90,
millisec: 0
};
if (diff >= (365.25 * 86400)) {
dateData.years = Math.floor(diff / (365.25 * 86400));
diff -= dateData.years * 365.25 * 86400;
}
if (diff >= 86400) {
dateData.days = Math.floor(diff / 86400);
diff -= dateData.days * 86400;
}
if (diff >= 3600) {
dateData.hours = Math.floor(diff / 3600);
diff -= dateData.hours * 3600;
}
if (diff >= 60) {
dateData.min = Math.floor(diff / 60);
diff -= dateData.min * 60;
}
dateData.sec = diff;
return dateData;
};
this.leadingZeros = function (num, length) {
if (length == null) {
length = 2;
}
num = String(num);
while (num.length < length) {
num = "0" + num;
}
return num;
};
this.update = function (newDate) {
_this.options.date = newDate;
return _this;
};
this.render = function () {
_this.options.render.apply(_this, [getDateData(_this.options.date)]);
return _this;
};
this.stop = function () {
if (_this.interval) {
clearInterval(_this.interval);
}
_this.interval = null;
return _this;
};
this.start = function (refresh) {
if (refresh == null) {
refresh = _this.options.refresh || $.countdown.defaultOptions.refresh;
}
if (_this.interval) {
clearInterval(_this.interval);
}
_this.render();
_this.options.refresh = refresh;
_this.interval = setInterval(function () {
return _this.render();
}, _this.options.refresh);
return _this;
};
return this.init();
};
$.countdown.defaultOptions = {
date: "June 7, 2087 15:03:25",
refresh: 1000,
onEnd: $.noop,
render: function (date) {
return $(this.el).html("" + date.years + " years, " + date.days + " days, " + (this.leadingZeros(date.hours)) + " hours, " + (this.leadingZeros(date.min)) + " min and " + (this.leadingZeros(date.sec)) + " sec");
}
};
$.fn.countdown = function (options) {
return $.each(this, function (i, el) {
var $el;
$el = $(el);
if (!$el.data('countdown')) {
return $el.data('countdown', new $.countdown(el, options));
}
});
};
return void 0;
})(jQuery);
}).call(this);
Just change
endDate = Date.parse($.isPlainObject(_this.options.date)
? _this.options.date : new Date(_this.options.date));
to
endDate = Date.parse($.isPlainObject(_this.options.date)
? _this.options.date : new Date(year,month,date));
example:
endDate = Date.parse($.isPlainObject(_this.options.date)
? _this.options.date : new Date(2017,02,15));

JS Countdown timer with days:hours:minutes

I found a neat timer but I need to customize it a bit to work for my project, I tried to change javascript code so it would be a countdown until the weekend and start again from ex: 6days:23hours:59minutes, but I failed miserably
I also would like to know how possible could I add a third row called days
http://codepen.io/anon/pen/ZYEBjP
JS code
var Clock = (function(){
var exports = function(element) {
this._element = element;
var html = '';
for (var i=0;i<6;i++) {
html += '<span> </span>';
}
this._element.innerHTML = html;
this._slots = this._element.getElementsByTagName('span');
this._tick();
};
exports.prototype = {
_tick:function() {
var time = new Date();
this._update(this._pad(time.getHours()) + this._pad(time.getMinutes()) + this._pad(time.getSeconds()));
var self = this;
setTimeout(function(){
self._tick();
},1000);
},
_pad:function(value) {
return ('0' + value).slice(-2);
},
_update:function(timeString) {
var i=0,l=this._slots.length,value,slot,now;
for (;i<l;i++) {
value = timeString.charAt(i);
slot = this._slots[i];
now = slot.dataset.now;
if (!now) {
slot.dataset.now = value;
slot.dataset.old = value;
continue;
}
if (now !== value) {
this._flip(slot,value);
}
}
},
_flip:function(slot,value) {
// setup new state
slot.classList.remove('flip');
slot.dataset.old = slot.dataset.now;
slot.dataset.now = value;
// force dom reflow
slot.offsetLeft;
// start flippin
slot.classList.add('flip');
}
};
return exports;
}());
var i=0,clocks = document.querySelectorAll('.clock'),l=clocks.length;
for (;i<l;i++) {
new Clock(clocks[i]);
}
I would create a helper:
var TimeHelper = function(days, hours, minutes, callback) {
this.subtractMinute = function() {
minutes = (minutes + 60 - 1) % 60;
if (minutes === 0) {
hours = (hours + 60 - 1) % 60;
if (hours === 0) {
days = (days + 24 - 1) % 24;
if (days === 0) {
days = 24;
hours = 0;
minutes = 0;
}
}
}
callback(days, hours, minutes);
}
}
function refreshUI(days, hours, minutes) {
//refresh my ui elements
}
var timeHelper = new TimeHelper(24, 0, 0);
And then you can call timeHelper.subtractMinute once/minute this on every minute

Categories

Resources