Showing a loading div during a jQuery ajax call - javascript

Im trying to show a loading div while waiting for an ajax call to complete. I have tried a couple of methods but cant seem to get anything to work consistently.
with my current code it works if i have a break point on the function that shows the div once the ajax is complete.
Fiddle
var https = 'https://www.googleapis.com/calendar/v3/calendars/';
function HideCheckShowLoading(checkId) {
$("#check_" + checkId).hide('slow', function() {
$("#loading_" + checkId).show('slow');
});
};
function HideLoadingShowCheck(checkId) {
$("#loading_" + checkId).finish().hide('slow', function() {
$("#check_" + checkId).finish().show('slow');
});
};
$(document).ready(function() {
$('#get').click(function() {
HideCheckShowLoading(1);
$.ajax({
url: https,
dataType: 'jsonp',
type: "GET",
success: function(response) {
//do something
},
error: function() {
//do something else
}
}).done(function() {
HideLoadingShowCheck(1)
});
});
$('#get2').click(function() {
HideLoadingShowCheck(1);
});
});
#check_1
{
background-color:red;
}
#loading_1
{
background-color:blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="check_1">Check</div>
<div hidden id="loading_1">LOADING</div>
<button id="get">Get</button>
<button id="get2">Get2</button>
What i would like to happen is,
on the click of a button we hide the check div
we show the loading div
make the ajax call
if successful do something(Reload the contents of the check div)
hide the loading div
show the check div
As said I have tried a few methods that i have found but i repeatedly get stuck with just the loading div shown
Thanks

I believe you may be slightly over-complicating things here. Something simple like this would suffice:
$('#get').click(function() {
HideCheckShowLoading();
$.ajax({
url: https,
dataType: 'jsonp',
type: "GET",
success: function (response) {
//do something
},
error: function() {
//do something else
},
complete: HideLoadingShowCheck
});
});
If you don't want the HideLoadingShowCheck routine to happen after success or error (standard behavior of complete), you can just move a function call HideLoadingShowCheck(); into your success and error blocks instead of using complete.

When you add () to a function name, it calls it immediately and returns the result. What you want to do is pass the function itself, not the result of the function - and you do that without the ().
There's no need for the $.when (assuming HideCheckShowLoading() doesn't make an ajax call, the jquery animations work differently), and $.ajax returns the promise itself, so you can update your code to:
$(document).ready(function() {
$('#get').click(function() {
HideCheckShowLoading();
$.ajax({
url: https,
dataType: 'jsonp',
type: "GET",
success: function (response) {
//do something
},
error: function() {
//do something else
}
})
//.done(HideLoadingShowCheck);
.done(function() { HideLoadingShowCheck(otherparams); })
});
});
I would change the showcheck function to add .finish() incase it's still animating from the showhide:
function HideLoadingShowCheck() {
$("#loading").finish().hide('slow',function () {
$("#check").finish().show('slow');
});
};

Related

How to check if my container fully load is completed?

I have an issue, do not know if it possible or not, how to check if my container is already loaded or not, because sometimes it is being loaded faster, sometimes slower and if it does not succeed in time getting an error in javaScript where gridview some functions are not recognizable(because the gridview is not loaded fast enough). Hope it is clear. Thanks for Your time.
Code:
function LoadPartial(partialUrl, container) {
$.ajax({
type: 'POST',
url: partialUrl,
success: function (returnData) {
$(container).html(returnData);
}
});
//.done(function () {
// return;
//});
}
you can use something like this.
$(".container").load(function (){
alert("Loaded :)");
});
Let me know in-case this doesn't work.
You can try using .data()
if ($('#mycontainer').data('loaded')) {
// your code
}
If you mean to find event when data received use "complete" function:
$.ajax({
type: 'POST',
url: partialUrl,
success: function (returnData) {
$(container).html(returnData);
},
complete: function() {
console.log('container filled with data');
}
});

FadeIn after ajax jquery

