Nested Content with Navbars using jQuery Mobile

I’ve been messing around with jQuery Mobile lately with the intention of using it in conjunction with Apache Cordova to build an Android app. I ran into a situation where I wanted to present different parts of the UI within an individual page depending on the item selected in a navbar on that page. This is useful for things like splitting up long forms. It took me a bit to figure out the solution, so I thought I’d share it.

Below is what the markup for my page looks like, where each link in the navbar uses an anchor that corresponds to a nested div in the content area.

<div data-role="page">
  <div data-role="header">
    <div data-role="navbar">
      <ul>
        <li><a href="#one" class="ui-btn-active ui-btn-persist">One</a></li>
        <li><a href="#two">Two</a></li>
        <li><a href="#three">Three</a></li>
      </ul>
    </div>
  </div>
  <div data-role="content">
    <div id="one">One content</div>
    <div id="two">Two content</div>
    <div id="three">Three content</div>
  </div>
</div>

Below is what the JavaScript looks like to make this work.

(function($) {

// Before handling a page change...
$(document).bind("pagebeforechange", function(e, data)
{
    // If the new page is not being loaded by URL, bail
    if (typeof data.toPage !== "string")
    {
        return;
    }

    // If the new page has a corresponding navbar link, activate its content div
    var url = $.mobile.path.parseUrl(data.toPage);
    var $a = $("div[data-role='navbar'] a[href='" + url.hash + "']");
    if ($a.length)
    {
        // Suppress normal page change handling since we're handling it here for this case
        e.preventDefault();
    }
    // If the new page has a navbar, activate the content div for its active item
    else
    {
        $a = $(url.hash + " div[data-role='navbar']").find("a.ui-btn-active");

        // Allow normal page change handling to continue in this case so the new page finishes rendering
    }

    // Show the content div to be activated and hide other content divs for this page
    var $content = $($a.attr("href"));
    $content.siblings().hide();
    $content.show();
});

})(jQuery);

Here’s what this looks like in action:

Demo of nested content areas accessible via navbar links

I’d be curious to know if there are other better or more efficient ways of handling this.

One Comment

  1. sha says:

    Hy very usefull! one question when i load navbar contain show me all div
    in a index page i’ve to hide two div belove first
    this is example I try to explain
    http://preprod.netsons.org/calcionews/
    thanks