Reputation: 914
i have the following jquery code. basically - it takes a value from an anchor - and displays a sub-menu content below it. this works perfectly.
$(function(){
$('.plus').live('click', function(event){
event.preventDefault();
$(this).addClass('lower');
var existingPath = $(this).attr('rel');
GetSubs(this, existingPath);
$(this).removeClass('plus').addClass('open'); //.delay(10000).removeClass('lower');
});
function GetSubs(IDclicked, existingPath){
var dataString;
dataString = 'lang=<%=Lang%>&rel=[' + existingPath + ']';
$.ajax({
type: "GET",
url: "/includes/getSubCatMenuLinks.asp",
data: dataString,
success: function(data) {
$(data).insertAfter(IDclicked);
},
error: function(obj,msg) {
alert('*** Error! ***\n\n'+msg);
}
});
}
});
what i would like to do - is have a a "loading" icon showing, while the content is loading - and then remove it when done.
displaying it is fine - thats whats done in the line
$(this).addClass('lower');
when a few lines down, i try remove that class - but the movemext is so fast - that the loading icon doesnt even show. ie - the ajax content hasnt appeared yet, but the jquery code has already loaded the class, loaded the ajax (somewhere) and then removed the class - so the loading icons doesnt even display.
i tried using the delay method - to have it removed a seconds or a few later - but it doesnt work.
any help appreciated!
thanks!
Upvotes: 1
Views: 184
Reputation: 816262
As already said, .delay
only works with animation methods. Simply remove the class when the Ajax request completed. To keep your code decoupled, make use of the deferred object returned by $.ajax
and pass a callback to the .always
method [docs]:
var $this = $(this).addClass('lower');
// ...
// or GetSubs(this, existingPath).done if you only want to remove the loader
// when the call was successful. Use .fail to handle error cases.
GetSubs(this, existingPath).always(function() {
$this.removeClass('lower');
// or
// $this.removeClass('plus').addClass('open').removeClass('lower');
// not quite sure when exactly you want to remove / add which classes
});
// ...
function GetSubs(IDclicked, existingPath){
// ...
return $.ajax({ // <- return the $.ajax return value
// ...
});
}
Upvotes: 5
Reputation: 318172
delay()
only works with animations, and not on functions like removeClass, for that you'll need a timeOut. Not only that, but the Ajax call is asynchronous, so your class is removed instantly and does not wait for the Ajax call to finish.
You could always do:
$(function(){
$(document).on('click', '.plus', function(e){
e.preventDefault();
var self = this,
existingPath = $(this).attr('rel');
$(self).addClass('lower');
GetSubs(self, existingPath, function() { //added callback
setTimeout(function() { //and a one second delay
$(self).removeClass('lower');
}, 1000);
});
});
function GetSubs(IDclicked, existingPath, callback){
var dataString = 'lang=<%=Lang%>&rel=[' + existingPath + ']';
$.ajax({
type: "GET",
url: "/includes/getSubCatMenuLinks.asp",
data: dataString,
success: function(data) {
$(data).insertAfter(IDclicked);
},
complete: function() {
callback.call(); //callback function is called when ajax is finished
},
error: function(obj,msg) {
alert('*** Error! ***\n\n'+msg);
}
});
}
});
This waits for the ajax call to finish, then waits one second, and then does the class stuff. Usually a timer just to show off your nice spinner is considered bad UI, so I would just keep the callback function.
Upvotes: 1