I have a problem with an animation (fadeIn). It doesn't work after ajax. There is just NO ANIMATION but the content appears.
My code is like:
function ajax(varia) {
return $.ajax({
dataType: "html",
async: false,
type: 'POST',
url: 'index.php?fn=' + varia,
data: { token: "mytoken" }
});
}
Function with ajax works fine...
ajax("login").done(function (data) {
$("body").prepend(data);
}).done(function () {
// The #login have atribute style="display: none;"
$("#login").fadeIn(500);
});
This problem can be resolved with using delay before the fade, but i think it should be fine without this. Why it's not?
Thats probably because JavaScript is an asynchroneus language. What you are experiening is a synchronization issue:
Your ajax is done, you are firing DOM manipulation (prepend()), and imidiately after you fire it you do the fadeIn() but the fadeIn is complete before your data is prepended, so probably you'are calling fadeIn() on an element that doesn't exist yet.
Try this:
ajax("login").done(function (data) {
$("body").prepend(data);
setTimeout(function(){
$("#login").fadeIn(500);
},0);
});
And read this to understand why using timeout 0 is sometimes helpful: Why is setTimeout(fn, 0) sometimes useful?
By wrapping your action with setTimeout function you are basically telling: "wait until everything is done before doing this".
Here's the fiddle: jsFiddle
Did you try to put both calls into the same .done()-Block?
I think this should work:
ajax("login", "html").done(function (data) {
$("body").prepend(data);
// The #login have atribute style="display: none;"
$("#login").fadeIn(500);
});
In this case it should be guaranteed that the two lines of code are executed
successively.
I've made an live example here: http://jsfiddle.net/xLo93d29/
For me it works.
You should use "success" instead of "done":
function ajax(varia) {
$.ajax({
dataType: "html",
async: false,
type: 'POST',
url: 'index.php?fn=' + varia,
data: { token: "mytoken" },
success: function(data) {
$("body").prepend(data);
// The #login have atribute style="display: none;"
$("#login").fadeIn(500);
}
});
}
ajax("login", "html");
May be you can do like this
.done(function (data) {
var $data = $(data).hide();
$data.prependTo($("body"));
$data.fadeIn(500);
});

Ajax complete is fired before success is ready, how can one prevent this behaviour?

I have an AJAX request which fetches a chunk of HTML which I insert into the DOM. While this is happening I am showing a spinner loading gif.
I want the spinner to hide at the exact same time as the data received from the ajax request is inserted into the DOM.
The problem is that the javascript starts executing the complete part before the HTML is actually inserted into the DOM. So for the end user the spinner goes away and a while after, the DOM pops up.
$('#mySpinner').show();
$.ajax({
success: function(data) {
$('#myElement').html(data);
},
complete:(){
$('#mySpinner').hide(); // This is called when the success part is still executing
}
});
EDIT: I'm not saying complete is fired before success. I am saying complete is fired before success is ready. So the order in what happens is this:
Success is called
$('#myElement').html(data); is called
Complete is called
$('#mySpinner').hide() is called
$('#mySpinner').hide() is finished
$('#myElement').html(data); is finished
Just do this then :
$('#mySpinner').show();
$.ajax({
success: function(data) {
$('#myElement').html(data);
$('#mySpinner').hide();
}
});
But the behaviour you describe is not inline with jQuery doc as complete should only occur after success and error ... can you reproduce this wrong behaviour in a jsFiddle ? It might be the problem is somewhere else...
html() runs synchronously, however the browser could still be rendering when the next statement is executed. You could try to add a simple setTimeout to give the browser time to display the added content:
$('#mySpinner').show();
$.ajax({
success: function(data) {
$('#myElement').html(data);
setTimeout(function() {
$('#mySpinner').hide();
}, 0);
},
error: function() {
$('#mySpinner').hide();
}
});
Another option is to add a specific element to the added html and only continue when that element exists:
function waitForDom(el, cb) {
if ($(el).length) {
$(el).remove();
cb();
return;
}
setTimeout(function() {
waitForDom(el, cb);
}, 10);
}
$('#mySpinner').show();
$.ajax({
success: function(data) {
$('#myElement').html(data + '<div id="waitForDom"></div>');
waitForDom("waitForDom", function() {
$('#mySpinner').hide();
});
},
error: function() {
$('#mySpinner').hide();
}
});
You can simply hide your spinner in success part of ajax code:
$('#mySpinner').show();
$.ajax({
success: function(data) {
$('#myElement').html(data);
$('#mySpinner').hide();
}
});

Generic way to handle all AJAX calls

