In my previous blog post, I showed how you can use jQuery dialog boxes to replace the JavaScript alert() and confirm() functions for a more advanced and skinnable interface.
In this blog post, I am going to dive a little deeper into the “timer” functionality and see how that can be combined with the dlgConfirm dialog box to create a pro-active application timer.
With today’s client-centric programming (JavaScript + Ajax = Web 2.0), your user may be using your application for quite some time before actually communicating back to the server. If you are using any authentication or sessions, you may need to contact the server with a “keep-alive” message periodically while still keeping the application secure if the user steps away from the application for any length of time.
The technique I am going to demonstrate starts a count down timer on the client. Each time a call is made back to the server, the timer is reset. When the timer runs down to 0, a confirmation dialog appears asking the user if they want to continue. If the user does not respond to the popup confirmation within a specified time period, the user is automatically logged out.
The Timer Code
function Timer(id, minLimit, callback) {
var thisTimer = this;
this.limit = 0
this.callback = callback;
this.minLimit = minLimit;
thisTimer.resetTimer();
thisTimer.id = "#" + id;
thisTimer.intv = setInterval(function () { thisTimer.intvFunc(); }, 1000);
}
Timer.prototype = {
intvFunc: function () {
$(this.id).text(this.formatTime(--this.timer));
if (this.timer === this.limit) {
clearInterval(this.intv);
this.callback.call(this);
}
},
formatNum: function (n) {
return n < 10 ? '0' + n : n;
},
formatTime: function (n, m, s) {
s = n % 60;
m = (n - s) / 60;
//return (m + (n > 0 ? 1 : 0)) + ' minute' + ((m > 0 || n == 0) ? 's' : '');
return [this.formatNum(m), ':', this.formatNum(s)].join('');
},
stopTimer: function () {
clearInterval(this.intv);
},
resetTimer: function () {
this.timer = this.minLimit * 60;
}
};
The Timer is basically a JavaScript object that attaches to an identifier (typically a <span> or <div>) to display a count down. When the count down reaches 0, it fires a function call.
The following code:
Time for Fun in <span id='funTime'></span>.
<script type="text/javascript">
new Timer('funTime', 5, function () { alert('FUN TIME!!'); });
</script>
Produces a timer that looks like this:
Time for Fun in 03:03.
When the timer reaches 00:00, an alert box will popup that look like this:
The parameters for the Timer object are:
1) The id of the object (div or span) that will display the timer
2) The length of time for the Timer in minutes
3) The code that will fire if the Timer reaches 00:00
If you keep a reference to the Timer object, you can call other functions on the object like:
var myTimer = new Timer('funTime', 5, function () { alert('FUN TIME!!'); });
myTimer.stopTimer(); // Stop the count down
myTimer.resetTimer(); // Reset the count down to original
Creating a Auto-Logout Timer
Step 1: Create a place-holder for your Timer
Logout Warning in <span id="timeleft"></span>.<br />
Step 2: Create a function to Start the Global Timer
function startLogoutTimer() {
var timeLeft = 30;
window.logoutTimer = new Timer('timeleft', timeLeft, function () {
dlgConfirm(
'Auto-Logout',
'<h2 style="text-align: center;">You will be automatically logged off in ' + timeLeft + ' minute'
+ (timeLeft == 1 ? '' : 's') + '.<br /><br />Would you like to continue using the system?</h2>',
function () {
var delayTimer = $('#dlgConfirm').data('delayTimer');
delayTimer.stopTimer();
$.ajax({
url: '[Your Keep Alive URL]',
type: 'POST',
success: function (data) {
if (data.Errors) {
displayErrors(data.Errors);
}
else {
$('#dlgConfirm').dialog('close');
startLogoutTimer();
}
},
error: function (jqXhr, textStatus, errorThrown) {
alert("Error '" + jqXhr.status + "' (textStatus: '" + textStatus + "', errorThrown: '" + errorThrown + "')");
}
});
},
function () { window.location = '[Your Logout URL]'; }, 600, 1);
});
}
This code creates a new Timer and attaches it to the global window object as “.logoutTimer”. It will display the Timer in the <span> we created in step 1.
If the timer reach 00:00, the function will be called that displays a dlgConfirm (see previous post for details on this object). The dlgConfirm() method displays a message to the user asking if they want to stay logged in. They have 1 minute to decide if they want to stay logged in. If they do not answer the question – or if they select ‘No’ (they don’t want to stay logged in), they they are directed to the Logout URL for your application. If they select ‘Yes’, they an ajax call is made to extend their login cookie from some period of time. Also, if they select ‘Yes’, the global timer is restarted.
Then we start the whole process with a call to:
$(function () {
startLogoutTimer();
}
The Delay Parameter for dlgConfirm()
The last parameter for dlgConfirm() is the delay parameter:
function dlgConfirm(title, msg, onYes, onNo, width, delay)
The relevant code in dlgConfirm for this parameter is:
var delayTimer = null;
var delay = $(this).data('delay');
if (delay > 0) {
var html = $(this).html();
html += "<br /><div style='text-align: center;'>Time Left: <span id='delaytimer'></span></div><br />";
$(this).html(html);
var onNo = $(this).data('onNo');
delayTimer = new Timer('delaytimer',
delay,
function () {
$('#dlgConfirm').dialog('close'); onNo(); });
}
$(this).data('delayTimer', delayTimer);
What this code says is:
1) Look for the delay value in the “data”.
2) If its greater than 0, then do the following:
3) Get the current “message” in the dialog and append a break (<br />), then a
centered <div>, then add the text and place-holder for:
Time Left: 00:00
4) Put the new message (with the appended Timer placeholder) back into the dialog
5) Start a new Timer that will call the onNo function if the Timer expires
No comments:
Post a Comment