How to stop jQuery Mobile calling $.mobile.loading('hide') during changePage? - jquery-mobile

I'm trying to stop jQuery Mobile hiding the loading spinner when changePage is called.
The program flow goes like this, starting with clicking a link, which has its click event defined like this:
$('body').delegate('.library-link', 'click', function() {
$.mobile.loading( 'show' );
$.mobile.changePage($('#page-library'));
return false;
});
Upon clicking the link, the pagebeforeshow event is fired, which triggers a function to populate the page from the local storage, or else make an ajax call to get the data.
$(document).on('pagebeforeshow', '#page-library', function(event){
ui.populate_data();
});
In ui.populate_data() we get the data from local storage or make an ajax call.
ui.populate_data = function() {
if (localdata) {
// populate some ui on the page
$.mobile.loading( 'hide' );
} else {
// make an ajax call
}
};
If the data is there, we load the data into the container and hide the loading spinner. If not it makes the ajax call, which on complete saves the data in local storage, and calls ui.populate_data()
The problem is, after the pagebeforeshow event is finished, changePage is calling $.mobile.loading( 'hide' ), even though the data might not be there yet. I can't find any way to prevent changePage from hiding the spinner, other than by temporarily redefining $.mobile.loading, which feels pretty wrong:
$('body').delegate('.library-link', 'click', function() {
$.mobile.loading( 'show' );
loading_fn = $.mobile.loading;
$.mobile.loading = function() { return; };
$.mobile.changePage($('#page-library'), {showLoadMsg: false});
return false;
});
and before hiding the spinner in my ui function:
ui.populate_data = function() {
if (localdata) {
// populate some ui on the page
if (typeof loading_fn === 'function') {
$.mobile.loading = loading_fn;
}
$.mobile.loading( 'hide' );
} else {
// make an ajax call
}
};
Surely there must be a way to get complete control over the showing and hiding of the loading widget, but I can't find it. I tried passing {showLoadMsg: false} to changePage, but as suggested by the docs it only does things when loading pages over ajax, which I'm not doing.

Maybe it's too much for many, but I found a solution other than the written in the comments (which didn't work for me).
I use the jquery mobile router and in the 'show' event of a page, I do $.mobile.loading("show");, so when the page appears it does with the loading spinner showing.
Though to hide the spinner, I had to use $('.ui-loader').hide();, which is weird, I know...
I use Jquery Mobile Router for a lot more, but it solved this issue.
(Maybe just listening to the proper event and triggering the spinner would also work, as this is what JQMR does...)
I'm using JQM 1.4.2...

Related

Events in Jquery mobile

