Is there a way to check if there's ajax request in progress?
Something like:
if ( $.ajax.inProgress ){ do this; } else { do that; }
yes there is
$.ajax({
type: 'get',
url: 'url',
data: {
email: $email.val()
},
dataType: 'text',
success: function(data)
{
if(data == '1')
{
$response.attr('style', '')
.attr('style', "color:red;")
.html('Email already registered please enter a different email.');
}
else
{
$response.attr('style', '')
.attr('style', "color:green;")
.html('Available');
}
},
beforeSend: function(){
$email.addClass('show_loading_in_right')
},
complete: function(){
$email.removeClass('show_loading_in_right')
}
});
the beforeSend will do the process you need to do when the ajax request has just started and complete will be called when the ajax request is complete.
documentation
To abort ajax request,
Use
if($.active > 0){
ajx.abort();//where ajx is ajax variable
}
To continue running ajax request,
Use
if($.active > 0){
return;
}
You should basically set a variable on top of script set to false and on ajax initiate set it to true and in the success handler set it to false again as described here.
You might like this:
$(document).ready(function() {
var working = false;
$("#contentLoading").ajaxSend(function(r, s) {
$(this).show();
$("#ready").hide();
working = true;
});
$("#contentLoading").ajaxStop(function(r, s) {
$(this).hide();
$("#ready").show();
working = false;
});
$('#form').submit(function() {
if (working) return;
$.post('/some/url', $(this).serialize(), function(data){
alert(data);
});
});
});
If you are in full control of the javascript code you could increment a variable whenever you start an ajax request and decrement it when the request completes (with success, failure or timeout). This way you always know if there is a request in progress.
Related
I have a following ajax operation that is intended to (1) show spinner gif before sending ajax request, and after after the request is complete, (2) hide the gif and 3 display appropriate alert messages.
Finally (4) reload the page.
Here's the code:
$.ajax({
url: rUrl,
data: {
id: rID,
requisitionStatus: rStatus,
comment: rComment
},
type: "POST",
cache: false,
beforeSend: function() {
$("#requisitionStatusDialog").dialog('close');
$('#ajax_loader_my').show();
},
success: function(data, resp) {
var json = data;
var obj = JSON && JSON.parse(json) || $.parseJSON(json);
if (obj.status == "success") {
alert('Success! ' + obj.message);
location.reload();
} else if (obj.status == "error") {
alert('Error!' + obj.message);
}
},
error: function(data, resp) {
$("#updateDialog").dialog('close');
console.log(resp);
},
complete: function() {
$('#ajax_loader_my').hide();
}
});
But in this case, alert pops up first while the spinner gif still shows up, and reloads the page after clicking OK.
I even tried hiding the gif in success callback itself instead of using complete:
success: function(data, resp) {
var json = data;
var obj = JSON && JSON.parse(json) || $.parseJSON(json);
if (obj.status == "success") {
$('#ajax_loader_my').hide();
alert('Success! ' + obj.message);
location.reload();
} else if (obj.status == "error") {
alert('Error!' + obj.message);
}
},
Both gives the same result.
The reason your alert pops up before the spinner is hidden is the success code runs before complete which hides the spinner. The reason it reloads is because after the alert you send location.reload();
Check that $('#ajax_loader_my').hide(); is actually hiding the spinner. The element that is or contains the spinner in your html must be have its id set to ajax_loader_my.
If you open Chrome or Firefox Dev tools you should be able to send $('#ajax_loader_my').hide() and see what happens.
Rewrite the code this way, this will put your alert and location related code in event queue which will run when it will be free.
if(obj.status=="success") {
$('#ajax_loader_my').hide();
setTimeout(function(){
alert('Success! '+obj.message);
location.reload();
},0);
}
Hi you should try to use promises here is the documentation Jquery promises, I made this on the fly it can have some errors but is just an example:
$( function() {
function AjaxCall(rID,rStatus,rComment){
return $.ajax({
url: 'request.php',
data: {
id: rID,
requisitionStatus: rStatus,
comment: rComment
},
type: "POST",
cache: false,
beforeSend: function() {
$("#requisitionStatusDialog").dialog('close');
$('#ajax_loader_my').show();
}
})
}
$( "#requisitionStatusDialog" ).dialog();
$("#yourbuttonInputId").on('click',function(event) {
AjaxCall().done(function(data,response){
var obj = JSON.parse(data);
if (obj.status == "success") {
alert('whe are on done!');
}
}).fail(function(data,response){
$("#updateDialog").dialog(' close');
}).always(function(data){
if(confirm('You have finished the request. Click OK if you wish to continue ,click Cancel to reload the page.'))
{
$('#ajax_loader_my').hide();
$("#requisitionStatusDialog").dialog('open');
}else{
location.reload();
}
});
});
} );
EDIT: Check this jsfiddle it will guide you to elaborate your code
Hope it Helps
I would rather suggest to use an empty div or span with an Id.
Than display success in the html of that div.
For Example:
$('#ajax_loader_my').hide();
setTimeout(function () {
$('#successDiv').html('Success! ' + obj.message);
location.reload();
}, 2000);
I wanted to make an ajax call, and then wait for the response from ajax call (Stop form submission till then) and then post the form based on the ajax response that I get. This question is based on Make ajax call and then submit form. So, after putting below script, everything works fine, but I lose the client side validation. Can I make an ajax call and still respect the Client Side validation?
#section scripts {
<script>
var canSubmit = false;
$('form').submit(function (e) {
if (!canSubmit) {
e.preventDefault();
var data = $('form').serialize();
var url = $(this).data('url');
$.ajax({
url: url,
type: 'POST',
data: data,
success: function (response) {
if (response.hasPreviousRequest) {
if (confirm("You've already applied for this job. Apply again?")) {
canSubmit = true;
$('form').submit();
}
}
else {
canSubmit = true;
$('form').submit();
}
},
error: function () {
alert("error");
}
});
}
});
</script>
}
P.S: Kindly note that as soon I as remove the ajax call Client side validation starts working fine. Can some one please explain me this behaviour?
You need to call the .valid() method on the form element (and if not, then cancel the ajax call)
$('form').submit(function (e) {
if (!$(this).valid()) {
return // exit
}
if (!canSubmit) {
....
I'm a little new to jQuery framework and while using AJAX with normal javascript I used readyState() function to display a loading gif image. But, I don't know how to use that in jQuery .post() method. Was it possible to add a class until it finishes loading? If so, please give a code sample. My function is similar to this:
$.post("verify.php",{
username: u,
password: p
},function(r) {
if(r == 1) {
$(".elmt").addClass("loading");
} else if (r == 0) {
location.href = 'http://localhost';
}
});
I always prefer using $.ajax for things like this as it has more options than the shortcuts :
$.ajax({
type: 'POST',
url : 'verify.php',
data: {
username: u,
password: p
},
beforeSend: function () {
$(".elmt").addClass("loading"); // add loader
}
}).always(function() { // always executed
$(".elmt").removeClass("loading"); // remove loader
}).done(function(r) { // executed only if successful
if (r == 0) {
location.href = '/';
}
});
Just call the addClass before the $.post() and be done with it
$(".elmt").addClass("loading");
$.post("verify.php", {
username: u,
password: p
}, function (r) {
location.href = 'http://localhost';
});
You could fire a custom event before starting your AJAX request.
Then in your success function, fire another to stop.
Or if you just want the loading animation:
$(".elmt").addClass("loading");
$.post("verify.php",{
username: u,
password: p
},function(r) {
$(".elmt").removeClass("loading");
// etc...
});
There is a global way to do this using ajaxStart() and ajaxStop(). See How to show loading spinner in jQuery?
If you need to do for all your requests. You could try:
$(document).ajaxStart(function(){
$(".elmt").addClass("loading");
});
$(document).ajaxStop(function(){
$(".elmt").removeClass("loading");
});
But it's not so cool to always display the loading when the request takes little time as it will cause the screen flicking. Try:
var timer;
$(document).ajaxStart(function(){
timer = setTimeout(function(){
$(".elmt").addClass("loading");
},1500);
});
$(document).ajaxStop(function(){
clearTimeout(timer);
$(".elmt").removeClass("loading");
});
By adding a timer, only requests that take longer than 1.5 seconds should be considered long and display a loading icon.
As you see on code below you can do your work on different results of post method
// Assign handlers immediately after making the request,
// and remember the jqxhr object for this request
var jqxhr = $.post("example.php", function() {
alert("success");
})
.done(function() { alert("second success"); })
.fail(function() { alert("error"); })
.always(function() { alert("finished"); });
// perform other work here ...
// Set another completion function for the request above
jqxhr.always(function(){ alert("second finished"); });
I have a procedure running on a timeout to load data in the background:
(function getSubPage() {
setTimeout(function() {
if (cnt++ < pagelist.length) {
loadSubPage(pagelist[cnt]);
getSubPage();
}
}, 500);
})();
In loadSubPage() I'm making $.ajax() calls:
function loadSubPage(page) {
if (typeof(initSubPages[page]) === "undefined") {
$.ajax({
type: "POST",
url: '/Main/GetPageData',
data: { page: page },
success: function (returndata) {
// ...
},
error: function() {
alert("Error retrieving page data.");
}
});
initSubPages[page] = true;
}
}
The problem I'm having is that the error handler is being hit when the user navigates away if any ajax requests are open. I'm trying to get around this by .stop()ing the requests on window.onbeforeunload, but I'm not sure what object to call .stop() on?
jQuery exposes the XMLHttpRequest object's abort method so you can call it and cancel the request. You would need to store the open request into a variable and call abort().
activeRequest = $.ajax({...
and to stop it
activeRequest.abort()
Abort Ajax requests using jQuery
This should come in handy.. You have a jQuery method for doing just that.
The $.ajax returns XMLHTTPRequestObject which has .abort function. This function will halt the request before it completes.
var xhr = $.ajax({ /*...*/
..
..
/* Later somewhere you want to stop*/
xhr.abort();
Read more: How to cancel/abort jQuery AJAX request?
Here is the solution I used based on the feedback:
window.onbeforeunload = function() {
for (page in ajaxing) {
if (ajaxing[page] != null)
ajaxing[page].abort();
}
};
var ajaxing = {};
function loadSubPage(page) {
if (typeof(initSubPages[page]) === "undefined") {
var ajaxRequest = $.ajax({
type: "POST",
url: '/Main/GetPageData',
data: { page: page },
success: function (returndata) {
// ...
},
error: function() {
alert("Error retrieving page data.");
},
complete: function() {
ajaxing[lot] = null;
}
});
ajaxing[page] = ajaxRequest;
initSubPages[page] = true;
}
}
function checkuser(user) {
var ret = false;
$.ajax({ type:'POST', url:'user.php',
async:false,
data:{'user':user},
success:function (data) {
if (data == 1) ret = true
} });
return ret;
}
I use bvalidator to validate fields. It seems to fire this function on every keypress and the user is not able to continue typing before the ajax call is competed. I'm not really sure what to do here.
How could I make the function not be ran more than once every two seconds for example?
You need to get rid of async:false but you also need to modify your code to work asynchronously. The synchronicity is what is causing your UI to 'freeze'.
Maybe you could try setting a timeout that will run 2 seconds after a key is pressed on your input, but if another key is pressed it restarts that timer. So in essence it will only after two seconds of no keystrokes.
var validateTimeout;
$('#target').keydown(function() {
clearTimeout(validateTimeout);
validateTimeout = setTimeout(function(){checkuser(user);},2000);
});
You'll need to update the checkuser ajax call to have a smarter callback to work async:
function checkuser(user) {
$.ajax({ type:'POST', url:'user.php',
async:false,
data:{'user':user},
success:function (data) {
if(data == 1){
//something to indicate sucess
}else{
//something to indicate failure
}
} });
}
You could throttle the call with a throttle plugin:
jQuery Throttle Plugin