Showing a div while page is loading, hiding when its done - javascript

I want to show a div with a loading animation over my page while the page loads some XML content. Once its loaded, I want to hide this div. How can I go about doing this?

$.ajax({
url: '/test.xml',
beforeSend: function(XMLHttpRequest) {
// Show the div before sending the request
$('#load').show();
},
complete: function(XMLHttpRequest, textStatus) {
// Hide the div no matter if the call succeeded or not
$('#load').hide();
},
success: function(xml) {
// if the request succeeds do something with the received XML
}
});

$.ajax({
type: "GET",
url: "your.xml",
dataType: "xml",
beforeSend: function() {
$('#div').fadeIn();
},
success: function(xml) {
// example for parsing xml
$(xml).find('YOUR_XML_TAG').each(function(){
// append xml to page HERE
});
},
complete: function() {
$('#div').fadeOut();
}
});

#cballou Your code will leave '#div' "up", if $.ajax() has not suceeded for any of numerous possible reasons.

Almost right ;)
Never under-estimate the importance of removing redundant $() calls. So ...
//all of this is inside some closure or function
var $blanket = $("#div") ;
// check if after last call, something has possibly removed your '#div'
// throw if false
ASSERT( $blanket.length === 1 ) ;
$.ajax({
type: "GET",
url: "your.xml",
dataType: "xml",
beforeSend: function() { $blanket.fadeIn();
},
success: function(xml) {
// example for parsing xml
$(xml).find('YOUR_XML_TAG').each(function(){
// append xml to page HERE
});
},
complete: function() { $blanket.fadeOut();
}
});
--DBJ

I would use the onbeforeunload event fired when the page URL changes, to create an overlay div with opacity at 0.5, which will be replaced by the new content when the page is loaded.

Related

Success message fades out after first form submit but not after subsequent submits

The first time a submit form the success message displays and then fades correctly. If I submit form again then it doesn't work. I want it to repeat the display of message and subsequent fade out after each form submit.
I found this answer
Trying to have a JQuery flash message after an ajax from submit in show again after more than one form submit (in rails)
but couldn't get to work, I'm very new to all this so be gentle ;-)
$(document).ready(function() {
$("#editMember").submit(function(e) {
e.preventDefault();
$.ajax( {
url: "php/adminUpdateMember.php",
method: "post",
data: $("form").serialize(),
dataType: "text",
success: function(strMessage) {
$("#message").text(strMessage);
}
});
});
setTimeout(function() {
$('#message').fadeOut('fast');
}, 4000);
});
Your setTimeout() call is not inside your submit() block. It will trigger the fadeOut 4 seonds after page load, and not be called again.
You might also need to call $('#message').show(), to make the element visible after it's been faded out.
$(document).ready(function() {
$("#editMember").submit(function(e) {
e.preventDefault();
$.ajax( {
url: "php/adminUpdateMember.php",
method: "post",
data: $("form").serialize(),
dataType: "text",
success: function(strMessage) {
$("#message").text(strMessage);
$('#message').fadeIn('fast');
}
});
setTimeout(function() {
$('#message').fadeOut('fast');
}, 4000);
});
});

onclick not triggering all codes in jquery

