Hiding div when making ajax call with jquery for smooth transition
I am currently hiding the div with id "countries" slowly and it has full function. I am making an ajax call where in this function I get a partial view and replace the div with the result and then show () slowly again.
This waits for the hide animation to complete before it makes the ajax call. To make this more efficient and use the time it takes to hide the div efficiently, is there a way I can make an ajax call before I hide and only show once when both ajax is done AND the hide animation is complete?
Sometimes the hide is not complete before the ajax is done and it won't make a smooth transition, and if I put the ajax call inside the complete animation function hide, such a slow delay can occur.
So the smoothest possible transition is to make the ajax call right away, but only drag the div when the hide animation is complete. How can i do this?
Below is what I have now, but it waits for the hide animation to complete before making an ajax call, which is not the most efficient way to ensure a smooth transition.
$("#countries").hide("slow", function(){
$.ajax({
url: 'blah',
type: 'get',
data: { region: region }
})
.done(function(result){
$("#divCountries").html(result);
$("#countries").show("slow");
});
});
source to share
I posted a revised answer that uses $ .when. For history, I'm not going to change this code.
Try your url with the following. If you have a problem, let me know in the comment. This is how it works for me:
Some HTML
<div style="background-color: red;" id="countries">countries div</div>
<button id="get">Get</button>
Some Javascript
var hidden = false;
var ajax = false;
$(document).ready(function() {
$('#get').click(function() {
$("#countries").hide("slow", function() {
$.ajax({
url: 'blah',
type: 'get',
data: { region: region },
success: setAjaxFlag(),
error: setAjaxFlag()
}).done(function(){
setHiddenFlag();
showCountries();
});
})
});
});
function setAjaxFlag() {
ajax = true;
}
function setHiddenFlag() {
hidden = true;
}
function showCountries() {
if(ajax === true && hidden === true) {
$("#divCountries").html(result);
$("#countries").show("slow");
} else {
showCountries();
}
}
source to share
If you want to show the result after completion and the div is hidden from the ajax call, you need to create certain conditions like below: -
function getResult() {
window.lock1 = 0; /*This means animation is not done*/
window.data1 = -1; /*The data by ajax is not yet fetched*/
$.ajax({
url: 'blah',
type: 'get',
data: {
region: region
},
success: function (result) {
if (window.lock1 !== 0) {
$("#divCountries").html(result);
$("#countries").show("slow");
} else {
window.data1 = result;
}
}
});
$("#countries").hide("slow", function {
if (window.data1 !== -1) {
$("#divCountries").html(window.data1);
$("#countries").show("slow");
} else {
window.lock1 = 1
}
});
}
I have created two variables that check if the div is hidden or not, and the ajax call is completed or not, if the div is hidden and the ajax call is completed after it, then it fetches the data straight ahead until it waits for the div to be hidden and once it is hidden it gets data from the global variable window.data1
source to share
I may be missing something, but it looks like the solution you are looking for is quite simple:
var hidden = false, ajaxed = false;
$("#countries").hide("slow", function() {
hidden = true;
if (ajaxed)
$("#countries").show("slow");
});
$.ajax({
url: 'blah',
type: 'get',
data: { region: region }
}).done(function(result) {
ajaxed = true;
$("#divCountries").html(result);
if (hidden)
$("#countries").show("slow");
});
-edit- I have to figure it out a bit. Both hidden and ajaxed are flags: hidden will be set to true when the div is completely hidden, and ajaxed will be set to true as soon as the ajax request receives a response. Also, the ajax request will be sent immediately instead of waiting until the div is hidden.
If you walk through the codes, you will see that one of the flags will always be true, whichever comes first. In any case, the "show" will only happen if the other flag is also true (double positive).
source to share
I'm not sure if you want to do it this way, but create some kind of event click
or event change
that makes it happen. (Not sure if this is how you have it now or not, but that's how I imagine ...). Thus, both start immediately. If ajax
ends first then hide
will be displayed. If it hide
ends first, it ajax
will return the show.
$(document).on('click','#someelement',function(){
var dvals = {}, aj = false, hide = false;
dvals['region'] = region;
$.ajax({
type: "POST",
url: '/',
data: dvals,
success: function(data){
aj = true;
if(aj && hide){
$("#divCountries").html(result);
$('#countries').show('slow');
}
}
});
$('#countries').hide('slow',function(){
hide = true;
if(aj && hide){
$(this).show('slow');
}
});
});
source to share
This is better. It takes care of the problem with less clutter by using JQuery.when http://api.jquery.com/jquery.when/ It's less funny, removing boolean states and a possible infinite loop. Oh, and I added a Fiddle - enable Ajax and run the fiddle until you get it the way you want it. http://jsfiddle.net/Xorat/uzjLchmx/
Truth said I had a problem getting my response data from success to show showResults. I tried using a variable out of scope to pass data. If you fix it, comment out the script with the correct ajax that works.
Html
<div id="countries">country data</div>
<button id="get">Get</button>
Javascript
var https = 'https://www.googleapis.com/calendar/v3/calendars/';
$(document).ready(function() {
$('#get').click(function() {
$.when($.ajax({
url: https,
dataType: 'jsonp',
type: "GET",
success: function (response) {
//do something
},
error: function() {
//do something else
}
}), $("#countries").hide("slow")).done(showResults());
});
});
function showResults() {
$("#countries").show("slow")
//and do some stuff with your data
}
source to share