Reputation: 63
I'm working on a web app on CodeIgniter with jQuery and I'm trying to make a javascript function to show an ajax loading image during ajax calls. In my example, the ajax call is successful but the loading never show so I think the problem is the first function in "when" is not executed. Does someone could help me with this? Thanks
HTML
<div id="form"></div>
CSS
#form {
height: 300px;
width: 350px;
}
.loadingOverlay {
border: 1px solid #EFEFEF;
background-color: #D8DCDF;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
position: absolute;
padding: 10px;
z-index: 1;
-moz-opacity: 0.50;
opacity: 0.50;
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha"(Opacity=50);
}
Javascript
function displayLoading(Container, Callback) {
var height = Container.height();
var width = Container.width();
$.when(function() {
Container.append('<div class="loadingOverlay" style="width: '+ width +'px; height: '+ height +'px;"><img class="ajaxLoading" src="http://www.ajaxload.info/images/exemples/2.gif" /></div>');
Container.find(".loadingOverlay").position({
"my": "center center",
"at": "center center",
"of": Container
});
Container.find(".ajaxLoading").position({
"my": "center center",
"at": "center center",
"of": Container
});
}, Callback()).then(function() {
Container.find(".loadingOverlay").hide().remove();
});
}
displayLoading($("#form"), function() {
$.ajax({
url: 'http://search.twitter.com/search.json',
dataType: 'jsonp',
data: {
q: 'ConceptionAb6'
},
success: function(results) {
// Only for testing the loading
setTimeout(function() {
alert(results.max_id);
}, 2000);
},
error: function() {
alert("error!");
}
});
});
Upvotes: 2
Views: 7937
Reputation: 3903
For the purposes of making an ajax loading animation, just do this:
$("<img src='loading.gif'/>").bind({
ajaxStart: function() { $(this).show(); },
ajaxStop: function() { $(this).hide(); }
});
It utilizes jQuery's built-in global ajax events that fire anytime an $.ajax()
call happens and binds them to your animation element.
Upvotes: 2
Reputation: 18078
Stripping displayLoading()
right down to the bones I get ...
function displayLoading(Container, Callback) {
...
$.when(function(){...}, Callback()).then(function() {
...
});
}
... revealing that $.when()
is not being used correctly.
$.when()
expects all its arguments to be promises, which not the case for either argument.
Moreover, $.when()
is unnecessary as only one promise (the jqXHR returned by $.ajax()) is involved.
I think the pattern you want is something like this :
function displayLoading(container, promise) {
//create a spinner in container if not already created
//show spinner
//hide other content
promise.done(function() {
//hide spinner
//show other content
});
}
displayLoading($("#form"), $.ajax({
//ajax options
});
Upvotes: 1
Reputation: 19128
In my opinion $.when is more usual when using several async requests. In your case I would use:
$.ajax({
beforeSend: function() {
var Container = $("#form");
var height = Container.height();
var width = Container.width();
Container.append('<div class="loadingOverlay" style="width: '+ width +'px; height: '+ height +'px;"><img class="ajaxLoading" src="/img/ajax-loader.gif" /></div>');
Container.find(".loadingOverlay").position({
"my": "center center",
"at": "center center",
"of": Container
});
Container.find(".ajaxLoading").position({
"my": "center center",
"at": "center center",
"of": Container
});
},
url: 'http://search.twitter.com/search.json',
dataType: 'jsonp',
data: {
q: 'ConceptionAb6'
},
success: function(results) {
alert(results.max_id);
},
error: function() {
alert("error!");
},
complete: function() {
$("#form").find(".loadingOverlay").hide().remove();
}
});
Upvotes: 1
Reputation: 6798
The problem seems to be having the ajax call wrapped in a function. This works fine:
function displayLoading(Container, Callback) {
var height = Container.height();
var width = Container.width();
Container.append('<div class="loadingOverlay" style="width: '+ width +'px; height: '+ height +'px;"><img class="ajaxLoading" src="/img/ajax-loader.gif" /></div>');
Container.find(".loadingOverlay").position({
"my": "center center",
"at": "center center",
"of": Container
});
Container.find(".ajaxLoading").position({
"my": "center center",
"at": "center center",
"of": Container
});
$.when($.ajax({
url: 'http://search.twitter.com/search.json',
dataType: 'jsonp',
data: {
q: 'ConceptionAb6'
},
success: function(results) {
setTimeout(function() {
alert(results.max_id);
}, 2000);
},
error: function() {
alert("error!");
}
})).then(function() {
Container.find(".loadingOverlay").hide().remove();
});
}
displayLoading($("#form"));
I'd read up on how deferred objects work in jQuery and figure out a different approach. http://colonelpanic.net/2011/11/jquery-deferred-objects/
Upvotes: 1