How can I delay an ajax call in jQuery? - javascript

Is there a way to delay an ajax request from executing until an animation finished?
var showAjaxLoader = function(selector) {
$("." + selector).fadeToggle("slow");
$("." + selector).parent().html('<img src="ajax-loader.gif" />').fadeIn();
};
$(".add, .delete")
.bind("ajax:beforeSend", function(event, data, status, xhr) {
showAjaxLoader(this.className);
});
Basically, the response of the request will replace the lay contents, but I don't want this to happen until the effect took place. Otherwise the image will just pop up with no effect...

U can use a callback methode for when the animation is finished:
$("p").fadeToggle("slow", function () {
$("div").append("<div>finished animation</div>");
// Here you can put your ajax request
});

Just use callback, as in the .fadeToggle(), .fadeIn() and .fadeOut() documentation. Make AJAX call within this callback.
And I believe you do not want to make request even when fading out that box (at least I don't see the reason here), but only when fading in.

Related

Spinner button that starts spinning when function is called and stops when it ends

I'm trying to make a spinner button that will spin while I make an AJAX request and stop when the answer is received.
I've got the AJAX handled but the spinning doesn't seem to work with the following code:
function refresh (id){
var iconElem = document.getElementById("spinner" + id);
iconElem.classList.add('fa-spin');
sleep(5000);
var buttonRefresh = document.getElementById("refreshButton" + id);
buttonRefresh.classList.remove("fa-spin");
};
Note : I have replaced the ajax function with a sleep (implemented elsewhere, but it works like like it should) since I am in a non-php environment.
What happens here is that the the class "fa-spin" is being added while the sleep is over, even though it comes after in the code... Am I missing some kind of "refresh" that I need to execute in order to make the added class effective ?
You need to stop the spinning in the completion callback of the ajax call as it is a async call.
What you are doing here is starting and then immediately stopping the spinner before the ajax call even finishes.
$.ajax({
url: "test.html",
cache: false,
success: function(html){
// stop the spinner here
}
});
Here is the simplest solution with a callback:
function sleep(callback,timeout){
setTimeout(callback,timeout)
}
sleep(() => {
//stop spinner here
},200)
Anyways, I suggest you to read more here
If you are doing an ajax request, you can also use the async:false header to make your request synced, and then your code should work.
Changes to the style or content of the document become effective only when the JavaScript function finishes and returns to the main event loop. Therefore, assuming your sleep() function works as expected (by doing a busy wait or something like that, although that is not actually sleeping), you can only see the total effect of all changes when the function returns. If you follow the advice of the other answers and remove the style in the callback of the AJAX call, you will be fine.

Ajax auto refresh blinks every time when loading

i'm developing a web page which has a div with a class called headlines, it auto refreshes every 10 seconds and the problem is when whenever the data loads into the div, it blinks and i want to get rid of it.
$(document).ready(function() {
setInterval(function() {
$('.headlines').load('headlines.php');
}, 10000);
});
You're not going to get rid of the blinks if you use .load(). It blinks because it initializes a request, clears the .headlines, and loads the response from the server. This response is not instantaneous.
What you could do instead is use $.ajax, and in the success method, rewrite the content of .headlines.
Edit
Think of it this way... If the response were to never load, then when you use .load(), it would be waiting for a response. During that wait period, the .headlines would be indefinitely blank.
Instead, what you can do is wait for a server response outside the context of .headlines.
setInterval(function() {
$.ajax({
url: 'your-url.html',
success: function(res) {
$('.headlines').html(res.data);
}
});
}, 10000);
You'll need to look at the jQuery documentation.
Like Josh Beam said, you need to use either the $.get() function to do the work! So update your code like:
$(document).ready(function() {
setInterval(function() {
$.get('headlines.php', function (data) {
$('.headlines').html(data);
});
}, 10000);
});
The $.load() function will blink. So we can use any other AJAX function, probably, $.ajax() or $.get() and inside the success function, we can update the .html() of the .headlines.

$.post() callback method suggestion

I always used something like this:
$("a.button").click(function() {
data = ...;
url = ...;
$.post(url, data, function() {
$(this).toggleClass('active');
});
});
The problem is when an user has a slow connection and clicks on that button, it doesn't seems to do anything, because the button will change the own status (adding the active class) once the request is complete. Of course I can "fix" this behavior by adding a spinner while the request is loading.
Now check out this one:
$("a.button").click(function() {
$(this).toggleClass('active');
data = ...;
url = ...;
$.post(url, data, function() {
// if request is successful do nothing
// else, if there's an error: $(this).toggleClass('active)
});
});
In other words, I change the button status instantly when the button is pressed and after this, I check for success/error. Is this a good way? What you think about? Are there other ways?
This is more of a UI question than code. Personally I prefer to show the spinner in cases where it could be confusing if there is no response. Since I don't know what class you're toggling and what effect it has on the element, I wouldn't know if toggling before success would be confusing at all.
One way or another, everyone alive knows the loading spinner. It's probably safe to go with that.
You've got the general idea there. You can implement it in other ways, for instance by setting global AJAX ajaxStart and ajaxSuccess functions:
$("a.button").click(function() {
data = ...;
url = ...;
$.post(url, data, function() {
// if request is successful do nothing
});
}).ajaxStart(function () {
$(this).toggleClass('active');
}).ajaxComplete(function () {
$(this).toggleClass('active');
}).ajaxError(function () {
//never forget to add error handling, you can show the user a message or maybe try the AJAX request again
});
These methods register handlers to be called when certain events, such
as initialization or completion, take place for any AJAX request on
the page. The global events are fired on each AJAX request if the
global property in jQuery.ajaxSetup() is true, which it is by default.
Note: Global events are never fired for cross-domain script or JSONP
requests, regardless of the value of global.
Source: http://api.jquery.com/category/ajax/global-ajax-event-handlers/
Use $.ajax success:
From jquery docs:
$.ajax({
url: "test.html",
success: function(){
$(this).addClass("done");
}
});
You could do something like:
$("a.button").click(function() {
var old_text = $(this).text();
var button = $(this);
$(this).text('Processing...');
$(this).attr('disabled', 'disabled'); // disable to button to make sure it cannot be clicked
data = ...;
url = ...;
$.post(url, data, function() {
// after request has finished, re-enable the link
$(button).removeAttr('disabled');
$(button).text(old_text);
});
});
Next thing, you should do something similar for catching errors (re-enable the button).
It always depends the way you've built your site, but in my opinion the active state should only be triggered at the instant you click.
So that should be: onmousedown you add your class and onmouseup you remove it.
The Ajax call could trigger a different function maybe showing a loading dialog/spinner.
There are several ways of building it: individually on each element as you did, or through a general styling function. Same for Ajax with the ajaxStart ajaxComplete functions as Jasper said.
Personally I'm using Ajax intensively, always changing the DOM dynamically, so I use livequery to setup style changing with events automatically when elements with given class(es) appear in the DOM, and I use ajaxStart and ajaxComplete for displaying a loading dialog.

Wait For Timer To Finish Before Function Runs

I think this fairly basic but I can't seem to find one on-line. This can be in JavaScript or jquery.
I need to create a timer for about a 1-2 seconds.
Meanwhile another function is using ajax to pass data to a server side php file. When the response text gets back it displays it on the page.
At the moment I have the ajax function running and the time taken for the function to complete is about 0.1 seconds. But this makes the page look really jumpy as the content changes css styles while the ajax is waiting for a response and then back to the original on return (hope that makes sense).
Anyway to combat this I would like the function to check if the timer has ended before displaying the response text.
The only way I can get it at the moment is by creating a interval timer for a second and running the ajax function when that completes, but this is not ideal as the viewer MUST wait the extra second or 2 even if the request to the server takes over that time to complete.
Hope All Of That Makes Sense & Thanks Very Much For Your Time.
Chris
You're better off attaching your function as a "success" handler to your AJAX call rather than using a fixed timer. How you attach it depends on which library, if any:
jQuery 1.4 style (still works in 1.5)
$.ajax({
// your AJAX options
success: yourFunc
});
jQuery 1.5 style
$.ajax({
// your AJAX options
}).done(yourFunc);
DOM style
// after creating your XHR
xhr.onreadystatechange = function() {
if (this.readyState === 4) { // 4 means the request has completed
if (this.status !== 200) { // 200 is success, so anything else...
// log or report error
return;
}
// call your other function, which uses the AJAX data
yourFunc(this.responseText);
}
};
I would use a setTimeout or the jQuery .delay() if a timer is your only option.
$.ajax({
success: function() {
setTimout(function() {
// styling code goes here
}, 1000);
}
});

jquery ajax synchronous call beforeSend

I have a function called:
function callAjax(url, data) {
$.ajax(
{
url: url, // same domain
data: data,
cache: false,
async: false, // use sync results
beforeSend: function() {
// show loading indicator
},
success: function() {
// remove loading indicator
}
}
);
}
In the code, I call "callAjax" X number of times and I want to update the data synchronously. It is done as expected, but one problem: the loading item doesn't show in beforeSend function. If I turn async to true, it works but the updates aren't synchronously done.
I've tried several things with no success. I tried putting the loading indicator before the ajax call like this:
function callAjax(url, data) {
// show loading div
$.ajax(
{
// same as above
}
);
}
But for some reason it doesn't want to show the loading indicator. I notice a strange behavior when I put an "alert" in the beforeSend and the loading indicator appears in that case, but I rather not pop up a message box.
Got any ideas?
Making a synchronous call like that is like putting up an "alert()" box. Some browsers stop what they're doing, completely, until the HTTP response is received.
Thus in your code, after your call to the "$.ajax()" function begins, nothing happens until the response is received, and the next thing as far as your code goes will be the "success" handler.
Generally, unless you're really confident in your server, it's a much better idea to use asynchronous calls. When you do it that way, the browser immediately returns to its work and simply listens in the background for the HTTP response. When the response arrives, your success handler will be invoked.
When you do the blocking I/O the program is halted until the the input is received, in JS words when doing a synchronous call, the program halts and browser window freezes (no painting can be done) until the response is received. In most cases doing syncronus calls and any kind of blocking I/O can be avoided. However imagine your doing a progress bar in java or any other programming language, you have to spawn a different thread to control the progress bar, I think.
One thing to try in your case, is to call the ajax call after a time delay
//loading div stuff,
//if your doing some animation here make sure to have Sufficient
//time for it. If its just a regular show then use a time delay of 100-200
setTimeout( ajaxCall, 500 );
EDIT ajaxcall in setTimeout, Example
This is what you are looking for - .ajaxStart()
It will be triggered when any ajax event starts
http://api.jquery.com/ajaxStart/
They even give a specific example similar to what you are trying to accomplish:
$("#loading").ajaxStart(function(){
$(this).show();
});
You can then use the .ajaxStop() function
$("#loading").ajaxStop(function(){
$(this).hide();
});

Categories