Update
Turns out, coding while tired is not optimal. As pointed out in the comments, I was missing the definition of oneHour in countdownAutoLogout()... It must have been accidentally deleted in the copy & paste-process... Sorry for the inconvenience! I'll show myself out.
I have two almost identical countdown functions located in site.js. One is working, the other not so much.
I used to have only countdownAutoLogout(), and it was working as expected. Upon adding countdownMeeting(durationSeconds), countdownAutoLogout() is only initiated, but doesn't count down, as I have illustrated with the alert()s in the code.
countdownAutoLogout() is called in the <body>-tag in _Layout.cshtml:
<body onload="javascript: countdownAutoLogout();">
countdownMeeting(durationSeconds) is called in the scripts section in the view:
#section scripts{
<script>
$(document).ready(function() {
// Model.RemainingSeconds is a model property of type double.
countdownMeeting(#Model.RemainingSeconds);
})
</script>
}
The functions:
// Padding with leading zero:
function pad(str, max, padder) {
padder = typeof padder === "undefined"
? "0"
: padder;
return str.toString().length < max
? pad(padder.toString() + str, max, padder)
: str;
}
function countdownAutoLogout() {
alert("This alert pops up.");
var oneMinute = 60000;
var twoHours = oneMinute * 121;
var countDownDate = Date.now() + twoHours;
var x = setInterval(function () {
var now = Date.now();
var distance = countDownDate - now;
var hours = Math.floor((distance % (oneHour * 24)) / oneHour);
var minutes = Math.floor((distance % oneHour) / oneMinute);
alert("This alert doesn't pop up.");
document.getElementById("SessionCookieExpirationCountdown").innerHTML =
pad(hours, 2) + ":" + pad(minutes, 2);
if (distance < 0) {
clearInterval(x);
location.href = "/Home/Timeout";
}
}, 5000);
}
// This function is working smoothly:
function countdownMeeting(durationSeconds) {
var oneMinute = 60000;
var oneHour = oneMinute * 60;
var duration = oneMinute * durationSeconds / 60;
var countDownDate = Date.now() + duration;
var x = setInterval(function () {
var now = Date.now();
var distance = countDownDate - now;
var hours = Math.floor((distance % (oneHour * 24)) / oneHour);
var minutes = Math.floor((distance % oneHour) / oneMinute);
var seconds = Math.floor((distance % oneMinute) / 1000);
document.getElementById("MeetingDurationCountdown").innerHTML =
pad(hours, 2) + ":" + pad(minutes, 2) + ":" + pad(seconds, 2);
if (distance < 0) {
clearInterval(x);
document.getElementById("MeetingDurationCountdown").innerHTML = "Overtime!";
}
}, 1000);
}
Related
I am new to javascript/jquery. I found the following example on the internet and I am trying to get it working with my SQL variable. But I am stuck because all it does is count down from 60 over and over again..
What I am trying to accomplish is the following. I have a variable which says how many seconds a user needs to wait before it can perform the action again $secs. What I need is to have the time and process-bar countdown with the seconds from the variable to zero. After that I will add a page reload line to it. But first the timer needs to work. I would really appreciate any help as I can not find any workable solution/explanation for my problem.
<div id='timer'></div>
<div id='progress' style='background:red; height:5px;'></div>
<script>
function started(duration) {
var TotalSeconds = "<?php echo $secs; ?>";
var documentWidth = $(document).width();
var start = Date.now();
var intervalSetted = null;
function timer() {
var diff = duration - (((Date.now() - start) / 1000) | 0);
var seconds = (diff % 60) | 0;
seconds = seconds < 10 ? "0" + seconds : seconds;
$('#timer').html("00:" + seconds);
var progresBarWidth = (seconds * documentWidth / TotalSeconds);
$('#progress').css({
width: progresBarWidth + 'px'
});
if (diff <= 0) {
clearInterval(intervalSetted);
}
}
timer();
intervalSetted = setInterval(timer, 1000);
}
started("<?php echo $secs; ?>");
</script>
You need to convert duration to time format.
<div id='timer'></div>
<div id='progress' style='background:red; height:5px;'></div>
<script>
function started(duration) {
var TotalSeconds = duration;
var documentWidth = $(document).width();
var start = Date.now();
var intervalSetted = null;
function timer() {
var diff = duration - (((Date.now() - start) / 1000) | 0);
var seconds = (diff % duration) | 0;
seconds = seconds < 10 ? "0" + seconds : seconds;
var date = new Date(0);
date.setSeconds(seconds);
var timeString = date.toISOString().substr(11, 8);
$('#timer').html(timeString);
var progresBarWidth = (seconds * documentWidth / TotalSeconds);
$('#progress').css({
width: progresBarWidth + 'px'
});
if (diff <= 0) {
clearInterval(intervalSetted);
}
}
timer();
intervalSetted = setInterval(timer, 1000);
}
started("<?php echo $secs; ?>");
</script>
function started(duration) {
var TotalSeconds = duration;
var documentWidth = $(document).width();
var start = Date.now();
var intervalSetted = null;
function timer() {
var diff = duration - (((Date.now() - start) / 1000) | 0);
var seconds = (diff % duration) | 0;
seconds = seconds < 10 ? "0" + seconds : seconds;
var date = new Date(0);
date.setSeconds(seconds);
var timeString = date.toISOString().substr(11, 8);
$('#timer').html(timeString);
var progresBarWidth = (seconds * documentWidth / TotalSeconds);
$('#progress').css({
width: progresBarWidth + 'px'
});
if (diff <= 0) {
clearInterval(intervalSetted);
}
}
timer();
intervalSetted = setInterval(timer, 1000);
}
started(60);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='timer'></div>
<div id='progress' style='background:red; height:5px;'></div>
I have a minute timer which counts from 15 to 0. I don't want to reset (= restart) the timer on page reload. but I can't figure out how to prevent the timer from resetting on a page reload. I'm using javascript with php. I have tried to add the timer time on load to php session but that didn't work for me. any suggestions? thank you :)
function startTimer() {
setTimeout('timer()', 60);
}
var continueMins = localStorage.getItem("continueMins");
var continueSecs = localStorage.getItem("continueSecs");
if (continueMins == 'true') {
mins = continueMins;
} else {
mins = 15;
}
if (continueSecs == 'true') {
secs = continueSecs;
} else {
secs = mins * 60;
}
function timer() {
if (document.getElementById) {
minutes = document.getElementById("minutes");
seconds = document.getElementById("seconds");
progressBar = document.getElementById("progressBar");
timerContainer = document.getElementById("timer-container");
expired = document.getElementById("expired");
btcAmount = document.getElementById("btcAmount");
btcAddress = document.getElementById("btcAddress");
window.onbeforeunload = function() {
localStorage.setItem("continueMins", getMinutes());
localStorage.setItem("continueSecs", getSeconds());
}
var totalSeconds = 15 * 60, remainingSeconds = getMinutes() * 60 + getSeconds();
progressBar.style.width = (remainingSeconds * 100 / totalSeconds) + "%";
minutes.innerHTML = getMinutes() < 10 ? "0" + getMinutes() : getMinutes();
seconds.innerHTML = getSeconds() < 10 ? "0" + getSeconds() : getSeconds();
if (mins < 1) {
minutes.classList.add("text-danger");
seconds.classList.add("text-danger");
}
if (mins < 0) {
expired.style.display = 'block';
timerContainer.style.display = 'none';
btcAmount.text = 'Expired';
btcAddress.text = 'Payment Window Expired';
localStorage.removeItem("continueMins");
localStorage.removeItem("continueSecs");
} else {
secs--;
setTimeout('timer()', 1000);
}
}
}
function getMinutes() {
mins = Math.floor(secs / 60);
return mins;
}
function getSeconds() {
return secs - Math.round(mins * 60);
}
startTimer();
<p class="font-18 font-500"><span id="minutes"></span> : <span id="seconds"></span></p>
You could use the localStorage (sessionStorage is also an option but more prone to restart your timer if the user e.g. reconnects in a new tab or restarts the browser)
How to do it to be on the save side (crashes, unexpected bahaviour e.g.you should update the elapsed time in your local storage from time to time. The "normal" situations are handled by checking for the respective event:
var aTimer, bool;
window.onbeforeunload = function (e) {
if (bool) return;
aTimer = setTimeout(function () {
bool = true;
localStorage.setItem("resetTimer", "false");
localStorage.setItem("currentTimer", MY_TIMER_VAR);
localStorage.setItem("sessionDate", MY_NEW_SESSION_VAR);
}, 500);
return ;
};
EDIT If you want that an elapsed timer is valid for lets say 24 hours you have also to place MY_NEW_SESSION_VAR which is a Date.now() converted in hours when reloading you check against TODAY_DATETIME_IN_HOURS which is a Date.now() converted in hours (This was my use case, if you do not need it just leave it out)
The keys and the values are always strings (note that, as with objects, integer keys will be automatically converted to strings).
When starting your program (loading js) you should check for the vars with:
var resetTimer = localStorage.getItem("resetTimer");
var sessionDate = localStorage.getItem("sessionDate");
if (resetTimer == "true" || sessionDate > (TODAY_DATETIME_IN_HOURS - 24) ){ // start timer }
To delete a single item
localStorage.removeItem("sessionDate");
If you want to use sessionStorage just replace localStorage with sessionStorage
EDIT full code for the OP tested and working as asked
var countDownTarget;
if (document.readyState!="loading") docReady();
/* Modern browsers */
else document.addEventListener("DOMContentLoaded", docReady);
function docReady() {
countDownTarget = parseInt(localStorage.getItem("countDownTarget"));
console.debug("Initvalue: " + countDownTarget);
if (isNaN(countDownTarget) == true || countDownTarget == "" || countDownTarget <= 0){ // If not defined
countDownTarget = new Date().getTime() + 15 * 60 * 1000;
console.debug("is NaN sInitvalue: " + countDownTarget);
//Update the count down every 1 second
setInterval(countDown, 1000);
} else {
console.debug("else Initvalue: " + countDownTarget);
setInterval(countDown, 1000);
}
}
window.onbeforeunload = function() {
localStorage.setItem("countDownTarget", countDownTarget);
};
// Functions you call
function countDown(){
var now = new Date().getTime();
//console.debug("now " + now);
var distance = countDownTarget - now;
console.debug("distance " + distance);
var mins = distance < 0 ? 0 : Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var secs = distance < 0 ? 0 : Math.floor((distance % (1000 * 60)) / 1000);
/** Add a zero in front of numbers<10 */
mins = prependZero(mins);
secs = prependZero(secs);
// Output the results
document.getElementById("minutes").innerHTML = mins;
document.getElementById("seconds").innerHTML = secs;
if (distance <= 0) {
// clearInterval(x);
localStorage.removeItem("countDownTarget");
clearInterval(countDown);
}
}
function prependZero(i){
if (i < 10) {
i = "0" + i;
}
return i;
}
Copy between your script tags or load as *.js file
I want to convert the value of album.songs[i].duration in the following code so it displays hr:mn:sc instead of the format it is stored in, which is seconds. Can I do this in this line of code?
var $newRow = createSongRow(i + 1, album.songs[i].title, album.songs[i].duration);
This is basic math...
function convert(s) {
var hr = (Math.floor(s / 3600));
var mn = (Math.floor(s % 3600 / 60));
var sc = (Math.floor(s % 60));
return hr +":"+ mn +":"+ sc;
}
/* for example */
var seconds = 345432;
console.log(convert(seconds));
Considering that you want to convert a duration (in seconds) in the format of hr:mn:sc, we can follow the below approach in vanilla javascript:
var duration = 5000; // seconds
var hour = parseInt(duration / 3600); // as 1 hour = 3600 seconds
var minutes = parseInt((duration - (hour * 3600)) / 60); // as 1 minute = 60 seconds
var seconds = duration - (hour * 3600) - (minutes * 60);
var durationStr = hour + ':' + minutes + ':' + seconds;
console.log(durationStr); // should print 1:23:20
Expanding on Hearner's answer, with padding for minutes and seconds < 10:
function pad(num) {
if (num < 10) return '0' + num;
return num;
}
function convert(s) {
var hr = (Math.floor(s / 3600));
var mn = pad(Math.floor(s % 3600 / 60));
var sc = pad(Math.floor(s % 60));
return hr +":"+ mn +":"+ sc;
}
/* for example */
var seconds = 3661;
console.log(convert(seconds)); // 1:01:01 instead of 1:1:1
// and you would use:
// var $newRow = createSongRow(i + 1, album.songs[i].title, convert(album.songs[i].duration));
I am trying to make a javascript timer that when initiated, starts counting up. The timer is just a visual reference from when a start button is clicked to when the end button is clicked.
I found a plugin online which works perfectly for counting down but I am trying to modify it to count up.
I hard coded a date way in the future. I am now trying to get the timer to start counting up to that date. This will be reset every time the start button is clicked.
This is the function I am working with. it works perfectly to count down but I cant figure out how to reverse it.
I thought it was something with how the differece was calculated but I believe it actually happens in the //calculate dates section.
Is there an easy way to reverse this math and have it count up instead?
Fiddle: http://jsfiddle.net/xzjoxehj/
var currentDate = function () {
// get client's current date
var date = new Date();
// turn date to utc
var utc = date.getTime() + (date.getTimezoneOffset() * 60000);
// set new Date object
var new_date = new Date(utc + (3600000*settings.offset))
return new_date;
};
function countdown () {
var target_date = new Date('12/31/2020 12:00:00'), // Count up to this date
current_date = currentDate(); // get fixed current date
// difference of dates
var difference = current_date - target_date;
// if difference is negative than it's pass the target date
if (difference > 0) {
// stop timer
clearInterval(interval);
if (callback && typeof callback === 'function') callback();
return;
}
// basic math variables
var _second = 1000,
_minute = _second * 60,
_hour = _minute * 60,
_day = _hour * 24;
// calculate dates
var days = Math.floor(difference / _day),
hours = Math.floor((difference % _day) / _hour),
minutes = Math.floor((difference % _hour) / _minute),
seconds = Math.floor((difference % _minute) / _second);
// fix dates so that it will show two digets
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;
// set to DOM
//
};
// start
var interval = setInterval(countdown, 1000);
};
JSFiddle
var original_date = currentDate();
var target_date = new Date('12/31/2020 12:00:00'); // Count up to this date
var interval;
function resetCountdown() {
original_date = currentDate();
}
function stopCountdown() {
clearInterval(interval);
}
function countdown () {
var current_date = currentDate(); // get fixed current date
// difference of dates
var difference = current_date - original_date;
if (current_date >= target_date) {
// stop timer
clearInterval(interval);
if (callback && typeof callback === 'function') callback();
return;
}
// basic math variables
var _second = 1000,
_minute = _second * 60,
_hour = _minute * 60,
_day = _hour * 24;
// calculate dates
var days = Math.floor(difference / _day),
hours = Math.floor((difference % _day) / _hour),
minutes = Math.floor((difference % _hour) / _minute),
seconds = Math.floor((difference % _minute) / _second);
// fix dates so that it will show two digets
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;
// set to DOM
//
};
// start
interval = setInterval(countdown, 1000);
};
This OP already has an answer but that has issue with timezone , so this answer.
DownVoters care to comment.
Try this. Fiddle
var TargetDate = new Date('2015', '08', '04', 11, 11, 30) // second parameter is month and it is from from 0-11
$('#spanTargetDate').text(TargetDate);
$('#spanStartDate').text(new Date());
var Sec = 0,
Min = 0,
Hour = 0,
Days = 0;
var counter = setInterval(function () {
var CurrentDate = new Date()
$('#spanCurrentDate').text(CurrentDate);
var Diff = TargetDate - CurrentDate;
if (Diff < 0) {
clearInterval(counter);
$('#timer').text('Target Time Expired. test in fiddle')
} else {
++Sec;
if (Sec == 59) {
++Min;
Sec = 0;
}
if (Min == 59) {
++Hour;
Min = 0;
}
if (Hour == 24) {
++Days;
Hour = 0;
}
if (Sec <= Diff) $('#timer').text(pad(Days) + " : " + pad(Hour) + " : " + pad(Min) + " : " + pad(Sec));
}
}, 1000);
function pad(number) {
if (number <= 9) {
number = ("0" + number).slice(-4);
}
return number;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Target Time - <span id="spanTargetDate"></span>
<br/>
<br/>Start Time - <span id="spanStartDate"></span>
<br/>
<br/>Current Time - <span id="spanCurrentDate"></span>
<br/>
<br/>Timer (DD:HH:MM:SS) - <span id="timer"></span>
<br/>
<br/>
I'm trying to self-taugh JavaScript and while doing some texts with a stopwatch I got lost into this problem. It's working but it's always starting on 95:34:47 instead of 00:00:00
This is what i tried so far.
<script>
/*Timer Stuff*/
function pad(num, size) {
var s = "0000" + num;
return s.substr(s.length - size);
}
function formatTime(time) {
var h = m = s = ms = 0;
var newTime = '';
h = Math.floor( time / (60 * 60 * 1000) );
time = time % (60 * 60 * 1000);
m = Math.floor( time / (60 * 1000) );
time = time % (60 * 1000);
s = Math.floor( time / 1000 );
ms = time % 1000;
newTime = pad(h, 2) + ':' + pad(m, 2) + ':' + pad(s, 2) + ':' + pad(ms, 3);
return newTime;
}
function update() {
var d = new Date();
var n = d.getTime();
document.getElementById("time").innerHTML = formatTime(n);
}
function start() {
MyVar = setInterval(update, 1);
}
</script>
</head>
<body>
<div>Time: <span id="time"></span></div>
<input type="button" value="start" onclick="start();">
</body>
I understand that I need to subtract an specific amount of time to match the timer accurately, however I can't figure out how to do it.
You need to store a variable with the start time, and subtract from that. The 95 you're getting for the hours is actually much higher, just being cropped, being that you're calculating from the Unix epoch.
I would just do it something like this:
function update() {
var d = new Date();
var n = d - startTime;
document.getElementById("time").innerHTML = formatTime(n);
}
function start() {
startTime = new Date();
MyVar = setInterval(update, 1);
}
Note that you don't even need to use d.getTime() when subtracting -- you can just subtract Date objects themselves.
You have to introduce a start-time variable.
In every update-step you have to get the difference from start to now.
For your code:
<script>
/*Timer Stuff*/
timestart = new Date();
timestart_time = timestart.getTime();
function pad(num, size) {
var s = "0000" + num;
return s.substr(s.length - size);
}
function formatTime(time) {
time = time -timestart_time;
var h = m = s = ms = 0;
var newTime = '';
h = Math.floor( time / (60 * 60 * 1000) );
time = time % (60 * 60 * 1000);
m = Math.floor( time / (60 * 1000) );
time = time % (60 * 1000);
s = Math.floor( time / 1000 );
ms = time % 1000;
newTime = pad(h, 2) + ':' + pad(m, 2) + ':' + pad(s, 2) + ':' + pad(ms, 3);
return newTime;
}
function update() {
var d = new Date();
var n = d.getTime();
document.getElementById("time").innerHTML = formatTime(n);
}
function start() {
MyVar = setInterval(update, 1);
}
</script>
</head>
<body>
<div>Time: <span id="time"></span></div>
<input type="button" value="start" onclick="start();">
</body>
That works for me :)