Recipe 26Creating Interfaces with jQuery Mobile

Problem

Developing native applications for mobile devices isn’t a simple task, and the programming knowledge required, and in some cases license fees, can create a barrier to entry. Android and iOS application development is typically done with Java and Swift, respectively. These are languages that many web developers don’t have experience using.

Our catalog needs a mobile-friendly version. Native applications for the iOS and Android platforms would be ideal, but we don’t have the time, resources, or knowledge to build them.

Ingredients

  • jQuery

  • jQuery Mobile[63]

  • QEDServer (for our test server)[64]

Solution

To solve this problem, we can bring together the benefits of both web applications and native applications. With jQuery Mobile, we can use HTML5, JavaScript, and CSS3 to develop web applications that behave similarly to native applications for mobile platforms. jQuery Mobile makes it easy to develop native-feeling applications using the tools we’re already familiar with.

We’ll explore jQuery Mobile by creating a site to browse through our company’s catalog. Our application will allow the user to view and search our merchandise. When we’re done, we’ll have built a mobile interface that looks like the figure.

images/jquerymobile/jqm_home.png

Creating an application with jQuery Mobile relies on some semantic HTML and the data attributes available in HTML5. Using these attributes, we can build most of the application without writing any extra JavaScript.

Building the Document

Let’s set up an HTML file to use jQuery Mobile. Our application will run on QEDServer. In the public folder of the server, create a file called index.html and add this boilerplate HTML to get started:

jquerymobile/index.html
 
<!DOCTYPE html>
 
<html​ lang=​"en"​​>
 
<head>
 
<meta​ charset=​"utf-8"​​>
 
<meta​ name=​"viewport"​ content=​"width=device-width, initial-scale=1"​​>
 
<title>​Incredible Products from AwesomeCo​</title>
 
<link​ rel=​"stylesheet"
 
href=​"http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css"​​>
 
</head>
 
 
<body>
 
<script
 
src=​"http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"​​>
 
</script>
 
<script
 
src=​"http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"​​>
 
</script>
 
<script​ src=​"products.js"​​>
 
</script>
 
</body>
 
</html>

The boilerplate includes four files: the jQuery Mobile CSS, the jQuery library, the jQuery Mobile script itself, and a file for us to add our own JavaScript. Now we’re ready to start adding pages and content to the application.

Creating Pages

A jQuery Mobile application consists of a set of pages. These pages can link to one another, but we can show only one page on the screen at a time, even though they all exist on the same HTML page. To build a page in jQuery Mobile, we use a <div> that has a data-role attribute set to page. When the framework runs, it loads whichever page comes first in the body of our HTML. Following that pattern. we’ll start by creating our home screen. Let’s add the following code below our opening <body> tag and above the <script> tags:

jquerymobile/index.html
 
<div​ data-role=​"page"​ id=​"home"​​>
 
<div​ data-role=​"header"​​>
 
<h1>​AwesomeCo​</h1>
 
</div>
 
<div​ data-role=​"main"​ class=​"ui-content"​​>
 
</div>
 
<div​ data-role=​"footer"​​>
 
<h4>​&copy; AwesomeCo​</h4>
 
</div>
 
</div>

Each page can have three sections: a header, content, and a footer. The header holds information about the current page in an <h1> tag. The header also can hold buttons for navigation within the application, as we’ll see later. The content region can hold any number of paragraphs, links, lists, forms, and any other markup you would use on a normal web page. The footer is an optional section that can hold a copyright or any other information we want on the bottom of every page.

Now that our landing page is ready, let’s create a few items to populate the content. We need some buttons to get to the other pages in our application, so let’s place the following code inside our main <div>:

jquerymobile/index.html
 
<div​ data-role=​"main"​ class=​"ui-content"​​>
 
<p>​Welcome to AwesomeCo, your number one source
 
for all things awesome.​</p>
 
 
<div​ data-role=​"controlgroup"​​>
 
<a​ href=​"#products"​ class=​"ui-btn"​​>​View All Products​</a>
 
<a​ href=​"#search"​ class=​"ui-btn"​​>​Search​</a>
 
</div>
 
</div>

First we create a paragraph giving some information about the application. Then we make a <div> with a role of controlgroup. This role removes the margin between the links so they appear as one set, as you can see in the next figure. We also give the anchors a class of ui-btn so that they’re styled accordingly. The two anchors link to other pages by setting the ID of the target page in the href attribute.

images/jquerymobile/without_icons.png

These buttons look great, but they could be enhanced to give some more feedback to the user. To add an icon to a button, we add a ui-icon-* class. The available icons can be found in the jQuery Mobile documentation,[65] but for our page we use the right-arrow icon and the search icon:

jquerymobile/index_icons.html
 
<div​ data-role=​"controlgroup"​​>
 
<a​ href=​"#products"​ class=​"ui-btn ui-icon-arrow-r ui-btn-icon-left"​​>
 
View All Products​</a>
 
<a​ href=​"#search"​ class=​"ui-btn ui-icon-search ui-btn-icon-left"​​>
 
Search​</a>
 
</div>

With these buttons, our home page navigation is complete. We’ve created a button group that will bring us to the various parts of our application and added customization to give some more feedback to the user.

The buttons we’ve added look good, but they don’t go anywhere yet. We need to add another page to the markup so that we can be sure the links actually go somewhere:

jquerymobile/index.html
 
<div​ data-role=​"page"​ id=​"products"​​>
 
<div​ data-role=​"header"​​>
 
<h1>​Products​</h1>
 
</div>
 
<div​ data-role=​"main"​ class=​"ui-content"​​>
 
</div>
 
 
<div​ data-role=​"footer"​​>
 
<h4>​&copy; AwesomeCo​</h4>
 
</div>
 
</div>