Is there a way to detect all AJAX calls (both GET and POST)? I need to do a generic way to show a loading div while the AJAX call process are running. Something like the code below:
$.ajax({
url: 'my/url',
type: "GET",
dataType: "json",
beforeSend: function() {
$('#loading').show();
},
success: function() {
$('#loading').hide();
// do some stuff...
}
Instead to call in every AJAX beforeSend() and success() behaviors (show and hide the loading div), I'm searching a generic way to handle it. When I have an AJAX call, I just do it:
$.ajax({
url: 'my/url',
type: "GET",
dataType: "json",
success: function() {
// do some stuff...
}
When that beforeSend() behavior is implicity in this request and the same for the success() hide behavior. Do you have any idea how can I treat this thing?
Thank you all!
Yes, you can do this using .ajaxStart() & .ajaxStop() methods like:
$(document).ready(function () {
$(document).ajaxStart(function () {
$('#loading').show();
}).ajaxStop(function () {
$('#loading').hide();
});
});
Funnily enough, I was trying to do this myself this morning!
$('#loading').bind('ajaxSend', function() {
$(this).show();
}).bind('ajaxStop', function() {
$(this).hide();
}).bind('ajaxError', function() {
$this.hide();
});
Obviously, lots of different ways to achieve this, but I prefer to bind the visibility of the loading message to the AJAX events, rather than the other way around...

Ajax Div toggle avoiding reloading content

I had a question regarding Ajax loading of html into a DIV. Ideally what I want is this:
A toggle div with close button, which I have the code for here: http://jsfiddle.net/tymeJV/uhEgG/28/
$(document).ready(function () {
$('#country').click(function () {
$("#country_slide").slideToggle(function() {
if ($(this).is(":visible")) {
alert("im visible!");
}
});
});
$('#close').click(function (e) {
e.preventDefault();
$('#country_slide').slideToggle();
});
});
Then I want some AJAX code to load a html file into the div when the div is expanded. The trick is that if the HTML is loaded successfully, I want it to avoid reloading the HTML file again if the div is closed and repoened, since I have already loaded it, and just simply toggle the content in and out with the button. The code I have for this (which I got help on from here is this):
http://jsfiddle.net/spadez/uhEgG/55/
$(function () {
$('#country_link').on('click', function (e) {
// Prevent from following the link, if there is some sort of error in
// the code before 'return false' it would still follow the link.
e.preventDefault();
// Get $link because 'this' is something else in the ajax request.
var $link = $(this);
// Exit if the data is loaded already
if ($link.data('loaded') === true)
return false;
$.ajax({
type: 'GET',
dataType: 'html',
url: '/ajax/test.html',
timeout: 5000,
beforeSend: function () {
},
success: function (data, textStatus) {
$("#country_slide").html(data);
alert('request successful');
// If successful, bind 'loaded' in the data
$link.data('loaded', true)
},
error: function (xhr, textStatus, errorThrown) {
$("#country_slide").html('Error');
},
complete: function () {
},
});
});
});
I haven't been able to get this working yet though. So my question is, is it actually possible to do this, and if it is, can anyone with more experience with jquery please help me integrate the div toggle with the ajax loading script.
This is one of my first jquery scripts and I am having a bit of a hard time with it, perhaps it is not for beginners. Thank you.
I edited the fiddle you posted adding the call to slideToogle() where appropriate. Also added a div element to hold the loaded html code.
<div id="country_slide">
Close
<div class=".content"></div> <!-- This is the div I added -->
</div>
You can check the log messages in the console to verify that the code is doing what you expect. The URL for the Ajax call you were doing always returned an error so I changed to the URL that jsfiddle provides for testing: /echo/html/.
Here's the modified JS code:
$(function () {
$('#close').click(function (e) {
e.preventDefault();
$('#country_slide').slideToggle();
});
$('#country_link').on('click', function (e) {
e.preventDefault();
var $link = $(this);
// Exit if the data is loaded already
if ($link.data('loaded') === true) {
console.log('Not using Ajax.');
$("#country_slide").slideToggle();
return false;
}
$.ajax({
type: 'GET',
dataType: 'html',
url: '/echo/html/',
timeout: 5000,
beforeSend: function () {
$("#country_slide .content").html('<p>Loading</p>')
},
success: function (data, textStatus) {
console.log('Fecthed with Ajax.');
$("#country_slide .content").html(data);
$("#country_slide").slideToggle();
// If successful, bind 'loaded' in the data
$link.data('loaded', true)
},
error: function (xhr, textStatus, errorThrown) {
alert('request failed');
},
complete: function () {
},
});
});
});

Categories

Resources