I'm trying to create a shoppingcart with reservation time. The remaining time gets calculated by php. As the user enters the requested page, the time gets executed with the integer of seconds, that comes from php (session). If there are 3 minutes left, javascript starts a confirm-box and asks the user, if he wants to reset the timer to go on with his cart.
While the confirm-box is shown, the execution of the timer gets paused. How can I change my code, so that the timer runs without pausing it by the confirm-box?
//Starting the Counter in the document.ready-block
//remainingSeconds($_SESSION['timer']) is the time left in seconds (as int)
CountDownTimer('<?php echo remainingSeconds($_SESSION['timer']); ?>', 'reservedTime');
And here is the CountDownTimer function:
// These functions are located in an external .js-file
// Found it on StackOverflow and edited it for my needs
function CountDownTimer(dt, id)
{
if(id == "kill") {
clearInterval(timer);
} else {
var _second = 1,
_minute = _second * 60,
_hour = _minute * 60;
function showRemaining() {
var time = dt--,
minutes,
seconds;
if (dt == 180) {
var extend = confirm("Reset the timer?");
if (extend) {
resetCounter();
}
}
if (dt < 0) {
clearInterval(timer);
document.getElementById(id).innerHTML = '00:00';
alert("No time left.");
//--redirect for readability removed--
return;
}
if(time > 59) {
minutes = Math.floor((time % _hour) / _minute);
seconds = Math.floor((time % _minute) / _second);
} else {
minutes = "0";
seconds = time;
}
if(minutes < 10) {minutes = "0"+minutes}
if(seconds < 10) {seconds = "0"+seconds}
document.getElementById(id).innerHTML = minutes + ":" + seconds;
}
timer = setInterval(showRemaining, 1000);
}
}
function resetCounter() {
request = $.ajax({url: "php/ajax.php?f=3"});
request.done(function (response, textStatus, jqXHR){
try {
var data = $.parseJSON(response);
CountDownTimer('0', 'kill'); // reset old counter
CountDownTimer(data.time, 'reservedTime'); // start new one
} catch(e) {
alert("ERROR ERMAGERD");
return false;
}
});
request.fail(function (jqXHR, textStatus, errorThrown){
alert("ERROR");
});
}
As the timer gets paused, it will create a time that differs from that in the session. So the cart might expire - but the user won't notice it and might lose his reserved items.
Edit: Or is there a better/secure method to integrate a shopping cart timer with output to the user, so that there won't be a time difference?
Related
I want to make a count of 2 minutes, but I want to give you click to the button "Start", so far, and managed to make it work, but I have an error in the minutes does not run as well back but that appears NaN:seconds.
I show them the code that i am working on.
var timeoutHandle;
function countdown(minutes) {
var seconds = 60;
var mins = minutes
function tick() {
var counter = document.getElementById("timer");
var current_minutes = mins-1
seconds--;
counter.innerHTML =
current_minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
if( seconds > 0 ) {
timeoutHandle=setTimeout(tick, 1000);
} else {
if(mins > 1){
// countdown(mins-1); never reach “00″ issue solved:Contributed by Victor Streithorst
setTimeout(function () { countdown(mins - 1); }, 1000);
}
document.getElementById("timer").innerHTML = "Finished"
}
}
tick();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class="tempo-completo">
<div id="timer">2:00</div>
<button onclick="countdown()">INICIAR</button>
</div>
You are not passing in the number of minutes to the countdown() function.
var timeoutHandle;
function countdown(minutes) {
var seconds = 60;
var mins = minutes
function tick() {
var counter = document.getElementById("timer");
var current_minutes = mins-1
seconds--;
counter.innerHTML =
current_minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
if( seconds > 0 ) {
timeoutHandle=setTimeout(tick, 1000);
} else {
if(mins > 1){
// countdown(mins-1); never reach “00″ issue solved:Contributed by Victor Streithorst
setTimeout(function () { countdown(mins - 1); }, 1000);
}
document.getElementById("timer").innerHTML = "Finished"
}
}
tick();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class="tempo-completo">
<div id="timer">2:00</div>
<button onclick="countdown(2)">INICIAR</button>
</div>
Jeremy Harris' answer is working perfectly fine, but i would like to propose another one.
Don't use setTimeout to make an interval function, use setInterval. Using setTimeout with a recursive loop is overall less precise
With that in mind i've tweek your code to incorporate this idea.
var timeoutHandle;
function countdown(minutes) {
var seconds = 60;
var mins = minutes
var counter = document.getElementById("timer");
var current_minutes = mins-1
// we create an interval variable to clear it later
// we also use an arrow function to have access to variable
// outside of the current function's scope.
let interval = setInterval(() => {
seconds--;
counter.innerHTML =
current_minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
// our seconds have run out
if(seconds <= 0) {
// our minutes have run out
if(current_minutes <= 0) {
// we display the finished message and clear the interval so it stops.
counter.innerHTML = "Finished"
clearInterval(interval);
} else {
// otherwise, we decrement the number of minutes and change the seconds back to 60.
current_minutes--;
seconds = 60;
}
}
// we set our interval to a second.
}, 1000);
}
<div class="tempo-completo">
<div id="timer">2:00</div>
<button onclick="countdown(2)">INICIAR</button>
</div>
I have the following code to show a timer for an online quiz application.On completion , I need to redirect to another page via ajax.
The code works for me,but I found that the timer delays when we shift tabs or minimise the browser.
var mins = 5;
var secs = 0; // Seconds (In addition to min) test time
var timerDisplay = $(document).find('#timerspan');
//Globals:
var timeExpired = false;
// Test time in seconds
var totalTime = secs + (mins * 60);
var countDown = function (callback) {
var interval;
interval = setInterval(function () {
if (secs === 0) {
if (mins === 0) {
timerDisplay.text('0:00');
clearInterval(interval);
callback();
return;
} else {
mins--;
secs = 60;
}
}
var minute_text;
if (mins > 0) {
minute_text = mins;
} else {
minute_text = '0';
}
var second_text = secs < 10 ? ('0' + secs) : secs;
timerDisplay.text(minute_text + ':' + second_text);
secs--;
}, 1000, timeUp);
};
// When time elapses: submit form
var timeUp = function () {
alert("Time's Up!");
timeExpired = true;
var completed=1;
$.ajax({
type:"POST",
url:"success.php",
data:{'userID':<?php echo $_SESSION['userID'];?>},
success: function (hasil) {
$('.response_div').html(hasil);
}
});
};
// Start the clock
countDown(timeUp);
Here is the JavaScript countdown code for Quiz:
var isClicked;
isClicked = false;
document.getElementById('quiz_button').onclick = function() {
isClicked = true;
};
function startTimer(duration, display) {
var timer = duration, minutes, seconds;
const interval = setInterval(function() {
minutes = parseInt(timer / 60, 10)
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ":" + seconds;
if (timer !== 0) {
--timer;
<?php
// start the time session...
Session::set('startTime', time());
?>
} else if (timer == 0) {
if( isClicked == false ) {
$( "#quiz_button" ).trigger( "click", function () {
clearInterval(interval);
});
} else {
clearInterval(timer);
}
}
}, 1000);
}
window.onload = function () {
var seconds = 10,
display = document.querySelector('#time');
startTimer(seconds, display);
};
when the page is load then countdown started.
There is a quiz_button to complete the quiz. When it's clicked I set it true using JS. Otherwise, it triggers the button continuously.
But when the quiz is completed by pressing the button then countdown is still counting. I need to stop it. How can I stop it?
I did:
} else {
clearInterval(timer);
}
I am attempting to make my javascript stopwatch run inside some sort of input box, this way if I wanted to change the current calculated time I could just edit the hour, minute, or second. I tried making the time wrapped inside of html tags but the time would not send from the script into the boxes. Any better ideas of how to make this work???
Javascript
function _timer(callback)
{
var time = 0; // The default time of the timer
var status = 0; // Status: timer is running or stoped
var timer_id; // This is used by setInterval function
// this will start the timer
this.start = function(interval)
{
interval = (typeof(interval) !== 'undefined') ? interval : 1000;
if(status == 0)
{
status = 1;
timer_id = setInterval(function()
{
switch(1)
{
case 1:
if(time < 86400)
{
time++;
generateTime();
if(typeof(callback) === 'function') callback(time);
}
break;
}
}, interval);
}
}
// this will stop or pause the timer ex. timer.stop()
this.stop = function()
{
if(status == 1)
{
status = 0;
clearInterval(timer_id);
}
}
// Reset the timer to zero or reset it to your own custom time
this.reset = function(sec)
{
sec = (typeof(sec) !== 'undefined') ? sec : 0;
time = sec;
generateTime(time);
}
// This methode return the current value of the timer and sends it to the database
this.getTime = function()
{
return time;
}
// This methode return the status of the timer
this.getStatus
{
return status;
}
// This methode will render the time variable to hour:minute:second format
function generateTime()
{
var second = time % 60;
var minute = Math.floor(time / 60) % 60;
var hour = Math.floor(time / 3600) % 60;
second = (second < 10) ? '0'+second : second;
minute = (minute < 10) ? '0'+minute : minute;
hour = (hour < 10) ? '0'+hour : hour;
$('div.timer span.second').html(second);
$('div.timer span.minute').html(minute);
$('div.timer span.hour').html(hour);
}
}
var timer;
$(document).ready(function(e)
{
timer = new _timer
(
function(time)
{
if(time == 0)
{
timer.stop();
}
}
);
timer.reset(0);
});
HTML
<div class="timer">
<span class="hour"></span>:<span class="minute"></span>:<span class="second"></span>
</div>
<div>
<button onClick="timer.start(1000)">Start</button>
<button onClick="timer.stop()">Stop</button>
<button onClick="timer.reset(0)">Reset</button>
</div>
Here's the final working solution.
Javascript
function _timer(callback, interval)
{
var time = time || 0; // The default time of the timer
var status = 0; // Status: timer is running or stoped
var timer_id; // This is used by setInterval function
var interval = interval || 1000;
// this will start the timer
this.start = function()
{
verifyTime();
if(status == 0)
{
status = 1;
timer_id = setInterval(function()
{
switch(1)
{
case 1:
if(time < 86400)
{
time++;
generateTime();
if(typeof(callback) === 'function') callback(time);
}
break;
}
}, interval);
}
}
// this will stop or pause the timer ex. timer.stop()
this.stop = function()
{
if(status == 1)
{
status = 0;
clearInterval(timer_id);
}
}
// Reset the timer to zero or reset it to your own custom time
this.reset = function(sec)
{
time = 0
generateTime()
}
// This methode return the current value of the timer and sends it to the database
this.getTime = function()
{
return time;
}
// This methode return the status of the timer
this.getStatus
{
return status;
}
// This methode will render the time variable to hour:minute:second format
function generateTime()
{
console.log(time);
second = time % 60;
minute = Math.floor(time / 60) % 60;
hour = Math.floor(time / 3600) % 60;
second = (second < 10) ? '0'+second : second;
minute = (minute < 10) ? '0'+minute : minute;
hour = (hour < 10) ? '0'+hour : hour;
$('div.timer input.second').val(second);
$('div.timer input.minute').val(minute);
$('div.timer input.hour').val(hour);
}
function verifyTime()
{
var verifySec = Number($('div.timer input.second').val());
second = time % 60;
verifySec === second ? second = second : time += verifySec - second % 60;
var verifyMin = Number($('div.timer input.minute').val());
minute = (verifyMin - Math.floor(time / 60)) * 60;
verifyMin === minute ? minute = minute : time += (verifyMin - Math.floor(time / 60)) * 60;
var verifyHour = Number($('div.timer input.hour').val());
hour = ((verifyHour - Math.floor(time / 3600)) * 60) * 60;
verifyHour === hour ? hour = hour : time += ((verifyHour - Math.floor(time / 3600)) * 60) * 60;
}
}
var timer;
$(document).ready(function(e)
{
timer = new _timer
(
function(time)
{
if(time == 0)
{
timer.stop()
}
},
1000
);
$('#start').click(timer.start)
$('#stop').click(timer.stop)
$('#reset').click(timer.reset)
$('.hour').focus(timer.stop)
$('.hour').focusout(timer.start)
$('.minute').focus(timer.stop)
$('.minute').focusout(timer.start)
$('.second').focus(timer.stop)
$('.second').focusout(timer.start)
});
HTML
<div class="timer">
<input type='text' class="hour" />:<input type='text' class="minute" />:<input type='text' class="second" />
</div>
<div>
<button id='start'>Start</button>
<button id='stop'>Stop</button>
<button id='reset'>Reset</button>
</div>
A have an eggtimer which can be stopped after clicking on the button "stop". What I want is making this timer working again (from the point where it stopped) after clicking "cancel" in a confirm box. Any sugestions? Thanks for help :)
<!DOCTYPE html>
<html>
<body onload="timer();">
<button onclick="exit();">stop</button>
<p id="seconds">30</p>
<script type="text/javascript">
var clock;
function timer () {
var start = new Date().getTime();
clock = setInterval(function() {
var seconds = Math.round(30 - (new Date().getTime() - start) / 1000);
if (seconds >= 0)
document.getElementById('seconds').innerHTML = seconds;
else
clearInterval(clock);
if (seconds==0) {window.location.href="something.com";
return;
}
}, 1000);
}
function exit(){
clearInterval(clock);
var result = confirm("Are you leaving?");
if (result == true) {
window.location.href="somewhere.com";
}
else {
timer();} // <-- ????
}
</script>
</body>
</html>
You can create a variable that holds in what seconds you are ;
var sec = seconds;
Change your function timer with the timer you want to start as a paramerter
function timer (time)
var clock;
var sec;
function timer (time) {
var start = new Date().getTime();
clock = setInterval(function() {
var seconds = Math.round(time - (new Date().getTime() - start) / 1000);
sec = seconds;
if (seconds >= 0){
document.getElementById('seconds').innerHTML = seconds;
}
else{
clearInterval(clock);
}
if (seconds==0){
window.location.href="something.com";
return;
}
}, 1000);
}
function exit(){
clearInterval(clock);
var result = confirm("Are you leaving?");
if (result == true) {
window.location.href="somewhere.com";
}
else {
console.log(sec);
timer(sec);} // <-- ????
}
<body onload="timer(30);">
<button onclick="exit();">stop</button>
<p id="seconds">30</p>
</body>
Here's a working example.
I moved the seconds variable outside the function so it persists and can be used to re-start the timer.
Also, I added an argument to the timer() function so the count down amount can be changed.
Note that the granularity is at the second level, so the actual count down time might eventually be longer than 30 seconds, but I believe it is acceptable in this use case.
var clock;
var seconds;
function timer(wait) {
var start = new Date().getTime();
clock = setInterval(function() {
seconds = Math.round(wait - (new Date().getTime() - start) / 1000);
if (seconds >= 0)
document.getElementById('seconds').innerHTML = seconds;
else
clearInterval(clock);
if (seconds == 0) {
window.location.href = "something.com";
return;
}
}, 1000);
}
function exit() {
clearInterval(clock);
var result = confirm("Are you leaving?");
if (result == true) {
window.location.href = "somewhere.com";
} else {
timer(seconds);
} // <-- ????
}
timer(30);
<button onclick="exit();">stop</button>
<p id="seconds">30</p>