├── keepalive.php ├── timeout.htm ├── screenshot.gif ├── examples.css ├── README.markdown ├── example-mint.htm ├── example-dialog.htm └── src ├── jquery.idletimer.js └── jquery.idletimeout.js /keepalive.php: -------------------------------------------------------------------------------- 1 | OK 2 | -------------------------------------------------------------------------------- /timeout.htm: -------------------------------------------------------------------------------- 1 | You've timed-out! 2 | -------------------------------------------------------------------------------- /screenshot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ehynds/jquery-idle-timeout/HEAD/screenshot.gif -------------------------------------------------------------------------------- /examples.css: -------------------------------------------------------------------------------- 1 | html, body { margin:0; padding:0; font:12px Helvetica, Arial, sans-serif } 2 | #content { padding:10px; } 3 | a { color:#477099 } 4 | 5 | #bar { background:#252823; padding:5px 10px; border-bottom:4px solid #C3D3DA } 6 | #bar h1 { margin:0; padding:0; color:#fff; font-size:40px; letter-spacing:-1px; text-shadow:0 0 4px #000000 } 7 | #bar h1 span { color:#C3D3DA } 8 | #bar div { float:right; margin-top:-50px; padding:20px 20px 0 0 } 9 | #bar a { color:#fff; text-decoration:none } 10 | #bar div a:hover { text-decoration:underline } 11 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # jQuery Idle Timeout 2 | 3 | See the original [Mint.com example](http://www.erichynds.com/examples/jquery-idle-timeout/example-mint.htm), or a [demo](http://www.erichynds.com/examples/jquery-idle-timeout/example-dialog.htm) using jQuery UI's dialog widget. 4 | 5 | This script allows you to detect when a user becomes idle (detection provided by Paul Irish's idletimer plugin) and notify the user his/her session 6 | is about to expire. Similar to the technique seen on Mint.com. Polling requests are automatically sent to the server at a configurable 7 | interval, maintaining the users session while s/he is using your application for long periods of time. 8 | 9 | ![Example](http://www.erichynds.com/examples/jquery-idle-timeout/screenshot.gif) 10 | -------------------------------------------------------------------------------- /example-mint.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | jQuery Idle Timeout 5 | 6 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | You will be logged off in  seconds due to inactivity. 18 | Click here to continue using this web page. 19 |
20 | 21 |
22 |

erichynds

23 |
« Return to Blog Post
24 |
25 | 26 |
27 |

jQuery Idle Timeout Demo - Mint.com Style

28 |

This idle timeout countdown is triggered after 5 seconds. Keep your mouse and keyboard still!

29 |

Example

30 |

A polling request is sent to the server every two seconds to keep the server side session alive. I've set this parameter to an extremely low number 31 | for demo purposes (timeout is only 5 seconds), but in reality, this should be much higher.

32 |

View source to see markup & CSS.

33 | 34 | 39 |
40 | 41 | 42 | 43 | 44 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /example-dialog.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | jQuery Idle Timeout 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 |

erichynds

15 |
16 | 17 | 18 |
19 |

20 | 21 | You will be logged off in seconds. 22 |

23 | 24 |

Do you want to continue your session?

25 |
26 | 27 |
28 |

jQuery Idle Timeout Demo - jQuery UI Dialog

29 |

This idle timeout countdown is triggered after 5 seconds. Keep your mouse and keyboard still!

30 |

A polling request is sent to the server every two seconds to keep the server side session alive. I've set this parameter to an extremely low number 31 | for demo purposes (timeout is only 5 seconds), but in reality, this should be much higher.

32 |

View source to see markup & CSS.

33 | 34 | 39 |
40 | 41 | 42 | 43 | 44 | 45 | 46 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /src/jquery.idletimer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery idleTimer plugin 3 | * version 0.8.092209 4 | * by Paul Irish. 5 | * http://github.com/paulirish/yui-misc/tree/ 6 | * MIT license 7 | 8 | * adapted from YUI idle timer by nzakas: 9 | * http://github.com/nzakas/yui-misc/ 10 | 11 | 12 | * Copyright (c) 2009 Nicholas C. Zakas 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining a copy 15 | * of this software and associated documentation files (the "Software"), to deal 16 | * in the Software without restriction, including without limitation the rights 17 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | * copies of the Software, and to permit persons to whom the Software is 19 | * furnished to do so, subject to the following conditions: 20 | * 21 | * The above copyright notice and this permission notice shall be included in 22 | * all copies or substantial portions of the Software. 23 | * 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 30 | * THE SOFTWARE. 31 | */ 32 | 33 | (function($){ 34 | 35 | $.idleTimer = function f(newTimeout){ 36 | 37 | //$.idleTimer.tId = -1 //timeout ID 38 | 39 | var idle = false, //indicates if the user is idle 40 | enabled = true, //indicates if the idle timer is enabled 41 | timeout = 30000, //the amount of time (ms) before the user is considered idle 42 | events = 'mousemove keydown DOMMouseScroll mousewheel mousedown', // activity is one of these events 43 | //f.olddate = undefined, // olddate used for getElapsedTime. stored on the function 44 | 45 | /* (intentionally not documented) 46 | * Toggles the idle state and fires an appropriate event. 47 | * @return {void} 48 | */ 49 | toggleIdleState = function(){ 50 | 51 | //toggle the state 52 | idle = !idle; 53 | 54 | // reset timeout counter 55 | f.olddate = +new Date; 56 | 57 | //fire appropriate event 58 | $(document).trigger( $.data(document,'idleTimer', idle ? "idle" : "active" ) + '.idleTimer'); 59 | }, 60 | 61 | /** 62 | * Stops the idle timer. This removes appropriate event handlers 63 | * and cancels any pending timeouts. 64 | * @return {void} 65 | * @method stop 66 | * @static 67 | */ 68 | stop = function(){ 69 | 70 | //set to disabled 71 | enabled = false; 72 | 73 | //clear any pending timeouts 74 | clearTimeout($.idleTimer.tId); 75 | 76 | //detach the event handlers 77 | $(document).unbind('.idleTimer'); 78 | }, 79 | 80 | 81 | /* (intentionally not documented) 82 | * Handles a user event indicating that the user isn't idle. 83 | * @param {Event} event A DOM2-normalized event object. 84 | * @return {void} 85 | */ 86 | handleUserEvent = function(){ 87 | 88 | //clear any existing timeout 89 | clearTimeout($.idleTimer.tId); 90 | 91 | 92 | 93 | //if the idle timer is enabled 94 | if (enabled){ 95 | 96 | 97 | //if it's idle, that means the user is no longer idle 98 | if (idle){ 99 | toggleIdleState(); 100 | } 101 | 102 | //set a new timeout 103 | $.idleTimer.tId = setTimeout(toggleIdleState, timeout); 104 | 105 | } 106 | }; 107 | 108 | 109 | /** 110 | * Starts the idle timer. This adds appropriate event handlers 111 | * and starts the first timeout. 112 | * @param {int} newTimeout (Optional) A new value for the timeout period in ms. 113 | * @return {void} 114 | * @method $.idleTimer 115 | * @static 116 | */ 117 | 118 | 119 | f.olddate = f.olddate || +new Date; 120 | 121 | //assign a new timeout if necessary 122 | if (typeof newTimeout == "number"){ 123 | timeout = newTimeout; 124 | } else if (newTimeout === 'destroy') { 125 | stop(); 126 | return this; 127 | } else if (newTimeout === 'getElapsedTime'){ 128 | return (+new Date) - f.olddate; 129 | } 130 | 131 | //assign appropriate event handlers 132 | $(document).bind($.trim((events+' ').split(' ').join('.idleTimer ')),handleUserEvent); 133 | 134 | 135 | //set a timeout to toggle state 136 | $.idleTimer.tId = setTimeout(toggleIdleState, timeout); 137 | 138 | // assume the user is active for the first x seconds. 139 | $.data(document,'idleTimer',"active"); 140 | 141 | 142 | 143 | 144 | }; // end of $.idleTimer() 145 | 146 | 147 | 148 | })(jQuery); 149 | -------------------------------------------------------------------------------- /src/jquery.idletimeout.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery Idle Timeout 1.2 3 | * Copyright (c) 2011 Eric Hynds 4 | * 5 | * http://www.erichynds.com/jquery/a-new-and-improved-jquery-idle-timeout-plugin/ 6 | * 7 | * Depends: 8 | * - jQuery 1.4.2+ 9 | * - jQuery Idle Timer (by Paul Irish, http://paulirish.com/2009/jquery-idletimer-plugin/) 10 | * 11 | * Dual licensed under the MIT and GPL licenses: 12 | * http://www.opensource.org/licenses/mit-license.php 13 | * http://www.gnu.org/licenses/gpl.html 14 | * 15 | */ 16 | 17 | (function($, win){ 18 | 19 | var idleTimeout = { 20 | init: function( element, resume, options ){ 21 | var self = this, elem; 22 | 23 | this.warning = elem = $(element); 24 | this.resume = $(resume); 25 | this.options = options; 26 | this.countdownOpen = false; 27 | this.failedRequests = options.failedRequests; 28 | this._startTimer(); 29 | this.title = document.title; 30 | 31 | // expose obj to data cache so peeps can call internal methods 32 | $.data( elem[0], 'idletimeout', this ); 33 | 34 | // start the idle timer 35 | $.idleTimer(options.idleAfter * 1000); 36 | 37 | // once the user becomes idle 38 | $(document).bind("idle.idleTimer", function(){ 39 | 40 | // if the user is idle and a countdown isn't already running 41 | if( $.data(document, 'idleTimer') === 'idle' && !self.countdownOpen ){ 42 | self._stopTimer(); 43 | self.countdownOpen = true; 44 | self._idle(); 45 | } 46 | }); 47 | 48 | // bind continue link 49 | this.resume.bind("click", function(e){ 50 | e.preventDefault(); 51 | 52 | win.clearInterval(self.countdown); // stop the countdown 53 | self.countdownOpen = false; // stop countdown 54 | self._startTimer(); // start up the timer again 55 | self._keepAlive( false ); // ping server 56 | options.onResume.call( self.warning ); // call the resume callback 57 | }); 58 | }, 59 | 60 | _idle: function(){ 61 | var self = this, 62 | options = this.options, 63 | warning = this.warning[0], 64 | counter = options.warningLength; 65 | 66 | // fire the onIdle function 67 | options.onIdle.call(warning); 68 | 69 | // set inital value in the countdown placeholder 70 | options.onCountdown.call(warning, counter); 71 | 72 | // create a timer that runs every second 73 | this.countdown = win.setInterval(function(){ 74 | if(--counter === 0){ 75 | window.clearInterval(self.countdown); 76 | options.onTimeout.call(warning); 77 | } else { 78 | options.onCountdown.call(warning, counter); 79 | document.title = options.titleMessage.replace('%s', counter) + self.title; 80 | } 81 | }, 1000); 82 | }, 83 | 84 | _startTimer: function(){ 85 | var self = this; 86 | 87 | this.timer = win.setTimeout(function(){ 88 | self._keepAlive(); 89 | }, this.options.pollingInterval * 1000); 90 | }, 91 | 92 | _stopTimer: function(){ 93 | // reset the failed requests counter 94 | this.failedRequests = this.options.failedRequests; 95 | win.clearTimeout(this.timer); 96 | }, 97 | 98 | _keepAlive: function( recurse ){ 99 | var self = this, 100 | options = this.options; 101 | 102 | //Reset the title to what it was. 103 | document.title = self.title; 104 | 105 | // assume a startTimer/keepAlive loop unless told otherwise 106 | if( typeof recurse === "undefined" ){ 107 | recurse = true; 108 | } 109 | 110 | // if too many requests failed, abort 111 | if( !this.failedRequests ){ 112 | this._stopTimer(); 113 | options.onAbort.call( this.warning[0] ); 114 | return; 115 | } 116 | 117 | $.ajax({ 118 | timeout: options.AJAXTimeout, 119 | url: options.keepAliveURL, 120 | error: function(){ 121 | self.failedRequests--; 122 | }, 123 | success: function(response){ 124 | if($.trim(response) !== options.serverResponseEquals){ 125 | self.failedRequests--; 126 | } 127 | }, 128 | complete: function(){ 129 | if( recurse ){ 130 | self._startTimer(); 131 | } 132 | } 133 | }); 134 | } 135 | }; 136 | 137 | // expose 138 | $.idleTimeout = function(element, resume, options){ 139 | idleTimeout.init( element, resume, $.extend($.idleTimeout.options, options) ); 140 | return this; 141 | }; 142 | 143 | // options 144 | $.idleTimeout.options = { 145 | // number of seconds after user is idle to show the warning 146 | warningLength: 30, 147 | 148 | // url to call to keep the session alive while the user is active 149 | keepAliveURL: "", 150 | 151 | // the response from keepAliveURL must equal this text: 152 | serverResponseEquals: "OK", 153 | 154 | // user is considered idle after this many seconds. 10 minutes default 155 | idleAfter: 600, 156 | 157 | // a polling request will be sent to the server every X seconds 158 | pollingInterval: 60, 159 | 160 | // number of failed polling requests until we abort this script 161 | failedRequests: 5, 162 | 163 | // the $.ajax timeout in MILLISECONDS! 164 | AJAXTimeout: 250, 165 | 166 | // %s will be replaced by the counter value 167 | titleMessage: 'Warning: %s seconds until log out | ', 168 | 169 | /* 170 | Callbacks 171 | "this" refers to the element found by the first selector passed to $.idleTimeout. 172 | */ 173 | // callback to fire when the session times out 174 | onTimeout: $.noop, 175 | 176 | // fires when the user becomes idle 177 | onIdle: $.noop, 178 | 179 | // fires during each second of warningLength 180 | onCountdown: $.noop, 181 | 182 | // fires when the user resumes the session 183 | onResume: $.noop, 184 | 185 | // callback to fire when the script is aborted due to too many failed requests 186 | onAbort: $.noop 187 | }; 188 | 189 | })(jQuery, window); --------------------------------------------------------------------------------