Reputation: 5820
I'm using $.ajax() to populate a list in my mobile web app. What I'd like to do is have the jQuery mobile loading spinner appears while this call is being performed and disappear once the list populates. The current version of JQM uses $.mobile.showPageLoadingMsg()
and $.mobile.hidePageLoadingMsg()
to show and hide the loading spinner, respectively. I can't figure out where exactly to place these statements to get the correct result. This seems like it should be a fairly easy thing to accomplish, I just haven't been able to find anything about this exact scenario.
Here's the ajax call inside the pagecreate function:
$('#main').live('pagecreate', function(event) {
$.ajax({
url: //url
dataType: 'json',
headers: //headers
success: function(data) {
for(i = 0; i < data.length; i++) {
$('#courses').append('<li>' + data[i].name + '<ul id="course' + data[i].id + '"></ul>' + '<span class="ui-li-count">' + data[i].evaluatedUserIds.length + '</span></li>');
$('#course' + data[i].id).listview();
for(j = 0; j < data[i].evaluatedUserIds.length; j++) {
$('#course' + data[i].id).append('<li><a href="">' + data[i].evaluatedUserIds[j] + '</a></li>');
}
$('#course' + data[i].id).listview('refresh');
}
$('#courses').listview('refresh');
}
});
});
Upvotes: 36
Views: 77520
Reputation: 3308
Or, the simplest way is to put it globally as a separation of concern -
Put below code into your master/layout view
<script type="text/javascript">
$(document).bind('mobileinit', function () {
//Loader settings
$.mobile.loader.prototype.options.text = "Loading..";
$.mobile.loader.prototype.options.textVisible = true;
$.mobile.loader.prototype.options.theme = "b";
$.mobile.loader.prototype.options.textonly = false;
});
$(document).on({
ajaxSend: function () { $.mobile.showPageLoadingMsg(); },
ajaxStart: function () { $.mobile.showPageLoadingMsg(); },
ajaxStop: function () { $.mobile.hidePageLoadingMsg(); },
ajaxError: function () { $.mobile.hidePageLoadingMsg(); }
});
</script>
Edit: Please use instead if you are targeting latest version of JQM (>1.2):
Upvotes: 3
Reputation: 3972
Before JQM 1.2:
$(document).ajaxStart(function() {
$.mobile.showPageLoadingMsg();
});
$(document).ajaxStop(function() {
$.mobile.hidePageLoadingMsg();
});
Since JQM 1.2:
$(document).ajaxStart(function() {
$.mobile.loading('show');
});
$(document).ajaxStop(function() {
$.mobile.loading('hide');
});
http://api.jquerymobile.com/page-loading/
Upvotes: 50
Reputation: 47776
You can use the beforeSend
and complete
events of $.ajax
to call $.mobile.showPageLoadingMsg
and $.mobile.hidePageLoadingMsg
. Would look like this:
$('#main').live('pagecreate', function(event) {
$.ajax({
beforeSend: function() { $.mobile.showPageLoadingMsg(); }, //Show spinner
complete: function() { $.mobile.hidePageLoadingMsg() }, //Hide spinner
url: //url
dataType: 'json',
headers: //headers
success: function(data) {
//...
}
});
});
Upvotes: 58
Reputation: 27058
$(document).ajaxSend(function() {
$.mobile.loading( 'show');
});
$(document).ajaxComplete(function() {
$.mobile.loading( 'hide');
});
Upvotes: 9
Reputation: 31
The problem here is that the call to $.ajax() happens within the control flow of the event handler (the caller).
A very simple way to decouple the ajax request from this control flow is to let setTimeout() invoke this function for you, like so:
setTimeout(function(){$.ajax( ... )}, 1);
You can then use the 'beforeSend' and 'complete' events of $.ajax() as stated before and be sure, that your spinner is showing up.
Upvotes: 2
Reputation: 1454
This is a bit late...but you need to:
$.mobile.showPageLoadingMsg()
before the AJAX call.async: true
in your call).$.mobile.hidePageLoadingMsg()
in your success()
function.Upvotes: 10
Reputation: 5820
A few people have asked about the workaround I ended up implementing, so I figured I'd share it. It's nothing particularly elegant or complicated, but it did seem to work. I haven't used the framework since the official 1.0 was released, so this may have been solved in the update. Essentially, I put the $.mobile.showPageLoadingMsg()
call into the pageshow
function, but wrapped it in an if clause that only fires the first time the page is shown:
var mainloaded = false;
$('#main').live('pageshow', function(event) { //Workaround to show page loading on initial page load
if(!mainloaded) {
$.mobile.showPageLoadingMsg();
}
});
$('#main').live('pagecreate', function(event) {
$.ajax({
url: //url
dataType: //datatype,
headers: //headers
success: function(data) {
//
//...loading stuff
//
$.mobile.hidePageLoadingMsg();
mainloaded = true;
}
//
//...handle error, etc.
//
});
});
Upvotes: 14
Reputation: 1427
You should do $.mobile.showPageLoadingMsg() just before the ajax call, and $.mobile.hidePageLoadingMsg() in the success (or fail) block so it goes away once a result comes back.
I've never used jQuery mobile, but it should operate the same as showing/hiding a regular ol' spinning image.
Upvotes: 3