Creating templated/persistant header/footer template in jQuery Mobile and PhoneGap
Solution 1:
I've been trying to tackle this problem for a few days now and I've gotten really close to the solution. I use the following HTML:
<body>
<div data-role="page" id="page">
<div data-role="header">
<h1 id="title">Title</h1>
</div><!-- /header -->
<div data-role="content" id="content">
<p>Loading...</p>
</div><!-- /content -->
<div data-role="footer" id="footer" data-position="fixed">
<div data-role="navbar" id="navbar">
</div>
</div><!-- /footer -->
</div><!-- /page -->
</body>
And I've created the following functions to load the menu/content using ajax:
$(document).on('pageinit', "#page", function() {
// for example: displayFooter();
loadContent("main");
loadMenu("default");
});
function loadContent(location) {
return $('#content').load("views/content/"+location+".html", function() {
$(this).trigger('create');
});
}
function loadMenu(location) {
$("#menu").remove();
$("#navbar").remove();
$("#footer").html('<div data-role="navbar" id="navbar">');
$("#navbar").html('<ul id="menu"></ul>');
$("#menu").load("views/menus/"+location+".html", function() { $("#menu").parent().navbar(); });
return true;
}
The .trigger('create');
and .navbar();
are the methods required to keep the JQM styling correct, however, there's still one little bug. The position of the menu (which is set using css top: ...px) is sometimes not correct and moves itself to the correct position after the first tap. Really close though!
Edit: By setting #footer
to position: fixed;
the minor bug I mentioned above is gone. Also, it's easy to make a method that calculates the top
(in px) for the #footer
if the position caused by the top
value by JQM is incorrect.
Solution 2:
Something like this:
function getText() {
//return footer text here
}
$("div:jqmData(role='page')").live("pagebeforecreate",function() {
// get find the footer of the page
var $footer =$(this).page().find('div:jqmData(role="footer")')
// insert it where you want it...
}
you could just define the role=footer in the getText and just check to see if it's defined... if not then add it.
Solution 3:
If you really want to do this properly, you need to look into a js framework like Thorax or JavascriptMVC.
In a JMVC app, you could do this from any view:
<div data-role="page">
<%== $.View('./header.ejs') %>
<div data-role="content">
...
</div>
<%== $.View('./footer.ejs') %>
</div>
jQuery Mobile is really only useful for progressive markup enhancement and styling for mobile devices. For the actual MVC part you need an MVC framework.
The examples for jQuery Mobile are also mostly geared for building mobile web sites which since they fetch pages from a server assume your code reuse is happening server side. A phonegap app is a whole nother beast since you will be generating these pages on the fly or from local static files. This is were the MVC framework comes in as you would be building your pages using controllers, views, view helpers, and model classes. You tie all that into jQuery mobile by listening to the pagebeforeshow event as shown on the jQm documentation page on scripting pages
Solution 4:
We haven't found a good way to do this yet either. So we are actually handling this dynamically in our custom js file. Looking for the closing container - and then dynamically appending the footer after the last content div closes.