I'm trying to show spinner and overlay before sending an ajax request. But The onclick event directly sending the ajax request without showing the overlay and spinner. Can anyone point me out what i'm doing wrong! here is my code
$(document).ready(function() {
$(".refreshBtn").on('click', function() {
$("#overlay").css('display', 'block');
$(".spinner").css('display', 'block');
TableDataContent();
});
function TableDataContent() {
$(".all_tab_content").html('');
var tableDiv = '<div id="Leaderboard" class="tabcontent"><table class="table-striped"><tbody></tbody></table></div>';
$(".all_tab_content").append(tableDiv);
var tableBody = $('#Leaderboard tbody');
$.ajax({
type: 'get',
url: 'https://sheets.googleapis.com/v4/spreadsheets/{SHEET_ID}/values/Leaderboard?key={API_KEY}',
async: false,
success: function(response) {
}
});
$("#overlay").css('display', 'none');
$(".spinner").css('display', 'none');
}
});
You are hiding the spinner before ajax finishes put hide them from inside the complete callback so they can be hidden even when the ajax fails.
$.ajax({
type: 'get',
url: 'https://sheets.googleapis.com/v4/spreadsheets/{SHEET_ID}/values/Leaderboard?key={API_KEY}',
async: false,
success: function(response) {
},
complete: function(xhr, textStatus){
$("#overlay").css('display', 'none');
$(".spinner").css('display', 'none');
}
});
Your spinner does not show because AJAX requests are asynchronous. It means that it will be executed while the script continue to be executed too.
To correct that, move instructions which hide the overlay and the spinner in the success callback of your AJAX.
Right now you are hiding .spinner and #overlay without waiting for ajax to complete. Ajax's success callback happening when data is received, this is exactly the moment you want hiding .spinner and rest.
$.ajax({
type: 'get',
url: 'https://sheets.googleapis.com/v4/spreadsheets/{SHEET_ID}/values/Leaderboard?key={API_KEY}',
async: false,
success: function(response) {
$("#overlay").css('display', 'none');
$(".spinner").css('display', 'none');
// rest of your business
}
});
The problem is entirely due to your use of async: false. It's incredibly bad practice as it prevents the browser from being updated while the request is in progress. It's for this reason you never see the UI changes.
To fix this, remove async: false and instead work with the async callbacks of $.ajax(), like this:
$(function() {
$(".refreshBtn").on('click', function() {
TableDataContent();
});
function TableDataContent() {
var $indicators = $("#overlay, .spinner").show(); // show the loading indicator when the request starts...
var tableDiv = '<div id="Leaderboard" class="tabcontent"><table class="table-striped"><tbody></tbody></table></div>';
$(".all_tab_content").empty().append(tableDiv);
var $tableBody = $('#Leaderboard tbody');
$.ajax({
type: 'get',
url: 'https://sheets.googleapis.com/v4/spreadsheets/{SHEET_ID}/values/Leaderboard?key={API_KEY}',
success: function(response) {
// work with the response here...
},
complete: function() {
$indicators.hide(); // hide the loading indicator when the request ends
}
});
}
});
Note the use of empty(), show() and hide() here.
You also presume you need to change {SHEET_ID} and {API_KEY} in the URL to their actual values - presuming that's not just redacted data in the question.

Can't get rid of a flash of content from after ajax page load

