Form submission after a period of time - javascript

I have a form. I do the following thing there:
Hide a loading animation when a big image has completed loading and show the big image.
Run a function that submits a form after a period of time (say 2 minutes).
User may still submit the form before the period (2 minutes). In this case he'll get an alert.
Whether user submits the form or the form is being auto-submitted, I do some task before submitting the form. I keep time passed since the big image was loaded. I keep it in a input field because I need the time passed. If user has more than 1 minute before auto submission, I show a confirmation whether the user is sure or can submit the form after sometime.
I was using a countdown timer which handled the auto-submit, but now I'm using custom count-up clock. So, I'm controlling the auto-submit. But it's not working. Here is the code that works correctly:
$(new Image()).on('load', function() {
$('#loading_img').hide();
$('#q').show();
start_exam(get_end_time());
}).prop('src', $('#q').prop('src'))
.each(function() { if (this.complete) $(this).trigger('load');});
$(document).ready(function(){
$('#footer').hide();
$('#header').hide();
});
function start_exam(end_time){
/**
* Load the countdown timer. It sometimes fails to load. At this kind of situation user won't be able to see any countdown timer.
* Everything else should work properly.
*/
$("#timer").jCountdown({
timeText:end_time,
timeZone:6,
style:"flip",
color:"white",
width:0,
textGroupSpace:15,
textSpace:0,
reflection:true,
reflectionOpacity:15,
reflectionBlur:2,
dayTextNumber:4,
displayDay:false,
displayHour:false,
displayMinute:true,
displaySecond:true,
displayLabel:false,
onFinish:function(){
exam_over();
}
});
}
// Do stuff when time is over or examinee submits answer script
function exam_over(){
$('#RecordExamineeForm').submit();
alert("Time over.");
}
function get_end_time(){
var exam_duration = <?=($exam['duration'] * MINUTE); ?>;
$('#RecordDuration').val(exam_duration);
var start = new Date();
$('#RecordStartTime').val(Math.round(start/1000));
start.setSeconds(start.getSeconds() + exam_duration);
var end_time = start.getFullYear() + '/' + (start.getMonth() + 1) + '/' + start.getDate();
end_time += ' ' + start.getHours()+ ':' + start.getMinutes();
end_time += ':' + start.getSeconds();
return end_time;
}
$('#RecordExamineeForm').submit(function(){
var now = new Date();
var duration = $('#RecordDuration').val();
var passed = Math.round((now - new Date($('#RecordStartTime').val() * 1000)) / 1000);
$('#RecordPassed').val(passed);
var time_left = duration - passed;
if(time_left > 60){
$('#RecordValid').val(true);
return confirm('You have more ' + Math.floor(time_left / 60) + ' minutes, will you submit now?');
}else if(time_left >= 0){
$('#RecordValid').val(true);
return true;
}else{
$('#RecordValid').val(false);
return true;
}
});
And this is the code I'm trying now:
$(new Image()).on('load', function() {
$('#loading_img').hide();
$('#q').show();
start_exam(get_end_time()); //submit the form after end time
}).prop('src', $('#q').prop('src'))
.each(function() { if (this.complete) $(this).trigger('load');});
// Do stuff when time is over or examinee submits answer script
function exam_over(){
$('#RecordExamineeForm').submit();
alert("Time over.");
}
function start_exam(delay){
console.log(delay);
$('#RecordExamineeForm').delay(delay).submit();
}
function get_end_time(){
var exam_duration = <?=($exam['duration'] * MINUTE); ?>;
$('#RecordDuration').val(exam_duration);
var start = new Date();
$('#RecordStartTime').val(Math.round(start/1000));
//console.log(exam_duration);
return exam_duration * 1000;
}
$('#RecordExamineeForm').submit(function(){
var now = new Date();
var duration = $('#RecordDuration').val();
var passed = Math.round((now - new Date($('#RecordStartTime').val() * 1000)) / 1000);
$('#RecordPassed').val(passed);
var time_left = duration - passed;
if(time_left > 60){
$('#RecordValid').val(true);
return confirm('You have more ' + Math.floor(time_left / 60) + ' minutes, will you submit now?');
}else if(time_left >= 0){
$('#RecordValid').val(true);
return true;
}else{
$('#RecordValid').val(false);
return true;
}
});
How to make this code running or how can I rearrange to perform the tasks to autosubmit the form? I also have to do the tasks I've described at the beginning of my question. Thanks in advance.
Update: I have changed start_exam() to:
function start_exam(delay){
setTimeout(function() {
exam_over();
}, delay);
}
And like above, exam_over() is:
function exam_over(){
$('#RecordExamineeForm').submit();
alert("Time over.");
}
But exam_over() is being executed two times! Can you please tell me why?