Now when we load the page in our browser and click the product link, we should see the application transition to the products page.

Viewing Products

With the products-list markup in place, it’s time to add the actual content so users can see what we offer. Since QEDServer has this data for us, we’ll use jQuery to load the product list via Ajax. First let’s make sure we have some products in the database by navigating to the nonmobile version at http://localhost:8080/products. If your database doesn’t contain any records, feel free to create a few placeholder items.

Since we’ve already created the structure for the products page, let’s create an empty <ul> in our content section to hold our list of products:

jquerymobile/index.html
 
<div​ data-role=​"main"​ class=​"ui-content"​​>
*
<ul​ id=​"products-list"​ data-role=​"listview"​​>​​</ul>
 
</div>

The <ul> has a role of listview so that jQuery Mobile knows how to style it. We also set an ID so we can easily reference it with jQuery when we want to update the list. If we reload the application and navigate to the products page, it’s pretty empty. To load some products, we use the custom events in jQuery Mobile to load the content dynamically when the user requests the page:

jquerymobile/products.js
 
(​function​($) {
 
var​ $products_page = $(​'#products'​),
 
$products_list = $(​'#products-list'​),
 
$product_page = $(​'#product'​);
 
 
$products_page.bind(​'pagebeforeshow'​, ​function​() {
 
$.getJSON(​'/products.json'​, ​function​(products) {
 
var​ $product_list_item;
 
$products_list.html(​''​);
 
 
$.each(products, ​function​(i, product) {
 
$product_list_item = $(​'<li>'​).append(
 
$(​'<a>'​)
 
.attr(​'href'​, ​'#product'​)
 
.text(product.name)
 
.data(​'transition'​, ​'slide'​)
 
);
 
$products_list.append($product_list_item);
 
});
 
 
$products_list.listview(​'refresh'​);
 
});
 
});
 
})(jQuery);

We bind to the page’s pagebeforeshow event to load the product list before the page is shown. The getJSON request queries the server and returns an array of products. Those products are iterated over and added to the list. Since we create new HTML, we refresh the listview, which tells jQuery Mobile to apply styles to newly inserted elements.

Now when we navigate to our products page we’re given a list of products to browse that looks like the figure.

images/jquerymobile/products.png

Our last goal for viewing the products is to create a show page for a specific product. When we tap a product on the product-list page, we want to show the details. Since we don’t want to create a page for each product, we’ll dynamically load the product and use a single-page template for all of our products. First we need to head back to where we generated the contents for the products listview. We need to add data attributes to the anchors to keep track of the product ID we want to navigate to, so we add a custom data attribute called data-product-id to the list of attributes we’re appending to the list items:

jquerymobile/products.js
 
$.each(products, ​function​(i, product) {
 
$product_list_item = $(​'<li>'​).append(
 
$(​'<a>'​)
 
.attr(​'href'​, ​'#product'​)
 
.text(product.name)
 
.data(​'transition'​, ​'slide'​)
*
.data(​'product-id'​, product.id)
 
);
 
$products_list.append($product_list_item);
 
});

Now that we’re tracking the product ID for each of the links, we can create a page to show the product. Let’s create the header, footer, and content <div>s for this page, as we did before with the list page:

jquerymobile/index_icons.html
 
<div​ data-role=​"page"​ id=​"product"​​>
 
<div​ data-role=​"header"​ id=​"product-header"​​>
 
<a​ href=​"#products"​ class=​"ui-btn ui-icon-back ui-btn-icon-left"
 
data-role=​"back"​ data-direction=​"reverse"
 
data-transition=​"slide"​​>​Back​</a>
 
<h1>​Product​</h1>
 
</div>
 
 
<div​ data-role=​"main"​ class=​"ui-content"​ id=​"product-content"​​>
 
<p​ class=​"description"​​>​​</p>
 
<span​ class=​"price"​​>​​<strong>​​</strong>​​</span>
 
</div>
 
 
<div​ data-role=​"footer"​​>
 
<h4>​&copy; AwesomeCo​</h4>
 
</div>
 
</div>

We create a back button in the header <div> that brings us back to the product list. We use the slide transition, as we did on the product-list page, but we add a reverse value for the data-direction attribute so the transition goes from right to left.

The last step to showing a product on the page is to intercept the navigation event and load the data from the server. Before, we asked the server to get information about several products. This time we get information about a single product and build the product view using the response. Let’s write the JavaScript to complete our product navigation. We add the following code right above the last line in our products.js file:

jquerymobile/products.js
 
$products_list.on(​'tap'​, ​'a'​, ​function​(e) {
 
requestProduct($(this).data(​'product-id'​));
 
});
 
 
function​ requestProduct(product_id) {
 
$.getJSON(​'/products/'​ + product_id + ​'.json'​, showProduct);
 
}
 
 
function​ showProduct(product) {
 
$(​'#product-header h1'​).text(product.name);
 
$(​'#product-content p.description'​).text(product.description);
 
$(​'#product-content span.price strong'​).text(​'$'​ + product.price);
 
}

We start off by binding to the tap event, which is a custom event in jQuery Mobile. Since the raw tap events on mobile browsers differ so greatly, the jQuery Mobile tap event removes the inconsistencies and offers a single interface for managing touch events. Next we store a reference to the product ID so that we can make a call with getJSON. On the success event we change the text of the product page to use the data we received.

images/jquerymobile/asingleproduct.png

Now we have a smooth interface that allows us to view products and their details. A single product page now looks like the image.

Further Exploration

We’ve only touched on a few of the features available through jQuery Mobile. Check out the API[66] for more details on other options this framework makes available to developers.

When we started this chapter, we added a search link on the home page that doesn’t actually do anything. Following the patterns we’ve established, and by referencing the API, it would be relatively easy to implement this functionality.

Also See

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.15.160.43