I'm trying for some time to make events work, but they do not work, I'm trying to look for any reaction with alert or console.log but nothing to do, no reaction. I tried to change the selectors, same result. I also try to introduce them with $(document).ready or $("#mypage").("pagecreate", ...
Still trying with jsfiddle, it works perfectly but on my file from the browser, nothing.
I have only swipe that works.
Scrollstop and navigate does not work.
$('#neww').on("scrollstop", function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
recept2();
}
Looking for a way to dynamically add more lists to the bottom of jQuery Mobile listview
$("#mypanel").on("navigate", function (event, data) {
var direction = data.state.direction;
if (direction == 'back') {
$("#mypanel").panel("close");
console.log(direction);
}
});
how to control back button event in Jquery mobile?

JQuery mobile persistent navbar (outside page div)

I've got a navbar outside the page div in a footer (it is on every page) I tried to do a simple fix for the persistent active state of the navbar It worked for the tabs on one of the pages but does not seem to work for this.
Actually, everything works except for some reason ui-btn-active does not get added
Here is the code
$(document).one( "pageinit", function() {
$('div[data-role="footer"] [data-role="navbar"] a').click(function(e) {
$(this).html("abc");
$('div[data-role="footer"] [data-role="navbar"] .ui-btn-active').removeClass('ui-btn-active ui-state-persist');
$(this).addClass('ui-btn-active ui-state-persist');
});
});
The html of the anchor changes, ui-state-persist gets added on the last line but ui-btn-active just does not get added for some reason...
Ok it seems jquery mobile automatically removes ui-btn-active on page transition, even if your navbar is out of page div (which I find kind of lame...) It seems it does this on or after pagebeforeshow, because this did not work with that event... so I just used pageshow instead.
Here is the working code:
var navbar;
$(document).on("pageshow", function() {
if(navbar) {
$(navbar).addClass('ui-btn-active')
}
});
$(document).one( "pageinit", function() {
$('div[data-role="footer"] [data-role="navbar"] a').click(function() {
navbar = $(this);
});
});

How to disable toolbar buttons during page transition?

I am using an external toolbar in a jQuery Mobile site I'm working on. I initialize it like so:
$(document).ready(function () {
$("[data-role='header'], [data-role='footer']").toolbar();
});
I have a couple of buttons in the toolbar and want to disable them during page transitions so users don't click them multiple times which seems to get the framework into a weird state. My first attempt has been to listen for the pagebeforeshow and pageshow events to programmatically disable and enable the buttons:
$(function() {
$("[data-role='header'], [data-role='footer']").toolbar({
create: function (event, ui) {
$(document).on('pagebeforeshow', function () {
$('#page-header .ui-btn').button('disable');
});
$(document).on('pageshow', function () {
$('#page-header .ui-btn').button('enable');
});
}
});
});
I have the code nested inside like that because I don't want to register the handlers until the toolbar has been initialized. However, I'm running into a separate problem:
Uncaught Error: cannot call methods on button prior to initialization; attempted to call method 'disable'
Since I'm not explicitly initializing the buttons myself, I'm not sure I understand how / where I can wait for them to be initialized.
Is there a better approach to this, and does anyone have any suggestions to get this working?
Use .button() on input with type button, reset and submit. For anchor or button tag you need to add / remove ui-state-disabled class.
$(document).on("pagecontainerbeforehide", function () {
$('#page-header .ui-btn').addClass('ui-state-disabled');
});
$(document).on("pagecontainershow", function () {
$('#page-header .ui-btn').removeClass('ui-state-disabled');
});
Demo

Get the referred link id on pagebeforeshow

In jqm I have something like this
<li>cats</li>
<li>dogs</li>
Page1 is a dynamic page and should load it's contents based on which link button I pressed and I use
$(document).on('pagebeforeshow', '#page1', function(event, data){
do something here with either cats or dogs
});
Now how do I determine here what link what used?
I could use sessionStorage or perhaps a
$('.loadPage').click(function(){
$(this).attr('id').blablabla
})
but it doesn't seem right to me. I'm sure the answer is there right in front of me, but I can't seem to get around it.
Any ideas?
You could store the id in #page1's data attribute on click of loadPage:
$(document).on("pageinit", "#page0", function () {
$(this).on("click", ".loadPage", function (e) {
e.preventDefault();
$("#page1").data("id", this.id);
});
});
Then, after jQM redirects you to #page1, check for the stored data :
$(document).on("pagebeforeshow", "#page1", function () {
alert($(this).data("id"));
// you can do anything with this id
});
Demo : http://jsfiddle.net/hungerpain/wN2L9/
compare the id:
if(this.id==='cats')
{
//do something here
}
On a side note you can use $(this).attr('id') also, but its better you use pure JavaScript whenever possible.

jquery mobile: how to create dynamic content only once, at page startup?

Here's what I want to do:
load basket using Ajax
show "wait" message
once loaded, refresh basket.
When I try to use pageinit function:
$(document).bind('pageinit', function(evt) {
console.log(evt);
}
Console log show it's called 29 times!
Everything is on one HTML page, and I'm using $.mobile.changePage() to change pages. So I tried this hack:
$(document).bind('pagebeforeshow', function(evt, pg) {
if (pg.prevPage.length==0) {
/* first page = code executed once */
var pg = $('#page-basket'),
footer = pg.children( ":jqmData(role=footer)" );
footer.hide().trigger('updatelayout');
AjaxGetBasket( function(data) { console.log('ajax basket ok'); });
}
});
But the layout is never updated.
How shall I do to modify page but only once at the beginning?
Try delegating the pageinit event handler so it only runs when #page-basket is initialized:
$(document).on("pageinit", "#page-basket", function() {
$(this).children(":jqmData(role=footer)").hide().trigger("updatelayout");
AjaxGetBasket(function(data) {
console.log("ajax basket ok");
});
});
I do not understand if your problem is solved, but i am in the same situation explained in the question and i have solved the problem binding a function to pagecreate event:
$(document).bind("pagecreate", function(e){
// call ajax and update the DOM of first 'page'
});
and that's all.

Resources