delay() is a jQuery method for the animation FX queue only, so it only works for animations, it won't work for a submit event unless you use queue(), but it would be easier to just use a timeout
change
function start_exam(delay){
console.log(delay);
$('#RecordExamineeForm').delay(delay).submit();
}
to
function start_exam(delay){
console.log(delay);
setTimeout(function() {
$('#RecordExamineeForm').submit();
}, delay);
}

I would recommend to handle the autosubmission with a setTimeout like this:
setTimeout(milliseconds, callback);
For the tasks todo before the submission you can use this:
<form onsubmit="tasksToDo()"></form>

So let's explain a bit of how jQuery works, I'll make it simple because we don't need to go in the details.
jQuery permits you to have Queues, where you can push functions and jQuery will execute the first one. There is one Queue that always exist by default and is always running, it's the FX one. You can use it, or you can not use it as well it's up to you. The first argument of queue()and delay()is a queue name, and if is not set il will use the FX queue.
There is not much magic going here, it simple : by calling queue(fn(){}) you will stack some function in the queue. Then if you queue is not running you will call myQueue.start() (or not if you're using the FX queue), so jQuery will execute the first function. That's all. of course you'll have then in the first function to call the second function when you've finished, etc... so the queue won't stop.
About delay() it is a kind of a template function. What it will do is just stack in your queue a function which will call the next function with a delay, like just calling setTimeout().
So in your case in particular, if you really want to use jQuery queue, you'll have to do as such :
function start_exam(delay){
// delaying the queue
$('#RecordExamineeForm').delay(delay);
// stacking the submit in the queue
$('#RecordExamineeForm').queue(function(next){
$('#RecordExamineeForm').submit();
next();
});
}
Don't forget to call the next function, else the queue will stop.
That said about the queues, in your case I think just using the function setTimeout would be enough.

Related

"User is Typing" Logics implementation in React Native

I am trying to show a message when a user is typing and hide the message after a timeout period is reached, I am using this logic with React Native and Gifted Chat.
updateTyping() {
var TYPING_TIMER_LENGTH= 1000;
if (this.state.connected) {
if (!this.state.typing) {
this.setState({typing : true})
console.log('typing')
}
var lastTypingTime = (new Date()).getTime();
setTimeout( () => {
var typingTimer = (new Date()).getTime();
var timeDiff = typingTimer - lastTypingTime;
if (timeDiff >= TYPING_TIMER_LENGTH && this.state.typing) {
console.log('Stop typing')
this.setState({typing : false});
}
}, TYPING_TIMER_LENGTH);
}
else{
console.log("Socket Cannot connect.")
}
}
Now the typing message keeps hiding and showing (blinking) even when the user is typing.
Logics
Now logically the typing message should show and if after 1000ms idle, the typing message hides.
Is there something I am not doing right from my snippet. Any Ideas would be much appreciated
Here's my implementation of doing your code but better (as explained in comment).
if (!this.state.typing) {
this.setState({typing : true})
console.log('typing')
} else {
clearTimeout(timeoutVar);
}
//var lastTypingTime = (new Date()).getTime();
timeoutVar = setTimeout( () => {
//you dont need to do this. either do this and no timeout,
//or do timeout and not this. It's virtually doing the same thing.
//
//var typingTimer = (new Date()).getTime();
//var timeDiff = typingTimer - lastTypingTime;
//if (timeDiff >= TYPING_TIMER_LENGTH && this.state.typing) {
console.log('Stop typing')
this.setState({typing : false});
//}
}, TYPING_TIMER_LENGTH);
The only important thing about this is you need to make sure that timeoutVar is defined somewhere outside of updateTyping, but accessible. Otherwise this doesn't work. The idea behind it is this: we set a timeout to do something and it's going to fire in the time we tell it to TYPING_TIMER_LENGTH, however every time we type something (assuming from your code this function gets hit when they type) we clear the timeout so it doesn't fire. The only time it fires is if we don't clear it, which will be if they stop typing (again, assuming from your code).
Hi I'm not good at react but upto my knowledge. Using timer is really a bad idea until or unless you the property is exact time bounded.
Sol:
Try to display the message using OnFocus and hide it when it goes away from that text box.

Adding an event listener to stop a timer started from another function jQuery

Sorry this is going to take a bit of explaining so you know what I'm trying to do here...
I'm having trouble with a timer function. Basically when the user hits the page, an Ajax request is made, the result of which starts a timer function. They have a certain amount of time in which to make a payment (this is a block chain based payment app, payment is made via an external wallet - no user input is required on the payment page at all, no buttons to click etc). If the timer runs out the payment box resets.
But if the persistent Ajax calls running in the background find the users payment on the block chain I need to kill the timer as it is no longer required, but I need to keep the payment box open while the confirmations are being monitored until the transaction is complete.
The trouble is I can't alter the already running timer function. I've tried every way possible I could think of but nothing stops the original function from running and ultimately resetting the payment box while the transaction is ongoing (waiting for confirmations).
I have been reading about wrapping the timer function in an object and adding a listener but everything I found seemed really confusing to me.
Below is the relevant code.
The function that starts the timer is being started by the Ajax response from another function...
myTimer(expiry);
The expiry variable being passed is vital as it sets an intial on / off state for the timer (whether to display it or not from the first response). So I need to keep that.
This is the timer function...
function myTimer(expiry) {
// If expiry set to 0 don't use the timer
if (expiry === 0) {
$('#timer').hide();
return;
}
var start = new Date();
var timeoutVal = Math.floor(expiry/100);
animateUpdate();
function updateProgress(percentage) {
$('#timerInner').css("width", percentage + "%");
}
function animateUpdate() {
var now = new Date();
var timeDiff = now.getTime() - start.getTime();
var perc = Math.round((timeDiff/expiry)*100);
if (perc <= 100) {
updateProgress(perc);
setTimeout(animateUpdate, timeoutVal);
} else {
// Timer expired, clear box and show buy button again
$("#paymentWrap").empty();
$("#btn-Pay").show();
$("#btn-Pay").prop("disabled", false);
return;
}
}
}
}
This is the part that I need to "kill" on demand via another function coming from another Ajax response...
// Timer expired, clear box and show buy button again
$("#paymentWrap").empty();
$("#btn-Pay").show();
$("#btn-Pay").prop("disabled", false);
return;
Can somebody explain how I can add a variable listener to this function (maybe by creating it as an object?) so that I can change the chunk of code that triggers the bit above to include a new var called cancelled that can be updated elsewhere in the script WHILE this function is running.
if (perc <= 100) {
updateProgress(perc);
setTimeout(animateUpdate, timeoutVal);
if (cancelled === true) {
// Hide the timer div and kill the timer function
$("#timer").hide();
return;
}
} else {
// Timer expired, clear box and show buy button again
.......
I know this was really long winded, apologies upfront, but thanks for reading and looking forward to any help you can offer.
Cheers!
You can define a global variable to reference setTimeout() call and use cleaTimeout()
let timer = null;
let then_ = new Date().getTime() + 10000;
function fn() {
timer = setTimeout(function() {
console.log("doing stuff at " + new Date()
, "time remaining to do stuff:", then_ - new Date().getTime());
if (new Date().getTime() < then_) {
fn()
} else {
done()
}
}, 1000)
}
function done() {
clearTimeout(timer);
timer = null;
console.log("done doing stuff at " + new Date());
}
document.querySelector("button")
.onclick = function() {
if (timer) {
done()
} else {
this.onclick = null;
}
}
fn();
<button>clear timer</button>

continue looping after alert message

Below is the function use to check for the session of my page. The page will reload after I clicked the alert message.
var timeleft = 60;
function checkTime() {
timeLeft--;
if (timeLeft == 30 )
{
alert("30 secs left.");
window.location.reload();
}
}
Is there anyway that the timeleft continue minus (if the user din't not notice the alert message) so that it will redirect to logout page when the timeleft is = 0.
alert() is a modal, it stops javascript execution. Check this code:
var start = new Date();
var start2;
window.setTimeout(function() {
var end = new Date();
var result = "time from start: " + (end.getTime() - start.getTime())
result += "\ntime from alert: " + (end.getTime() - start2.getTime())
result += "\nalert was open for: " + (start2.getTime() - start.getTime())
alert(result);
}, 500);
window.setTimeout(function() {
alert("hello");
start2 = new Date();
}, 100);
Fiddle for upper code: http://jsfiddle.net/aorcsik/vfeH2/1/
Check out this code, it shows that even setTimeout is stopped during alert(), but you can check how much time the user was looking at the alert, and update your counter (timeLeft) by decreasing with the measured time devided by your ticker delay.
Solution: So my solution would be to measure how much time the user looks at the alert modal, and whenever he clicks ok, check if his session ended, if yes redirect to logout, else do the usual redirect.
var start = new Date();
alert("xxx");
var t = (new Date()).getDate() - start.getDate();
if (t / 1000 > timeLeft) {
/* logout */
} else {
/* redirect */
}
Note: another solution would be to use some html popup instead of the javascript alert, which would not block javascript execution
If you want an async alert you can try this
setTimeout(function() { alert('30 secs left'); }, 1);
But if you want a timed logout you can do something like this instead:
function checkTime() {
setInterval(function(){alert("30 secs left.")},30000); // shown at 30 seconds
setInterval(function(){logout()},60000); // called at 60 seconds
}
function logout() {
// logout functionality
}
your code comment is strange
first you are using a number (60) and you consider it as (two minutes) then alert it is(30 seconds left)..
Anyways ..
you want to count down and when there is only 30 seconds left you want to reload the page!!
the problem here is that when you reload the page you will reset the count down from (60 as in your code)
the solution is one of the following:
1- save the countdown in localstorage as pointed out by #Fabrizio and when the page is reloaded again then use the saved counterdown value.
however this solution assume that your user browser can save to localstorage
2- second solution is that you post your page with the countdown and reload it with the count down..
let us say that you page address is: www.myexampleaddress.com/mypage
then you call the address as follow :www.myexampleaddress.com/mypage?timeleft=30
and catch this on the server and reload the page from the server with value in your querystring ..
so your coude after the alert should be like this
var myURL = location.href+'?timeleft=30';
location.href =myURL;
i hope that help :)

How to automatically reload a page after a given period of inactivity

How can I automatically reload a webpage, if there have been no activity on the page for a given period of time?
This can be accomplished without javascript, with this metatag:
<meta http-equiv="refresh" content="5" >
where content ="5" are the seconds that the page will wait until refreshed.
But you said only if there was no activity, what kind for activity would that be?
If you want to refresh the page if there is no activity then you need to figure out how to define activity. Let's say we refresh the page every minute unless someone presses a key or moves the mouse. This uses jQuery for event binding:
<script>
var time = new Date().getTime();
$(document.body).bind("mousemove keypress", function(e) {
time = new Date().getTime();
});
function refresh() {
if(new Date().getTime() - time >= 60000)
window.location.reload(true);
else
setTimeout(refresh, 10000);
}
setTimeout(refresh, 10000);
</script>
I have built a complete javascript solution as well that does not require jquery. Might be able to turn it into a plugin. I use it for fluid auto-refreshing, but it looks like it could help you here.
JSFiddle AutoRefresh
// Refresh Rate is how often you want to refresh the page
// bassed off the user inactivity.
var refresh_rate = 200; //<-- In seconds, change to your needs
var last_user_action = 0;
var has_focus = false;
var lost_focus_count = 0;
// If the user loses focus on the browser to many times
// we want to refresh anyway even if they are typing.
// This is so we don't get the browser locked into
// a state where the refresh never happens.
var focus_margin = 10;
// Reset the Timer on users last action
function reset() {
last_user_action = 0;
console.log("Reset");
}
function windowHasFocus() {
has_focus = true;
}
function windowLostFocus() {
has_focus = false;
lost_focus_count++;
console.log(lost_focus_count + " <~ Lost Focus");
}
// Count Down that executes ever second
setInterval(function () {
last_user_action++;
refreshCheck();
}, 1000);
// The code that checks if the window needs to reload
function refreshCheck() {
var focus = window.onfocus;
if ((last_user_action >= refresh_rate && !has_focus && document.readyState == "complete") || lost_focus_count > focus_margin) {
window.location.reload(); // If this is called no reset is needed
reset(); // We want to reset just to make sure the location reload is not called.
}
}
window.addEventListener("focus", windowHasFocus, false);
window.addEventListener("blur", windowLostFocus, false);
window.addEventListener("click", reset, false);
window.addEventListener("mousemove", reset, false);
window.addEventListener("keypress", reset, false);
window.addEventListener("scroll", reset, false);
document.addEventListener("touchMove", reset, false);
document.addEventListener("touchEnd", reset, false);
<script type="text/javascript">
var timeout = setTimeout("location.reload(true);",600000);
function resetTimeout() {
clearTimeout(timeout);
timeout = setTimeout("location.reload(true);",600000);
}
</script>
Above will refresh the page every 10 minutes unless resetTimeout() is called. For example:
clicky
Based on the accepted answer of arturnt. This is a slightly optimized version, but does essentially the same thing:
var time = new Date().getTime();
$(document.body).bind("mousemove keypress", function () {
time = new Date().getTime();
});
setInterval(function() {
if (new Date().getTime() - time >= 60000) {
window.location.reload(true);
}
}, 1000);
Only difference is that this version uses setInterval instead of setTimeout, which makes the code more compact.
var bd = document.getElementsByTagName('body')[0];
var time = new Date().getTime();
bd.onmousemove = goLoad;
function goLoad() {
if(new Date().getTime() - time >= 1200000) {
time = new Date().getTime();
window.location.reload(true);
}else{
time = new Date().getTime();
}
}
Each time you move the mouse it will check the last time you moved the mouse. If the time interval is greater than 20' it will reload the page, else it will renew the last-time-you-moved-the-mouse.
use JavaScript setInterval method:
setInterval(function(){ location.reload(); }, 3000);
Auto reload with target of your choice. In this case target is _self set to itself,but you could change the reload page by simply changing the window.open('self.location', '_self'); code to something like this examplewindow.top.location="window.open('http://www.YourPageAdress.com', '_self'";.
With a confirmation ALERT message:
<script language="JavaScript">
function set_interval() {
//the interval 'timer' is set as soon as the page loads
var timeoutMins = 1000 * 1 * 15; // 15 seconds
var timeout1Mins = 1000 * 1 * 13; // 13 seconds
itimer=setInterval("auto_logout()",timeoutMins);
atimer=setInterval("alert_idle()",timeout1Mins);
}
function reset_interval() {
var timeoutMins = 1000 * 1 * 15; // 15 seconds
var timeout1Mins = 1000 * 1 * 13; // 13 seconds
//resets the timer. The timer is reset on each of the below events:
// 1. mousemove 2. mouseclick 3. key press 4. scrolling
//first step: clear the existing timer
clearInterval(itimer);
clearInterval(atimer);
//second step: implement the timer again
itimer=setInterval("auto_logout()",timeoutMins);
atimer=setInterval("alert_idle()",timeout1Mins);
}
function alert_idle() {
var answer = confirm("Session About To Timeout\n\n You will be automatically logged out.\n Confirm to remain logged in.")
if (answer){
reset_interval();
}
else{
auto_logout();
}
}
function auto_logout() {
//this function will redirect the user to the logout script
window.open('self.location', '_self');
}
</script>
Without confirmation alert:
<script language="JavaScript">
function set_interval() {
//the interval 'timer' is set as soon as the page loads
var timeoutMins = 1000 * 1 * 15; // 15 seconds
var timeout1Mins = 1000 * 1 * 13; // 13 seconds
itimer=setInterval("auto_logout()",timeoutMins);
}
function reset_interval() {
var timeoutMins = 1000 * 1 * 15; // 15 seconds
var timeout1Mins = 1000 * 1 * 13; // 13 seconds
//resets the timer. The timer is reset on each of the below events:
// 1. mousemove 2. mouseclick 3. key press 4. scrolling
//first step: clear the existing timer
clearInterval(itimer);
clearInterval(atimer);
//second step: implement the timer again
itimer=setInterval("auto_logout()",timeoutMins);
}
function auto_logout() {
//this function will redirect the user to the logout script
window.open('self.location', '_self');
}
</script>
Body code is the SAME for both solutions:
<body onLoad="set_interval(); document.form1.exp_dat.focus();" onKeyPress="reset_interval();" onmousemove="reset_interval();" onclick="reset_interval();" onscroll="reset_interval();">
I came up with a slightly different solution, because I found that setInterval isn't really accurate, see: setInterval timing slowly drifts away from staying accurate
// Based on https://stackoverflow.com/a/15279599
// Refresh Rate is how often you want to refresh the page
// based off the user inactivity (in seconds).
var refresh_after = 20;
var last_user_action = new Date();
// Reset the Timer on users last action
function reset() {
last_user_action = new Date();
}
// Countdown that executes every second.
setInterval(function () {
refreshCheck();
}, 1000);
// The code that checks if the window needs to reload
function refreshCheck() {
var expire_time = new Date(last_user_action);
expire_time.setSeconds(expire_time.getSeconds() + refresh_after);
now = new Date();
if (now.getTime() >= expire_time.getTime() && document.readyState == "complete") {
window.location.href = window.location.href; // We do this to discard the POST data.
}
}
window.addEventListener("click", reset, false);
window.addEventListener("mousemove", reset, false);
window.addEventListener("keypress", reset, false);
window.addEventListener("scroll", reset, false);
document.addEventListener("touchMove", reset, false);
document.addEventListener("touchEnd", reset, false);
Yes dear,then you have to use Ajax technology. to changes contents of
particular html tag:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<title>Ajax Page</title>
<script>
setInterval(function () { autoloadpage(); }, 30000); // it will call the function autoload() after each 30 seconds.
function autoloadpage() {
$.ajax({
url: "URL of the destination page",
type: "POST",
success: function(data) {
$("div#wrapper").html(data); // here the wrapper is main div
}
});
}
</script>
</head>
<body>
<div id="wrapper">
contents will be changed automatically.
</div>
</body>
</html>
I would consider activity to be whether or not the user is focused on the window. For example, when you click from one window to another (e.g. Google Chrome to iTunes, or Tab 1 to Tab 2 within an internet browser), the webpage can send a callback saying "Im out of focus!" or "Im in focus!". One could use jQuery to harness this possible lack of activity to do whatever they wanted. If I were in your position, I would use the following code to check for focus every 5 seconds, etc and reload if no focus.
var window_focus;
$(window).focus(function() {
window_focus = true;
}).blur(function() {
window_focus = false;
});
function checkReload(){
if(!window_focus){
location.reload(); // if not focused, reload
}
}
setInterval(checkReload, 5000); // check if not focused, every 5 seconds
And finally the most simple solution:
With alert confirmation:
<script type="text/javascript">
// Set timeout variables.
var timoutWarning = 3000; // Display warning in 1Mins.
var timoutNow = 4000; // Timeout in 2 mins.
var warningTimer;
var timeoutTimer;
// Start timers.
function StartTimers() {
warningTimer = setTimeout("IdleWarning()", timoutWarning);
timeoutTimer = setTimeout("IdleTimeout()", timoutNow);
}
// Reset timers.
function ResetTimers() {
clearTimeout(warningTimer);
clearTimeout(timeoutTimer);
StartTimers();
$("#timeout").dialog('close');
}
// Show idle timeout warning dialog.
function IdleWarning() {
var answer = confirm("Session About To Timeout\n\n You will be automatically logged out.\n Confirm to remain logged in.")
if (answer){
ResetTimers();
}
else{
IdleTimeout();
}
}
// Logout the user and auto reload or use this window.open('http://www.YourPageAdress.com', '_self'); to auto load a page.
function IdleTimeout() {
window.open(self.location,'_top');
}
</script>
Without alert confirmation:
<script type="text/javascript">
// Set timeout variables.
var timoutWarning = 3000; // Display warning in 1Mins.
var timoutNow = 4000; // Timeout in 2 mins.
var warningTimer;
var timeoutTimer;
// Start timers.
function StartTimers() {
warningTimer = setTimeout(timoutWarning);
timeoutTimer = setTimeout("IdleTimeout()", timoutNow);
}
// Reset timers.
function ResetTimers() {
clearTimeout(warningTimer);
clearTimeout(timeoutTimer);
StartTimers();
$("#timeout").dialog('close');
}
// Logout the user and auto reload or use this window.open('http://www.YourPageAdress.com', '_self'); to auto load a page.
function IdleTimeout() {
window.open(self.location,'_top');
}
</script>
Body code is the SAME for both solutions
<body onload="StartTimers();" onmousemove="ResetTimers();" onKeyPress="ResetTimers();">
With on page confirmation text instead of alert
Since this is another method to auto load if inactive I give it a second answer. This one is more simple and easier to understand.
With reload confirmation on the page
<script language="javaScript" type="text/javascript">
<!--
var autoCloseTimer;
var timeoutObject;
var timePeriod = 5100; // 5,1 seconds
var warnPeriod = 5000; // 5 seconds
// Warning period should always be a bit shorter then time period
function promptForClose() {
autoCloseDiv.style.display = 'block';
autoCloseTimer = setTimeout("definitelyClose()", warnPeriod);
}
function autoClose() {
autoCloseDiv.style.display = 'block'; //shows message on page
autoCloseTimer = setTimeout("definitelyClose()", timePeriod); //starts countdown to closure
}
function cancelClose() {
clearTimeout(autoCloseTimer); //stops auto-close timer
autoCloseDiv.style.display = 'none'; //hides message
}
function resetTimeout() {
clearTimeout(timeoutObject); //stops timer
timeoutObject = setTimeout("promptForClose()", timePeriod); //restarts timer from 0
}
function definitelyClose() {
// If you use want targeted reload: parent.Iframe0.location.href = "https://URLHERE.com/"
// or this: window.open('http://www.YourPageAdress.com', '_self');
// of for the same page reload use: window.top.location=self.location;
// or window.open(self.location;, '_self');
window.top.location=self.location;
}
-->
</script>
Confirmation box when using with on page confirmation
<div class="leftcolNon">
<div id='autoCloseDiv' style="display:none">
<center>
<b>Inactivity warning!</b><br />
This page will Reloads automatically unless you hit 'Cancel.'</p>
<input type='button' value='Load' onclick='definitelyClose();' />
<input type='button' value='Cancel' onclick='cancelClose();' />
</center>
</div>
</div>
Body codes for both are the SAME
<body onmousedown="resetTimeout();" onmouseup="resetTimeout();" onmousemove="resetTimeout();" onkeydown="resetTimeout();" onload="timeoutObject=setTimeout('promptForClose()',timePeriod);">
NOTE: If you do not want to have the on page confirmation, use Without confirmation
<script language="javaScript" type="text/javascript">
<!--
var autoCloseTimer;
var timeoutObject;
var timePeriod = 5000; // 5 seconds
function resetTimeout() {
clearTimeout(timeoutObject); //stops timer
timeoutObject = setTimeout("definitelyClose()", timePeriod); //restarts timer from 0
}
function definitelyClose() {
// If you use want targeted reload: parent.Iframe0.location.href = "https://URLHERE.com/"
// or this: window.open('http://www.YourPageAdress.com', '_self');
// of for the same page reload use: window.top.location=self.location;
// or window.open(self.location;, '_self');
window.top.location=self.location;
}
-->
</script>
Using LocalStorage to keep track of the last time of activity, we can write the reload function as follows
function reloadPage(expiryDurationMins) {
const lastInteraction = window.localStorage.getItem('lastinteraction')
if (!lastInteraction) return // no interaction recorded since page load
const inactiveDurationMins = (Date.now() - Number(lastInteraction)) / 60000
const pageExpired = inactiveDurationMins >= expiryDurationMins
if (pageExpired) window.location.reload()
}
Then we create an arrow function which saves the last time of interaction in milliseconds(String)
const saveLastInteraction = () => window.localStorage.setItem('last', Date.now().toString())
We will need to listen to the beforeunload event in the browser to clear our lastinteraction record so we don't get stuck in an infinite reload loop.
window.addEventListener('beforeunload', () => window.localStorage.removeItem('lastinteraction'))
The user activity events we will need to monitor would be mousemove and keypress. We store the last interaction time when the user moves the mouse or presses a key on the keyboard
window.addEventListener('mousemove', saveLastInteraction)
window.addEventListener('keypress', saveLastInteraction)
To set up our final listener, we will use the load event.
On page load, we use the setInterval function to check if the page has expired after a certain period.
const expiryDurationMins = 1
window.addEventListener('load', setInterval.bind(null, reloadPage.bind(null, expiryDurationMins), 1000))
I am doing it like this:
let lastActionTaken = new Date().getTime();
function checkLastAction() {
let now = new Date().getTime();
if (now - lastActionTaken > 1000 * 60 * 60) window.location.reload();
else lastActionTaken = now;
}
window.addEventListener("mousemove", checkLastAction);
window.addEventListener("touchstart", checkLastAction);
window.addEventListener("keydown", checkLastAction);
This will reload the page as soon as the user moves their mouse, hits a key or touches a touchscreen if it has been inactive for 1 hour. Also, this takes care of the focus as well, so if a user is moving their mouse in a different program and then come back to this window it will reload, which is good because the point is to not have old data being shown.
Many of these other answers either don't answer the main part of the question "with no activity", or they are incredibly, unnecessarily complex. I have taken the accepted answer (here: https://stackoverflow.com/a/4644315/9008140 )
and modified it to take advantage of the fact you can assign timers to variables. This allows us to get rid of the second timer, as well as the timestamp.
/**
* create a timer that refreshes the page after the number of
minutes has passed without user interaction.
* Moving the mouse or pressing a key on the current page will start
the timer over.
* #param {any} minutes
*/
var refreshTimer;
function setPageRefreshTimer(minutes) {
var refreshInterval = minutes * 60 * 1000; //interval is in milliseconds. We refresh every x minutes.
$(document.body).bind("mousemove keypress", function (e) {
if (refreshTimer != null && refreshTimer != undefined) {
window.clearTimeout(refreshTimer);
}
refreshTimer = window.setTimeout(function () { window.location.reload(true); }, refreshInterval);
});
refreshTimer = window.setTimeout(function () { window.location.reload(true); }, refreshInterval);
}
This sample code will refresh based on a passed in parameter in minutes, with an accuracy as great as a javascript timer can be. In testing, always less than a second. I created this as a function but you can pull it into your page if you wish.
This task is very easy use following code in html header section
<head> <meta http-equiv="refresh" content="30" /> </head>
It will refresh your page after 30 seconds.

How can I execute a setTimeout() only when the user is present (with the mouse movement) with jQuery

I have a function that updates a <div /> via AJAX:
function update() {
<!-- .ajax() -->
setTimeout(update(), 3000);}
}
What I need is that this is not executed when the user is not present on the website, so if there is no movement of the mouse (we will suppose that if move it is in the website) it will not update .mousemove(). By the way, there is any other thing that we can do to know is someone is active on the website?
How can this be done? Thank you in advance!
Edit: probably I explained bad. I need to know the way to only update when there is activity. Like Facebook does with his news feed, the front page. Thanks!
You could use a mousemove handler to track when the user last moved, and then have the process only happen if they last moved the mouse within X seconds. But of course, if the user is sitting there reading something, or if they're a keyboard-oriented kind of person, that will tend to miss that they are there... So you'd probably want to look at keydown as well.
Here's a mousemove example:
jQuery(function($) {
var count = 0, lastmove = new Date();
$(document).mousemove(function() {
++count;
lastmove = new Date();
$('#display').html("Moved " + count + " times");
});
});​
Then your update code could do this:
function update() {
if (new Date() - lastmove < 60000) { // 60 seconds
// Really do the update
}
else {
// Check back in a few seconds
setTimeout(update, 3000);
}
}
Off-topic, but you have an error in your update code. You have:
setTimeout(update(), 3000);
...which will call update immediately and then try to use its return value to schedule something to happen in three seconds. If you want the call to update to be scheduled to happen in three seconds, leave off the () after it:
setTimeout(update, 3000);
I think I might have ended up with something such as this. Avoids date arithmetic. Only cares whether there's been some activity since the last update().
window.activeFlag = false;
window.updateDelay = 3000;
$(document).bind('mousemove scroll keydown', function(){ activeFlag = true; });
function update() {
if(activeFlag) {
doWork();
activeFlag = false;
}
}
window.setTimeout(update, updateDelay);
edit: I've discovered a flaw in the code. The following is more appropriate:
window.activeFlag = false;
window.updateDelay = 3000;
$(document).bind('mousemove scroll keydown', function(){ activeFlag = true; });
function update() {
if(activeFlag) {
doWork();
activeFlag = false;
}
window.setTimeout(update, updateDelay);
}
update();
I think there is no easy way to determine if the user is present
I would use a combination of mousemove, scroll, keypress.
var bUpdate = false;
function update() {
if(bUpdate){
///perform your ajax request
}
}
$(document).mousemove(function(){
bUpdate = true;
setTimeout(function(){bUpdate=false;}, 3000);}
});

Categories

Resources