JqueryMobile footer for nested list

I have a nested list in a jQuery Mobile test application. And it has a fixed footer.

Works great until I click on an item in the list. Everything below the top of the list does not have a footer.

Is there a way to keep the footer in the entire navigation of the nested list?

Thanks in advance.

Adam.

Here is the code:

<!-- ################ Menu Page ##################### --> <div data-role="page" id="home" data-theme="a"> <div data-role="header" data-position="inline"> <h1>Menu</h1> </div> <div data-role="content"> <ul data-role="listview"> <li><a href="#">List</a> <ul data-role="listview" data-theme="c"> <li><a href="index.html">List</a></li> <li><a href="index.html">List</a></li> <li><a href="index.html">List</a></li> <li><a href="index.html">List</a></li> </ul> </li> <li><a href="#">List</a> <ul data-role="listview" data-theme="c"> <li><a href="index.html">List</a></li> <li><a href="index.html">List</a></li> <li><a href="index.html">List</a></li> <li><a href="index.html">List</a></li> </ul> </li> <li><a href="#">List</a> <ul data-role="listview" data-theme="c"> <li><a href="index.html">List</a></li> <li><a href="index.html">List</a></li> <li><a href="index.html">List</a></li> <li><a href="index.html">List</a></li> </ul> </li> <li><a href="#">List</a> <ul data-role="listview" data-theme="c"> <li><a href="index.html">List</a></li> <li><a href="index.html">List</a></li> <li><a href="index.html">List</a></li> <li><a href="index.html">List</a></li> <li><a href="index.html">List</a></li> </ul> </li> </ul> </div><!-- eof content --> <div data-role="footer" data-position="fixed" data-id="myfooter"> <div data-role="navbar"> <ul> <li><a data-icon="grid" data-iconpos="top" href="#home">Menu</a></li> <li><a data-icon="star" data-iconpos="top" href="#location">Location</a></li> <li><a data-icon="alert" data-iconpos="top" href="http://www.site.com" rel="external">Full Site</a></li> <li><a data-icon="grid" data-iconpos="top" href="#addpad">Pad</a></li> <li><a data-icon="info" data-iconpos="top" href="#more">More</a></li> </ul> </div><!-- /navbar --> </div><!-- eof footer --> </div><!-- eof page#home --> 
+8
jquery-mobile mobile-safari mobile-website jqtouch
source share
4 answers

I banged my head about this issue for several days, and this time Google did not help. I finally came up with the following solution. It copies the HTML header to a new page before the transition begins, and then removes the code from the previous page after the transition is completed. The header and footer will still move with the transition to the page, but they will be preserved even when navigating through nested lists.

 // dynamically move the header and footer between pages on load events $('div.ui-page').live('pagebeforeshow', function(event, ui) { // avoid duplicating the header on the first page load if (ui.prevPage.length == 0) return; // remove the jQuery Mobile-generated header $('.ui-header').addClass('to-remove-now'); $('#header').removeClass('to-remove-now'); $('.to-remove-now').remove(); // grab the code from the current header and footer header = $('#header')[0].outerHTML; footer = $('#footer')[0].outerHTML; // mark the existing header and footer for deletion $('#header').addClass('to-remove'); $('#footer').addClass('to-remove'); // prepend the header and append the footer to the generated HTML event.currentTarget.innerHTML = header + event.currentTarget.innerHTML + footer; }); // remove header from previous page $('div.ui-page').live('pagehide', function(event, ui) { $('.to-remove').remove(); }); 

Then just add id="header" to the div header and id="footer" in the footer and place them as usual in your content.

+2
source share

Here's how I got around this, but the footer. Removing an attribute is to prevent the initialization code from executing twice, which leads to many intervals in blocks. This method saves all class styles for style elements. Another nice thing is the code that needs to be executed only once for pagecreate in order to add footers.

 $('div.ui-page:not(#mainPage)').live('pagecreate', function(event) { if ($(event.currentTarget).find('footer').length == 0) { var footer = $('#footerNavBar').html(); $(event.currentTarget).append( '<footer class="footerNavBar">' +footer + '</footer>'); $(event.currentTarget).find('.ui-navbar').removeAttr('data-id').removeAttr('data-role').removeAttr('role'); } }); 

.

 <div data-role="page" id="mainPage"> <header data-role="header" data-position="inline" id="mainHeader"> <h1> <img src="images/icon.png" alt="icon" /> </h1> </header> <section data-role="content"> </section> <footer data-role="footer" data-position="fixed" id="footerNavBar"> <div data-role="navbar" data-id="footerNavBar"> <ul> <li><a href="index.html" data-icon="home" data-iconpos="bottom" data-prefetch>Home</a></li> <li><a href="link2.html">Link 2</a></li> </ul> </div> </footer> </div> 
+1
source share

