I've got a field A in my webpage which, when edited by the user, invokes an API call (using jQuery), which updates field B. After the edit, the API should be called every 10 seconds to update the field B again. I currently do this using:
setTimeout(thisFunction, 10000);
The problem is that this timeout is set every time the user edits field A, which after editing field A a couple times causes the timeout to be set multiple times and the API to be called many many times. This makes the website look pretty stressy.
What I would rather like to do, is set a new timeout every time the field is edited, be it either by the user editing field A, or by the interval reaching 10 seconds and thereby polling the API. In other words; the field should be updated if field B wasn't updated for 10 or more seconds.
Lastly, if the user then clicks button C, the polling should stop.
So my question; how can I run a function to update field B if that field B wasn't updated for 10 or more seconds and how do I stop the polling when I want to (when the user clicks another button) All tips are welcome!
A timer can be cancelled with clearTimeout, so:
var timer = null;
if (timer) {
clearTimeout(timer); //cancel the previous timer.
timer = null;
}
timer = setTimeout(thisFunction, 10000);
var update;
// something happened
clearTimeout(update);
update = setTimeout(thisFunction, 10000);
Related
I'm working on a private site with important data, and I want to log out any user who hasn't done anything for 10min (forgot the tab open in the background as an example). How can I do that, is just running an event listener to the mouse clicks with a timer is fine, or are there other better solutions for this?
This can be achieved by JavaScript only.
Since our web app can be open in multiple tab, so its better to store last activity of user in localStorage
First lets declare events which we consider as user activity and store time of user activity in localStorage
document.addEventListener("mousemove", () =>{
localStorage.setItem('lastActvity', new Date())
});
document.addEventListener("click", () =>{
localStorage.setItem('lastActvity', new Date())
});
Next lets create interval which will be checked on every given interval.
let timeInterval = setInterval(() => {
let lastAcivity = localStorage.getItem('lastActvity')
var diffMs = Math.abs(new Date(lastAcivity) - new Date()); // milliseconds between now & last activity
var seconds = Math.floor((diffMs/1000));
var minute = Math.floor((seconds/60));
console.log(seconds +' sec and '+minute+' min since last activity')
if(minute == 10){
console.log('No activity from last 10 minutes... Logging Out')
clearInterval(timeInterval)
//code for logout or anything...
}
},1000)
event listeners for mouse movement (not clicks), and event listeners for keyboard clicks as well should do the job.
Let's say you want to log out the user after 10mins of inactivity. Simply start a timer (for 10mins) the moment user logs in, every time the user makes any mouse movement or any keyboard clicks, use the event listener to reset the timer.
If there is no activity, after 10mins, the timer should execute log out functionality.
Update :
Like the case suggested by Vishnu Bhadoriya, in that case, the idle solution should be to implement a heartbeat b/w the client and the server. Now, in this case, your mouse and keyboard listeners would send a lifeline event to the server, and the server will keep its session alive. When the lifeline event is not received by the server for more than 10mins (threshold for activity), the server can emit an event to the client which can log him out or can simple invalidate the client's auth token
I have used a few of the jquery keepalive session plugins with out problem.
I have been asked for something a bit different.
We have some forms (built before I started here) that are fairly large and users work in them for a while. The page is never refreshed, so they click save and the session is expired and redirect to the login page.
I suggested one of these plugin, that just prompt the user a few minutes before the session expires which would make an ajax call to keep the session alive.
However, they said, will what if they dont see the prompt and miss it all together and logs them out.
They would like me to check
Has the user had any interaction with the page in the last 5 minutes.
If Yes=Ajax call to keep alive the session, and reset timer.
if No, continue to wait until we get within 2 minutes of session time out and prompt user.
They are trying to avoid the prompt.
Is there anyway with JS/Jquery to know if the page has had any client side interaction?
Rather than using a timer to check if they've had any interaction in the last 5 minutes, couldn't you just send your keepalive any time the form has changed? It would eliminate a need for a timer loop and a small payload ajax call just to keep the session alive shouldn't hurt performance at all.
If you still want to keep the timer loop, I would still recommend using the change event on your form elements. Changing the form implies they're interacting with it, and I think that satisfies their requirement.
Edit: Update to use timer
var idle = true;
function finalIdleCheck(prompt){
if(idle){
if(prompt){
alert("last warning!");
}
//Tighten the idle check time loop; may even want to go < 30s
setTimeout(finalIdleCheck, 30*1000);
} else {
//Ajax stuff to keep session alive
idle = true; //Reset idle flag
}
}
function checkIdle(){
if(idle){
//Warn them
alert("You've been idle");
setTimeout(function(){
finalIdleCheck(true);
}, 60*2*1000);
} else {
//Ajax stuff to keep session alive
idle = true; //Reset idle flag
}
}
$(document).ready(function(){
$("form input").on("change", function(){
idle = false;
}
setTimeout(idleCheck, 60*5*1000);
}
I am writing a chat application that can have many chat windows open at once. Every time a window is opened I call a setInterval on my function, update_chat(), that updates an individual chat window. I pass the chat_id to update_chat()
setInterval("update_chat("+chat_id+")",4000);
chat_id is just the id of the chat. So I can have the function update_chat running multiple times on different intervals depending on how many chats are open. Start the chat works fine.
My main question is how can I stop the interval above. I don't want to stop all intervals, just the one associated with a particular chat. I tried this
clearInterval("update_chat("+chat_id+")");
but it didn't do anything.
I tried
var chat_intervals=[]
chat_intervals[chat_id]=setInterval("update_chat("+chat_id+")",4000);
clearInterval(chat_intervals[end_id]);
It didn't stop the interval
clearInterval(docs) takes an interval ID as a parameter to know which interval to clear. setInterval (docs) returns an interval ID when called, so you store that in a var and pass it to clearInterval when you want that one to clear.
//start the interval, store its ID
var interval_id = setInterval( function () { /* do something*/ }, 1000);
//clear the interval
clearInterval(interval_id);
Note that setTimeout (docs) and clearTimeout (docs) work with each other in the same way.
Also note that while setInterval can take a string argument as the function to run, it can also take actual functions (which is highly preferred). So your code could be better written as:
var update_chat_interval = setInterval(function () {
update_chat(chat_id);
}, 4000);
// to clear it later:
clearInterval(update_chat_interval);
I'm fairly new to JavaScript/jQuery, but have made a script to change the background picture.
First Script
The first script version works fine and does the following:
creates a setInterval timer that calls function backgroundChange() to run every 7 seconds
decides the next picture URL
sets the background picture
This works great, but the problem is when the website is live, on a slow connection the background picture doesn't load in time for the next timer change.
New Script
So the new version:
creates a setTimeout timer that calls function backgroundChange() to run after 7 seconds
var theTimer = setTimeout(backgroundChange, 7000);
clearsTimeout (surely I shouldn't have to run this?)
window.clearTimeout(theTimer);
decides the next picture URL
waits until the picture is loaded:
then sets the background picture
then adds a new setTimeout timer
$('#testImage').attr('src', imageText).load(function()
{
$('#backgroundTop').fadeIn(timeIn,function()
{
theTimer = setTimeout(backgroundTimer, 7000);
});
});
The problem is that the timer now seems to be called double the amount of times whenever the timer runs and exists in the .load function.
I havent purposely not posted my code yet, as I want to make sure my understanding is correct first, rather than someone just fixing my code.
Ta very much.
Instead of unbinding, you could use a JavaScript closure for the timer function. This will maintain a single timer that is reset every time it is called.
var slideTimer = (function(){
var timer = 0;
// Because the inner function is bound to the slideTimer variable,
// it will remain in score and will allow the timer variable to be manipulated.
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
Then in your code:
$('#testImage').attr('src', imageText).load(function() {
$('#backgroundTop').fadeIn(timeIn,function()
{
slideTimer(backgroundTimer, 7000);
});
});
There should be no need to clear or set the timer anywhere else in your code.
You need to unbind the load handler before you add the next one, since they keep piling up as your code stands. With every iteration, you add an extra handler that does the exact same thing. Use unbind to remove the old handler before you reattach:
$('#testImage').unbind('load');
I'm currently working on a simple form that stores users inputted information to a database.
The form will be displayed on iPads at a Kiosk.
If a user walks up to the form and starts to fill in the fields, but doesn't finish and walks away, I want the form fields to clear for the next person.
This is being done to prevent someone from walking up to an iPad with half of the previous users information that was never submitted.
I know I'll have to use Javascript, but I have no clue where to start.
I would say handle the keydown event of the window object and save the current time. Something like this:
var timerID = null;
var timeoutDuration = 60000; // Put the timeout duration here
window.addEventListener('keydown', function(e) {
if(timerID !== null) {
clearTimeout(timerID);
timerID = null;
}
timerID = setTimeout(function() {
// Clear all the fields here
}, timeoutDuration);
}, false);
Here's a demo.
Why not just reload the page after a period of inactivity? Safer bet. Just use setTimeout and clearTimeout JavaScript functions to achieve this when the fields get updated to reset the timers. Use setTimeout to reload the page. This will ensure that the page is reset.
See Reload and JavaScript timing.
In my opinion, the best thing to use it the javaScript timing event.
This can be done by setTimeout() and clearTimeout() functions. Then in those functions you can address the input boxes document.getElementById("nameofElement") and then clear them.
Good example that is easy to follow see :
JavaScript Timing Events
Hope this helps.