Calling a function until jQuery .post finishes loading - javascript

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"); });

Related

Prototype Ajax.Updater evaluate string before the update

here's my code:
new Ajax.Updater('container', url, {
method: "get",
onLoading: function () {
document.getElementById('container').innerHTML = "Loading...";
},
on200: function(response) {
if(response.responseText.match(/WhatImLookingFor/)) {
window.location = "leNewURL";
}
},
onComplete: function(response) {
//do other cool stuff
}
});
What I'm trying to do is intercept the response before container gets updated and if the text in the response matches WhatImLookingFor, I want to redirect the user to leNewURL. With the code above this is happening, but not before the update, so it looks quirky. Is there anyway that I can intercept right before the update happens or do I have to resort to other hacks like hiding container and show it only if there's no match?
If you want to customize the behavior of your Ajax call like that I would recommend using the base Ajax.Request() http://api.prototypejs.org/ajax/Ajax/Request/
new Ajax.Request(url, {
method: "get",
onLoading: function () {
$('container').update("Loading...");
},
onComplete: function(response) {
if(response.responseText.match(/WhatImLookingFor/)) {
window.location = "leNewURL";
}
else {
//do other cool stuff
$('container').update(response.responseText);
}
}
});
I swapped out the document.getElementById() with the $() utility method as its less to type and includes all of PrototypeJS's Element methods

Stopping an $.ajax call on page unload

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;
}
}

javascript does not reconnect to server side if connection is lost

I have Jquery+Ajax page that connects to server gets some data, and displays it. This is done all the time, function calls itself after it completes all task and starts to perform again and again. But If komputer loses internet connection everything stops. And when connections comes back again, nothing happens. Here is javascript code. How can I iprove it so it will continue to work after connection is back again.
$(document).ready(function() {
var a=1;
var max='23';
function kiosk()
{
if(a<max)
{
$.post('engine.php', { index: a },
function(result)
{
result = jQuery.parseJSON(result);
$('#main').css({'display':'none'});
$('#div_city').html(result.dest);
$('#div_price').html(result.price);
$('#div_price_pre').html('From ');
$('#div_price_after').html(' Euro');
$('#main').fadeIn(2000).delay(3000).fadeOut(2000, function()
{
$('#main').hide;
a++;
kiosk();
});
});
}
else
{
a=1;
kiosk();
}
}
kiosk();
});
I would suggest rather than using $.post you use
$.ajax({ type: "post" , success : function1() , failure: function2() }.
In function2() you can call koisk again after a timeout. and the succces would be the function you have created right now.
This link will help you understand the ajax function jQuery Ajax error handling, show custom exception messages
Eg Code snippet:
function kiosk()
{
if(a<max)
{
$.ajax({type : "POST" , url : 'engine.php',data: { index: a },
success : function(result)
{
result = jQuery.parseJSON(result);
$('#main').css({'display':'none'});
$('#div_city').html(result.dest);
$('#div_price').html(result.price);
$('#div_price_pre').html('From ');
$('#div_price_after').html(' Euro');
$('#main').fadeIn(2000).delay(3000).fadeOut(2000, function()
{
$('#main').hide;
a++;
kiosk();
});
},error : function (xhr, ajaxOptions, thrownError){ setTimeout(200,kiosk()) }
});
}
else
{
a=1;
kiosk();
}
}
kiosk();
});`
Using jQuery.post you are passing a callback which is executed only on success.
You should use jQuery.ajax which has different callbacks. See documentation with complete, success and error callbacks.
You could even use statusCode to map a specific HTTP code to a custom function.
Script brokes because i think it throws exception. You can add your code try and catch block, and even if has errors you can continue to try.
try {
result = jQuery.parseJSON(result);
// do your work
} catch {
// call function again
}
Or you can use, jquery ajax, it has a onerror event.

weird problem - change event fires only under debug in IE

I have form autocomplete code that executes when value changes in one textbox. It looks like this:
$('#myTextBoxId)').change(function () {
var caller = $(this);
var ajaxurl = '#Url.Action("Autocomplete", "Ajax")';
var postData = { myvalue: $(caller).val() }
executeAfterCurrentAjax(function () {
//alert("executing after ajax");
if ($(caller).valid()) {
//alert("field is valid");
$.ajax({ type: 'POST',
url: ajaxurl,
data: postData,
success: function (data) {
//some code that handles ajax call result to update form
}
});
}
});
});
As this form field (myTextBoxId) has remote validator, I have made this function:
function executeAfterCurrentAjax(callback) {
if (ajaxCounter > 0) {
setTimeout(function () { executeAfterCurrentAjax(callback); }, 100);
}
else {
callback();
}
}
This function enables me to execute this autocomplete call after remote validation has ended, resulting in autocomplete only when textbox has valid value. ajaxCounter variable is global, and its value is set in global ajax events:
$(document).ajaxStart(function () {
ajaxCounter++;
});
$(document).ajaxComplete(function () {
ajaxCounter--;
if (ajaxCounter <= 0) {
ajaxCounter = 0;
}
});
My problem is in IE (9), and it occurs only when I normally use my form. Problem is that function body inside executeAfterCurrentAjax(function () {...}); sometimes does not execute for some reason. If I uncomment any of two alerts, everything works every time, but if not, ajax call is most of the time not made (I checked this by debugging on server). If I open developer tools and try to capture network or debug javascript everything works as it should.
It seems that problem occurs when field loses focus in the same moment when remote validation request is complete. What I think it happens then is callback function in executeAfterCurrentAjaxCall is executed immediately, and in that moment jquery validation response is not finished yet, so $(caller).valid() returns false. I still do not know how alert("field is valid") helps in that scenario, and that could be sign that I'm wrong and something else is happening. However, changing executeAfterCurrentAjaxCall so it looks like this seems to solve my problem:
function executeAfterCurrentAjax(callback) {
if (ajaxCounter > 0) {
setTimeout(function () { executeAfterCurrentAjax(callback); }, 100);
}
else {
setTimeout(callback, 10);
}
}

Ajax request in progress jQuery

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.

Categories

Resources