views:

253

answers:

4

How to implement a gmail-like "this is taking too long" warning message using jQuery Ajax API?

For those who have never seen this message on gmail, it appears when the 'signing in' process takes too long for completion, and then some solutions are suggested.

I'm using jQuery Ajax on my website and I want to warn users when page loading is very slow and then suggest some solutions (a link to refresh the page, or to a help page, for example).

+7  A: 

I'd suggest something as simple as this arrangement:

function tooLong() {
    // What should we do when something's taking too long?  Perhaps show a `<div>` with some instructions?
    $("#this-is-taking-too-long").show();
}

// Then, when you're about to perform an action:
function performSomeAction() {
    var timer = setTimeout(tooLong, 10000);
    $.get('/foo/bar.php', {}, function() {
        // Success!
        clearTimeout(timer);
    });
}
VoteyDisciple
The argument to clearTimeout should be the return value from setTimeout (the timer handle), not the method to be invoked when the timer expires.
tvanfosson
Actually, `clearTimeout` expects timeout id, not the function object as you have it here.
kangax
I've understood the logic and the timeout arrangement, but how setTimeout function works and in which cases it is applicable? I couldn't find it on jQuery documentation.
fjsj
@fjsj - setTimeout is pure javascript, it's not part of jQuery. Try http://www.w3schools.com/htmldom/met_win_settimeout.asp
tvanfosson
Wow: I completely blanked on `clearTimeout` there. I've edited in the fix. fjsj: `setTimeout` is a built-in JavaScript function; it's not part of jQuery. You can find documentation and plenty of examples through Google. All it does is schedule a function to be called some number of milliseconds in advance (in my example 10000 milliseconds, or 10 seconds). `clearTimeout` cancels that scheduled event.
VoteyDisciple
@Votey - I stomped on your edit -- feel free to roll mine back if you made other changes.
tvanfosson
A: 

You could use the ajaxStart() and ajaxStop() messages to show() and hide() your loading indicator.

 $("#loading").ajaxStart(function(){
   $(this).show();
 });

 $("#loading").ajaxStop(function(){
   $(this).hide();
 });
jrummell
I don't want to show a loading indicator. I need to show it only when loading time takes too long (something like a timeout).
fjsj
I missed that part. I would go with VoteyDisciple's answer.
jrummell
+2  A: 

Why not just use the built-in jQuery ajax 'timeout' option. It's a good practice to use it anyways, in case you have issues with your ajax call. Or, you could re-invent the wheel ;)

edit: and, er, I think you would want to couple that with an error function.

jonstjohn
+1 if you are already using the $.ajax method that allows an error callback. If you'd otherwise use get/load/post and only want the this is taking too long message, then using set/clearTimeout would be acceptable.
tvanfosson
You can also use the $.ajaxSetup method - that will affect all ajax calls.
jonstjohn
Bear in mind that the timeout error within $.ajax will actually stop looking for a response from the server, as a result it would be "this couldn't be processed" as opposed to what the OP wanted which is "this is taking too long".
jakeisonline
+2  A: 

the jQuery loading plugin i wrote does this as a default option. here's the demo:

http://jquery-values.googlecode.com/svn/other/loading/jquery.loading.htm

http://plugins.jquery.com/project/loading

Nathan Bubna