tags:

views:

172

answers:

2

I've got a checkout page which has some ajax calls that update hidden fields when the user changes delivery country for instance.

Most of the time, this works fine, the page has time to update hidden fields before the user clicks submit. Some of the time though, due to slow connection or whatever the ajax doesn't return the hidden fields in time and the user is allowed to submit an incomplete form.

After reading another question on here, I am using ajaxStart and ajaxComplete to disable and re-enable the submit button of the form.

I also want to display a 'please wait' message next to the button to keep the user informed of what is happening.

This all works fine, but in 99% of the cases this message flashes and disappears quickly, too quick to read and looking distracting / buggy.

What I would like to do is only show this message if the ajax call is taking a long time to respond (indicating we've got a slow connection) - say 250ms?

I've not used timers in jquery before so this will hopefully help me get to grips with the concepts involved.

Here is the function so far

// if we're waiting for any ajax to complete we need to disable the submit
$(document).ajaxStart(function() {
  $(".ajaxbutton").attr("disabled", "disabled");
  // if it's taken longer than 250ms (say) display waiting message
      $('#processingAlert').html(' ...please wait one moment');
      $('#processingAlert').show();
      // end the if here
})
$(document).ajaxComplete(function() {
  $(".ajaxbutton").removeAttr("disabled");
    $('#processingAlert').hide();
});

I know it's a very basic question and I could easily do it in PHP but i'm a novice to jquery so I need a bit of beginners help!

Thanks!

A: 

Try:

function hideAlert() {
  $('#processingAlert').hide();
}

$(document).ajaxComplete(function() {
  $(".ajaxbutton").removeAttr("disabled");
  setTimeout(hideAlert, 1000); // or whatever delay you feel is appopriate, in ms
});

See http://www.w3schools.com/js/js_timing.asp

In addition, I would suggest taking a look at the very pretty blockUI plugin. That would allow you to do something like this:

$.blockUI.defaults.fadeOut = 1000;
$.blockUI.defaults.message = '<h3>...please wait one moment</h3>';

$(document).ajaxStart(function() {
    $(".ajaxbutton").attr("disabled", "disabled");
    $.blockUI;
}).ajaxComplete(function() {
    $(".ajaxbutton").removeAttr("disabled");
    $.unblockUI
});
karim79
Hi, that's not exactly the question I was asking (I only want to show the alert if a certain amount of time has passed during ajaxStart) but I see what you are doing. I will read the tutorial and see if I can learn what I wanted to do. Thanks!
Ashley
Hi, thanks for the blockUI suggestion, but I want this to be unobtrusive. In fact invisible for 99%+ of users - it's only if they have a slow connection or some sort of delay that I want them to see anything, just a small 'please wait' next to the checkout button.
Ashley
+1  A: 

setTimeout is your friend here.

something along the lines of the below should work, although I haven't tested it for typos etc.

// if we're waiting for any ajax to complete we need to disable the submit
$(document).ajaxStart(function() {
  $(".ajaxbutton").attr("disabled", "disabled");
  // if it's taken longer than 250ms (say) display waiting message
  timer = setTimeout(function() {
    $('#processingAlert').html(' ...please wait one moment');
    $('#processingAlert').show();
  }, 250);
})
$(document).ajaxComplete(function() {
  $(".ajaxbutton").removeAttr("disabled");
    $('#processingAlert').hide();
    // cancel showing the message when the ajax call completes.
    clearTimeout(timer);
});
Seb Pollard
Great! Exactly what I was looking for - that's a great simple function to learn, thanks!
Ashley
Does this mean that all AJAX calls on this page would be held to these two functions?
patridge
Yes I think so - as far as I am aware $(document).ajaxStart and $(document).ajaxComplete are fired at the start and end of any ajax call on the page
Ashley