I have a page that makes different ajax calls based on what element one clicks on. There are four IDs and only one should be visible at any given moment. My problem comes when I load new ajax content into a div - I get a flash for a very brief second of the previous content. Here is one of my functions for one of the calls (they are all essentially the same). At the beginning of the function I hide everything. Then after the ajax has loaded I show the relevant div. I'm confused about why this would not work. There should be no flash, since all the div are hidden, right?
$('body').on("click", "#answer-submit", function() {
$('#games, #location, #question, #answer').css('display' , 'none');
var theAnswer = $('#challenge-answer').val();
$.ajax({
type: "POST",
url: "ajax/answer.php",
data: { answer : theAnswer },
dataType: "html",
success: function(msg){
if(parseInt(msg)!=0) {
$('#answer').html(msg);
}
}
});
$('#answer').css('display' , 'block');
});
The problem is an asynchronous request is going to happen asynchronously. In other words, your success function is going to be called after $('#answer').css('display' , 'block'); (it is a race condition but it's practically guaranteed). The solution is simple -- move $('#answer').css('display' , 'block'); into the success function:
$('body').on("click", "#answer-submit", function() {
$('#games, #location, #question, #answer').css('display' , 'none');
var theAnswer = $('#challenge-answer').val();
$.ajax({
type: "POST",
url: "ajax/answer.php",
data: { answer : theAnswer },
dataType: "html",
success: function(msg){
if(parseInt(msg)!=0) {
$('#answer').html(msg);
$('#answer').css('display' , 'block');
}
}
});
});
You can even chain it like so:
if (parseInt(msg) != 0) {
$('#answer')
.html(msg)
.css('display', 'block');
}

JQuery fadeOut not working for ajax post request

I have this JQuery code:
$(function(){
$('input#SearchGo').on('click', function(){
var searchid = $('input#search').val();
var dataString = 'search='+ searchid;
$.ajax({
type: "POST",
url: "tickets.php",
data: dataString,
cache: false,
success: function(html) {
$("#result").html(html).show();
}
});
return false;
});
});
that does a live search and posts data to a PHP page.
On every page i have a div with an id of overlay with a loading image while the page loads, then this code:
$(window).load(function(){
// PAGE IS FULLY LOADED
// FADE OUT YOUR OVERLAYING DIV
$('#overlay').fadeOut();
});
removes the overlay div once the page has loaded.
when i run the search query, the overlay div doesnt fadeOut at all, i tried adding $('#overlay').fadeOut(); within the success part of my function but it doesnt fadeOut the div.
UPDATE:
here is the HTML for the loading / overlay div
<div id="overlay" class="overlay">
<img src="images/integra_loading.gif" alt="Loading" width="12%" style="margin-top:15%;" />
<br /><br />
<h1>Loading...</h1>
</div>
$(function(){//this says the dom is ready
$('#overlay').fadeOut();
});
alternatively
$(document).on("ajaxComplete", function(){
$('#overlay').fadeOut();
});
Don't hide your ajaxloader with a function that is called from the html script wich is loaded through the ajax request. just show the loader before the request and hide it before replacing the html content with your response.
function loader(){
this.id = '#overlay'
};
loader.prototype.show = function(){
$(this.id).fadeIn();
};
loader.prototype.hide = function(){
$(this.id).fadeOut();
};
loaderObj = new loader();
$('.list').live('click', function() {
loaderObj.show();
$.ajax({
type: "GET",
url: "http://echo.jsontest.com/uid/12345/value/nuno_bettencourt",
cache: false,
dataType: "json",
success: function(json) {
// setTimeout only to delay the response and let the loader do his thing ;)
setTimeout(function(){
loaderObj.hide();
$('#ajaxResult').html("UID=" + json.uid + "\nName=" + json.value);
}, 2000);
}
});
i made you a small fiddle example http://jsfiddle.net/358Fz/1/
after doing your $.ajax, add a done. in that done, do the fadeout!
$.ajax({
...
}).done(function(){
$('#overlay').fadeOut();
});
you can add a .fail for when it fails, etc. see: http://api.jquery.com/jquery.ajax/
Just define the loader variable outside of your click event and then use it where needed. There will be less overhead if you only have to traverse the DOM once to locate the loader element. You can also change the on event to just a click event to save a few key strokes unless you need to delegate the event to another element. Also, you don't need to look up $(input#search) since ID's are unique. Removing the variable selector and just looking up the ID will be more efficient.
$(function() {
var $loader = $('#overlay');
$('.list').click(function(){
$loader.fadeIn();
$.ajax({
type: "GET",
url: "http://time.jsontest.com/",
dataType: 'json',
cache: false,
success: function(json) {
$loader.fadeOut();
$("#axajResponse").html('<b>Current Time:</b> ' + json.time).show();
}
});
return false;
});
});
In the above example I'm getting back the current time so that you can see the response change on each click event.
Here is an example: http://jsfiddle.net/bradlilley/jLG4g/

abort previous ajax call on event

the problem is that when I click on .personalized class it does not have both #loading_personalized and #divPersonalized so it takes the AJAX call ..and as soon as I click again on .personalized in time the id #loading_personalized is showing up it hides but the previous AJAX call is not cancelled yet so it executes and shows #divPersonalized, but I want that at the time the #loading_personalized is showing up and I click on .personalized the previous AJAX call should also cancel..
here is my code......
$(document).ready(function(){
$(".Personalized").click(function(){
if($("#divPersonalized").is(':visible')){
$('#triangle-personalized').hide();
$("#divPersonalized").hide();
}
else if($('#loading_personalized').is(':visible'))
{
$('#loading_personalized').hide();
//if this event is true, abort previous ajax call here
}
else {
$.ajax({
type:"POST",
url:"personalized.php",
cache:false,
beforeSend: function(){
$('#loading_personalized').show();
$('#triangle-personalized').show();
},
complete: function(){
$('#loading_personalized').hide();
},
success: function(html){
$("#divPersonalized").html(html).show();
}
});
}
});
You need to store jQuery ajax object and then call abort()
myAjaxCall = $.ajax({
type:"POST",
url:"personalized.php",
cache:false,
beforeSend: function(){
$('#loading_personalized').show();
$('#triangle-personalized').show();
},
complete: function(){
$('#loading_personalized').hide();
},
success: function(html){
$("#divPersonalized").html(html).show();
}
});
if($('#loading_personalized').is(':visible'))
{
$('#loading_personalized').hide();
myAjaxCall.abort();
}

Categories