I found that adding a tab (footer) outside the jqt div works fine.

My DZ / jQT fork β†’ https://github.com/DataZombies/jQTouch

Demo β†’ http://web.me.com/djpinter1/iPhone/jqtouch/demos/main_tabbar/

0
source share

I managed to solve this problem as follows. This was made possible thanks to Mikkel's answer, so thanks for sharing this!

 /* */ function prepareHeaderFooterForULDiving(pageName) { // dynamically move the header and footer between pages on load events $(document).bind('pagebeforeshow', function(event, ui) { // If the previous page length is zero then we couldn't possibly be drilling into a nested list this very moment if (ui.prevPage.length == 0) return; var pathname = window.location.pathname; var fullPath = $(location).attr('href'); //alert (pathname +" versus1 "+fullPath); // Don't add an extra header and footer to a page that doesn't need it // The pathname must end with the page name and the fullPath must NOT end with .php (all nested list pages will have extra pieces) var regex = new RegExp(pageName+"$"); if (pathname.match(regex) && !fullPath.match(/.php$/)) { $headerObj = $('[id^=header]:last'); $footerObj = $('[id^=footer]:last'); // Since we find the latest header and footer (and since that latest one might be the one we want to display var beginningState = event.currentTarget.innerHTML; var beginningHeader = $headerObj[0].outerHTML; var beginningFooter = $footerObj[0].outerHTML; // Before we copy the header and footer, find out if we are copying a copy or not; if we are, // make sure we add special handling to get rid of the first copy when we hide the current page var alreadyHadClass = $headerObj.hasClass('to-remove'); // copy the code from the current header and footer but before you clone it, add the to-remove class to it; that way // we only end up removing the footers and headers that we have dynamically added! // Get the latest header and footer; there a possibility the header would be grabbed from a prior loaded page that isn't presently visible (and with a misleading phrase) // Multiple layers of ULs could end up causing the wrong footer to be removed $headerObj.addClass('to-remove'); $footerObj.addClass('to-remove'); var header = $headerObj[0].outerHTML; var footer = $footerObj[0].outerHTML; // Now that we know that we are going to be drawing on this particular branch of the contactUs.php UL leaf, mark every previous // leaf (if applicable in higher or lower part of the tree) for immediate removal once the page is hidden // Do NOT do this before we clone if (alreadyHadClass) { $('.to-remove').addClass('removeOncePageHidden'); } // Remove the temporary designation; this way we don't accidentally remove contactUs.php header when we return $headerObj.removeClass('to-remove'); $footerObj.removeClass('to-remove'); // Optionally, you could remove the auto-generated header (with the next ul content); but I kinda like it // remove the jQuery Mobile-generated header //$('.ui-header').addClass('to-remove-now'); //$('.to-remove-now').remove(); // For some crazy reason this pagebeforeshow can be fired TWICE! Ridiculous I know; only update the screen if it doesn't // already look like that. Otherwise, you'll end up with a flashing of an instant where the first-added header and footer // display and then get removed during the pagehide if ( beginningState.indexOf(beginningHeader) != -1 || beginningState.indexOf(footer) != -1 ) { // this script has just been fired twice and the header that we copied we don't need any more; the page is fine except that we just removed the class that needs to stay there console.log("Didn't do it!"); $headerObj.removeClass('removeOncePageHidden'); $footerObj.removeClass('removeOncePageHidden'); } else if ( beginningState.indexOf(header) == -1 && beginningState.indexOf(footer) == -1 ) { // prepend the header and append the footer to the generated HTML console.log("weird: "+header+"\nbut the kicker: "+beginningState); event.currentTarget.innerHTML = header + event.currentTarget.innerHTML + footer; } else { // We didn't just create a new one so undo the addition of the 'remove it now' Class; we'll // go ahead and keep it since this code has been fired twice now for one page load console.log("whoah"); $headerObj.removeClass('removeOncePageHidden'); $footerObj.removeClass('removeOncePageHidden'); } } }); $(document).bind('pagehide', function(event, ui) { $('.removeOncePageHidden').remove(); var fullPath = $(location).attr('href'); //alert ("Should we remove anything here: "+fullPath); // We only need to run this code when we're navigating into a page that is a top-level page (nested-list-generated pages have 'fun' characters appended beyond the .php) if (fullPath.match(/.php$/)) { //alert("Removing all to-removers"); $('.to-remove').remove(); } }); } 

This is my first foray into jquerymobile scripts, so there may be some problematic aspect that I don’t know about, but all my navigation attempts have succeeded in creating the behavior I was looking for. Curiously, the script seems to have continued to shoot even after I left my contact page. My if statements contained this from misbehavior, but perhaps this is something others should be careful about.

My footer is not a fixed position, which seems to have a different behavior or response to this, but maybe this will also help you.

-one
source share

All Articles