how can I call data when jQueryMobile page changed - jquery-mobile

Im building a browser-based app by jQueryMobile and facing a problem: Now I have a single HTML contains multiple "data-role=page" sections each of them will call backend to grab content once activated.
$('body').bind('pagechange',function(event){
//grab content base on page id here, working!!!
});
However, if user reload the page by press "refresh" button on browser how can I detect and call backend page?
Thanks

Use the pageshow event. Something like this:
$("[data-role=page]").live('pageshow',function(event, ui){
var myId = $.mobile.activePage.attr('id');
// do something
});

Related

Custom changePage on jquery mobile causes c.data("page") is undefined on second call

I'm trying to build some custom navigation in a dynamic application, all screens are obtained from the server and thus I registered the pagebeforechange event and execute my own function.
Everything works as I expected except when I refresh the data I destroy the dynamic pages and try to call the page I was in again using the page Id, but this second time, although my code creates the HTML for the page, jQuery Mobile throws an "c.data("page") is undefined" error.
I bind the pagebeforechange event:
$(document).bind('pagebeforechange', function(e, data) {
if(typeof data.toPage === 'string') {
appobj.dynamicPage(data.toPage, data.options);
}
});
Then in the dynamicPage method I create the HTML for my page based on Underscore.js templates and let jQuery continue changing the page:
$.get('templates/page.tpl.html', function (data) {
html = _.template(data, { /* several template parameters */});
});
page = $(html);
page.appendTo('body').page();
The idea was to use as much of jQM as possible since I'm creating the destination page and injecting it into the DOM.
When I need to update the supporting data, that I store in localStorage, I just find all dynamic pages and destroy them:
var current = $.mobile.activePage.attr('id');
$('.dynamicpage').remove();
$.mobile.changePage('#' + current
When running the application I can easily navigate between various screens/pages, even for pages that don't exist when the application starts but if the data needs to be updated (because the user added elements in the application of data in the database changed) then the removal code is executed but the old page is not regenerated ending in a white page with all the DOM contents hidden, but the page I wanted to navigate too seems to be in the DOM (at least firebug tells me so).
If I were to restart development I would probably use Backbone.js to handle my model updates and view changes but for now I'll have to use only jQM. Any suggestions? I understand that jQM is not finding my page but I don't see why since my event should be called and the page regenerated, even with the allowSamePageTransition flag set.
Regards,
Sérgio Lopes

jQuery UI Dialog with jqGrid loaded by AJAX is not closing

I have a jqGrid loaded by AJAX inside a jQuery UI Dialog. Everything is working fine, except the Dialog which is not closing. When I click in both buttons, it reaches the alerts, but the Dialog is not being closed.
buttons: {
'Confirm': function() {
alert('OK Confirm');
$('#test-grid').dialog('close');
},
'Cancelar': function() {
alert('OK Cancel');
$(this).dialog('close');
}
}
I've tried with $('#test-grid').dialog('close') and $(this).dialog('close'), but no one works. If I remove the jqGrid loaded by AJAX, everything works fine.
The error console on Firefox and Chrome is empty.
I'm loading the jqGrid page with:
$('#test-grid').load('/grid').dialog('open');
Can anyone help me?
UPDATE
I've tried to load a simple HTML snippet using AJAX and the problem persists.
The problem is that the call to load is interfering with the call to open the dialog. You can fix this by loading the AJAX content into a child element of test-grid. For example:
$('#test-grid-child').load('/grid');
$('#test-grid').dialog('open');
Update
I just read the docs for load and gave this a bit more thought. What is happening is that when the code $('#test-grid').load('/grid').dialog('open'); is executed, an AJAX request is started and the dialog is created immediately. But once the load's AJAX request finishes, jQuery comes back and overwrites the contents of #test-grid. This explains why the dialog could not be closed, because the underlying markup is modified out from underneath the dialog object.
Retrieving data to a child element eliminates this problem since load and dialog each now manipulates a different section of the DOM.
Note that if the AJAX request takes a long time to complete, you might want to consider implementing a complete function to give feedback to the user - maybe by displaying a spinner until the data is ready. For example:
$('#test-grid-child').load('ajax/test.html', function() {
alert('Load was performed.'); // Perform any necessary UI action here
});
Anyway, more information than you probably needed, but I just wanted to update this question while it was still fresh in my mind...

jQuery Mobile - Manipulating the DOM - Refreshing a page

This whole jQuery mobile dynamic data (pulling data from the server) is driving me nuts. Why should it be this difficult to manipulate the DOM and the refresh the page?
I have my page:
<div data-role="page" id="intranet-holidays" data-title="HOLIDAYS" data-add-back-btn="true"></div>
In document.ready I have the following:
$( document ).delegate( "#intranet-holidays", "pagebeforecreate", function() {
$('body').addClass('ui-loading');
$.mobile.loadingMessage = "Loading Holidays...";
$.mobile.showPageLoadingMsg();
// calls getJSON to retrieve data from the web server
loadHolidays();
});
When my data returns back from the server I add collapsible DIVs into my page (intranet-holidays).
Inside of the collapsible DIVs I have some ULs.
I know my syntax is correct because I can grab the generated HTML, save it to a file, then display that file and it all shows correctly. Here is a screen shot:
Here is what my dynamically loaded page looks like (not what I want):
I know that I can refresh a listview with the following:
$('#list').listview('refresh');
That works great for a list.
How do I refresh the page (that contains collapsible DIVs and those collapsible DIVs contains ULs)?
Yes, I want all the data in the page to be dynamic.
In the success handler method of the AJAX call that fetches the JSON data,add $('#intranet-holidays').trigger('create'); after you create the lists.
Try:
$('#page').trigger('create');
Or read:
http://www.elijahmanor.com/2011/02/dynamically-appending-elements-to.html

Pre-render JQM pages in the background

I have a mobile web app built with jQuery Mobile. It is using a multi-page template, with most of the content being created dynamically with javascript. The first time the app is loaded it shows a splash screen and then sends the user to an "index" page. From there the user can navigate to different parts of the app via # links. Each page's content is created dynamically with javascript and then inserted into the DOM on the "pageshow" event.
This works very well with one little problem that I haven't been able to solve. The first time a page is loaded it takes several seconds for the content to be generated and inserted into the DOM. Subsequent loads are fine since the previously rendered content is already in the DOM and is only replaced if there is new data. What I want to do is pre-render each page's DOM so that there is no noticeable delay when a page is loaded for the first time. I can achieve this by calling $.mobile.changePage() on each page. The problem is that I want this to be done in the background without the pages or any page transitions being shown to the user. Is there any way to do this?
P.S.: Worst-case scenario, I'd just keep the splash screen on top of everything while the pages are pre-rendered, but I can't even do this since JQM does the transition and changes the page whenever I call $.mobile.changePage().
All you have to do is use the $.mobile.loadPage. In the example below I show how to initialize a single page by hash URL upon the showing of #one. You could list out all of them if you wanted or create a fancy script to find all the [data-role] elements that do not have a class of ui-page, grab it's ID, and call a load on in the same way I have here.
$("#one").live("pageshow",function(){
$.mobile.loadPage("#two");
});
You can see the example in action on this jsfiddle..
I stumbled upon your question since I was looking into somewhat the same issue. What I ended up with is a _preloadPages() function in my project basically instantiating the page widgets which normally are done internally. Since this is not documented please keep in mind this can break anytime when upgrading JQM.
To control which pages to preload and which not I've introduced a class 'preload' which I place on the page containers I want to preload. This _preloadPages() function I call during splash screen and to not stress the initialization of my app to much the preloading is done in a 300ms interval. Still playing with these numbers though.
function _preloadPages()
{
// Execute the page() widget call on all pages that haven't yet been initialized, we do this
// to prevent a slight delay when initially loading a page
//
var $pages = $( "[data-role='page'].preload:not(.ui-page)" )
, index = 0
, pageCount = $pages.length
;
var preloadTimer = setInterval( function()
{
var page = $pages[ index ]
, $page = $( page )
;
$page.page();
index++;
if ( index === pageCount )
{
clearTimeout( preloadTimer );
}
}, 300 );
}

jQuery Mobile Page refresh mechanism

I'm having a lot of pain understanding how jQuery Mobile handles pages refresh after an ajax update.
I'm having a two pages - unique file site: a search engine.
First page is a search field. Submit triggers a JSON call and parser which updates the second page: results.
for now i'm using: $.mobile.changePage( $('#result') ); which does the job great from search field to result page.
However:
If I reuse it from result page for next/prev pages ( new json call, new parse, new added nodes in the DOM );
Jquery Mobile just don't "paint" the newly added nodes.
can anyone explain, please the use and distinction of
1- $.mobile.page()
2- $.mobile.changePage()
3- $.mobile.refresh()
or give me a hint on how I should handle page changes.
thanks!
function refreshPage()
{
jQuery.mobile.changePage(window.location.href, {
allowSamePageTransition: true,
transition: 'none',
reloadPage: true
});
}
Taken from here http://scottwb.com/blog/2012/06/29/reload-the-same-page-without-blinking-on-jquery-mobile/ also tested on jQuery Mobile 1.2.0
Please take a good look here: http://jquerymobile.com/test/docs/api/methods.html
$.mobile.changePage() is to change from one page to another, and the parameter can be a url or a page object. ( only #result will also work )
$.mobile.page() isn't recommended anymore, please use .trigger( "create"), see also: JQuery Mobile .page() function causes infinite loop?
Important:
Create vs. refresh: An important distinction
Note that there is an important difference between the create event and refresh method that some widgets have. The create event is suited for enhancing raw markup that contains one or more widgets. The refresh method that some widgets have should be used on existing (already enhanced) widgets that have been manipulated programmatically and need the UI be updated to match.
For example, if you had a page where you dynamically appended a new unordered list with data-role=listview attribute after page creation, triggering create on a parent element of that list would transform it into a listview styled widget. If more list items were then programmatically added, calling the listview’s refresh method would update just those new list items to the enhanced state and leave the existing list items untouched.
$.mobile.refresh() doesn't exist i guess
So what are you using for your results? A listview? Then you can update it by doing:
$('ul').listview('refresh');
Example:
http://operationmobile.com/dont-forget-to-call-refresh-when-adding-items-to-your-jquery-mobile-list/
Otherwise you can do:
$('#result').live("pageinit", function(){ // or pageshow
// your dom manipulations here
});
I posted that in jQuery forums (I hope it can help):
Diving into the jQM code i've found this solution. I hope it can help other people:
To refresh a dynamically modified page:
function refreshPage(page){
// Page refresh
page.trigger('pagecreate');
page.listview('refresh');
}
It works even if you create new headers, navbars or footers. I've tested it with jQM 1.0.1.
I found this thread looking to create an ajax page refresh button with jQuery Mobile.
#sgissinger had the closest answer to what I was looking for, but it was outdated.
I updated for jQuery Mobile 1.4
function refreshPage() {
jQuery.mobile.pageContainer.pagecontainer('change', window.location.href, {
allowSamePageTransition: true,
transition: 'none',
reloadPage: true
// 'reload' parameter not working yet: //github.com/jquery/jquery-mobile/issues/7406
});
}
// Run it with .on
$(document).on( "click", '#refresh', function() {
refreshPage();
});
I solved this problem by using the the data-cache="false" attribute in the page div on the pages I wanted refreshed.
<div data-role="page" data-cache="false">
/*content goes here*/
</div>
In my case it was my shopping cart. If a customer added an item to their cart and then continued shopping and then added another item to their cart the cart page would not show the new item. Unless they refreshed the page. Setting data-cache to false instructs JQM not to cache that page as far as I understand.
Hope this helps others in the future.
This answer did the trick for me http://view.jquerymobile.com/master/demos/faq/injected-content-is-not-enhanced.php.
In the context of a multi-pages template, I modify the content of a <div id="foo">...</div> in a Javascript 'pagebeforeshow' handler and trigger a refresh at the end of the script:
$(document).bind("pagebeforeshow", function(event,pdata) {
var parsedUrl = $.mobile.path.parseUrl( location.href );
switch ( parsedUrl.hash ) {
case "#p_02":
... some modifications of the content of the <div> here ...
$("#foo").trigger("create");
break;
}
});

Resources