Attribute Description

Attribute Description

data-role The value of the data-role attribute defines the type of UI element that will be created once the HTML has been processed by jQuery Mobile. Primarily, UI elements are transformed by the jQuery Mobile library at runtime by simply adding relevant CSS classes which influence the look and feel of the original HTML. In some cases, jQuery Mobile will also add additional HTML elements to the DOM to create the relevant mobile web page.

data-id The data-id element is used to specify a unique identifier for the UI control. This ID can be used to tell jQuery Mobile that a particular element should remain consistent between different pages in the UI.

data-icon Some UI elements (such as the button control) can contain icons to help represent the purpose of the control. Icons are specified using a name that relates to a particular icon. There are a number of built-in icons that can be used, such as the one in our sample. Additionally, you can use custom icons by specifying a unique identifier and then defining some custom CSS for that icon. More information can be found at the following URL: http://jquerymobile.com/demos/1.0a2/#docs/buttons/buttons-

icons.html

With our modified HTML with the data-role attributes in place, jQuery Mobile can begin to work with our application layout. Figure 11–14 shows an example of the UI generated from the preceding index.html file.

CHAPTER 11: Mobile UI Frameworks Compared

Figure 11–14. The initial effort with jQuery Mobile yields a header and footer, but not much of a map. As with our work with the other frameworks so far, the default instructions for including a

Google map don’t yield a very positive result. As such, some special treatment is going to be required to display the map correctly.

NOTE: When writing this book, we got to framework three and the integration of a Google map still consistently failed, so it was time to do some further investigation. Was it just one version of Android that had this issue? It would appear not—testing with Android 1.6, 2.1, and 2.2 all revealed the same problem across the board.

While not conclusive, this seems tied to the fact that each of the frameworks makes use of absolute positioning to some degree with regard to controlling their layouts. This in turn makes correctly sizing child div elements difficult, and yields an incorrect map display. It’s something that can be worked around, but it is nonetheless frustrating.

As with our work with jQTouch, the fix is to manually size the map container to fit the containing page. We will make our adjustments to moundz.js to do that, and perform some other initialization to prepare the Moundz UI. As with earlier examples, we make our adjustments to the screen layout in the initScreen function:

function initScreen() { // size the canvas to the height of the page minus the header $('#map_canvas').height(

$('#main').height() - $('#main div[data-role="header"]').outerHeight() - $('#main div[data-role="footer"]').outerHeight() - 30

CHAPTER 11: Mobile UI Frameworks Compared

); } // initScreen

In this case, the changes required are relatively minor, but hardly scientific. We essentially size the height of the map to the height of the page (the #main div) minus the height of the header and footer within the page (plus a fudge factor of 30 pixels to have everything display accurately). With that change complete, our Moundz main screen is starting to look the part. Figure 11–15 shows an example.

Figure 11–15. The jQuery Mobile Moundz interface is starting to come together. With the interface starting to come together, we just need to make some further

modifications to moundz.js to get things working with our modified HTML. First, we will update the activateMarker function to update the middle button on the

page footer: function activateMarker(marker) {

// iterate through the markers and set to the inactive image for (var ii = 0; ii < markers.length; ii++) {

markers[ii].setIcon('img/pin-inactive.png'); } // for

// update the specified marker's icon to the active image marker.setIcon('img/pin-active.png');

// update the navbar title using jQuery $('#marker-nav a[href="#marker-detail"]')

.unbind('tap’) .find('.ui-btn-text')

.html(marker.getTitle());

CHAPTER 11: Mobile UI Frameworks Compared

// if content has been provided, then add the has-detail // class to adjust the display to be "link-like" and // attach the click event handler var content = markerContent[marker.getTitle()]; if (content) {

$('#marker-nav a[href="#marker-detail"]') .tap(function() { $('#marker-detail div[data-role="content"]').html(content); });

} // if

// update the marker navigation controls updateMarkerNav(getMarkerIndex(marker));

} // activateMarker While the start of the code here is exactly the same as we had in the non-framework

version, there are some differences after that:

1. Rather than target the anchor using a class selector, we are now using an attribute selector to find the link that takes us to the #marker-detail page.

2. Once that link is found, we unbind from the tap event rather than the click event, as jQuery Mobile uses these tap events to communicate that the user has tapped

a particular control on the screen.

3. Next, we locate a span with the ui-btn-text class within the anchor tag and replace its content with the title of the marker. As mentioned previously, for some of the data-role types, jQuery Mobile will generate additional HTML elements to properly create the look and feel needed for the UI. This is the case with buttons. As such, we need to update the text within the ui-btn-text span within the anchor rather than the text of the anchor itself.

4. We then move on to binding to the tap event of the button when a marker has content. As before, we locate the link that will take us to the #marker-detail page

and add a handler to the tap event that will occur. The handler for this tap event simply updates the HTML content in the content area of the #marker-detail page, in a similar way to what our non-framework UI did previously.

Once these changes have been made, you should be able to navigate to a detail screen in the application by clicking the middle button in the footer. Figure 11–16 shows how the two pages should look in an Android emulator.

CHAPTER 11: Mobile UI Frameworks Compared

Figure 11–16. We now have the basis of a working multipage jQuery Mobile application. Now that we have simple paging working in the application, we just need to attach

appropriate event handlers to allow our user to navigate between all the resource locations that are displayed. We do this by making some fairly subtle changes to the updateMarkerNav function:

function updateMarkerNav(markerIndex) { // find the marker nav element var markerNav = $('#marker-nav');

// reset the disabled state for the images and unbind click events markerNav.find('a')

.addClass('disabled') .unbind('tap');

// if we have more markers at the end of the array, then update // the marker state if (markerIndex < markers.length - 1) {

markerNav.find('a.right')

.removeClass('disabled') .tap(function() {

activateMarker(markers[markerIndex + 1]); });

} // if

if (markerIndex > 0) { markerNav.find('a.left')

.removeClass('disabled') .tap(function() {

activateMarker(markers[markerIndex - 1]);

CHAPTER 11: Mobile UI Frameworks Compared

}); } // if } // updateMarkerNav

Here, we’re essentially just replacing our search for img tags within the #marker-nav div with a search for anchor elements instead. Additionally, as before, we replace references to click events with appropriate tap handlers.

That’s it. Our Moundz application as it existed before has been converted to a jQuery Mobile application with relative ease.