Chapter 1. Creating a Mobile Enabled Shopping Cart with HTML5, jQuery, and TaffyDB, Part 1

The changing mobile landscape, and newer web technologies, means that working with mobile commerce requires a new approach to an old problem. This tutorial will take you through the steps to create a simple mobile commerce site that provides an interactive shopping experience over low-bandwidth connections. Part one of this tutorial will walk you through using PHP5, jQuery, and Taffy DB to create an interactive product catalog. Part two of this tutorial will walk you through using an HTML5 database to store a shopping cart and show you how to submit the shopping cart to a server at the time of checkout.

If you’d like to follow along, you can download the files for the project template here. The final source files that you’ll have created by the end of this tutorial are here.

Step 1: Set Up the Tutorial Directory on Your Web Server

You will be able to complete this tutorial using a standard web server that has PHP5 installed. To get started, create a new directory on your web server named tutorial. Inside the tutorial directory, create two directories: css and js. Under the js directory, create a directory named lib.

When you are done, the directory structure should look like this:

  • tutorial/css/

  • tutorial/js/

  • tutorial/js/lib/

Next, download the following source libraries:

Place the file html5resetcss.css in the tutorial/css/ directory, and place the jQuery, Taffy DB, and JSON javascript files in the tutorial/js/lib/ directory.

Finally, create the following four empty files.

  • tutorial/catalog.php

  • tutorial/index.html

  • tutorial/js/site.js

  • tutorial/css/site.css

We’ll will be working with these four files in this tutorial.

Step 2: Provide the Entire Product Catalog in JSON Format from the eCommerce System

In order to minimize http requests between the mobile device and the server while a customer is browsing the product catalog, we’re going to download the entire catalog from the ecommerce system when the catalog is viewed in a browser. Note that if you are working with a very large catalog, you may want to download categories or subcategories as needed instead of the full catalog.

We’ll start with defining the category and product information with arrays. In practice, these arrays will contain the results of database queries from your PHP5-based ecommerce system. For this tutorial, open the file catalog.php, and add the following category and product information:

<?php

// simulates result of db query for categories
$categories = array();
$categories[] = array(id => 1, parent_id => 0, name => 'root');
$categories[] = array(id => 2, parent_id => 1, 
    name => 'Compact Discs');
$categories[] = array(id => 3, parent_id => 1, 
    name => 'Concert Souvenirs');

// simulates result of db query for products
$products = array();
$products[] = array(id => 1, category_id => 2, sku => 'CD001', 
    price=>15.00, name => 'CD: Greatest Hits');
$products[] = array(id => 2, category_id => 2, sku => 'CD002', 
    price=>15.00, name => 'CD: Unplugged');
$products[] = array(id => 3, category_id => 2, sku => 'CD003', 
    price=>15.00, name => 'CD: World Tour');
$products[] = array(id => 4, category_id => 3, sku => 'PD001', 
    price=>10.00, name => 'Souvenir Pin');
$products[] = array(id => 5, category_id => 3, sku => 'PD002', 
    price=>10.00, name => 'Mug');
$products[] = array(id => 6, category_id => 3, sku => 'PD003', 
    price=>20.00, name => 'Hat');
$products[] = array(id => 7, category_id => 3, sku => 'PD004', 
    price=>12.00, name => 'Summer Tour Poster');
$products[] = array(id => 8, category_id => 3, sku => 'PD005', 
    price=>5.00,  name => 'Concert Program');
?>

Notice that the categories have a parent_id field, which contains the id of the parent category, and a category_id field, which contains the id of the product’s category. These fields will be used later in this tutorial to find child categories and products for a parent category id.

Next, we’ll convert the category and product information to JSON objects and arrays using the json_encode function that is provided by PHP5. Append the following code to the end of catalog.php:

// create the response
$response = array(categories => $categories, products => $products);

// display the json encoded response
echo json_encode($response);

That’s it. When catalog.php is viewed in a browser, the category and product information will be provided as JSON objects and arrays. You can try it out by opening catalog.php in a browser.

I find it helpful to validate the JSON output at http://www.jslint.com to ensure the conversion is working correctly. Copy the output from catalog.php, paste it into the JSLint form, and submit. If you get the result message: “JSON: good.”, you can move on to Step 3: Set Up the Catalog HTML Page.

Step 3: Set Up the Catalog HTML Page

For this tutorial, customers will be able to browse our mobile commerce site using three views:

  1. The store view, which displays a list of product categories in the store.

  2. The category view, which displays a list of products in a category.

  3. The product view, which displays the details of a product.

To increase the responsiveness of our mobile commerce site on a mobile device, we’ll be using a single HTML page to present all three views, and we’ll use JavaScript and CSS to change the visibility of views and to update the view content as customers browse the site. We’ll start by defining the basic structure for our mobile commerce site. Open the file named index.html, and add the following code:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; 
charset=utf-8" />
        <title>Concert Catalog</title>

		<!-- iOS -->
		<meta name="apple-mobile-web-app-capable" content="yes">
		<meta name="apple-mobile-web-app-status-bar-style" content="black">
		<meta name = "viewport" content = "width = device-width, 
initial-scale = 1, user-scalable = no">

		<style type="text/css" media="screen">
			<!--
			@import url(css/html5reset-1.4.1.css);
			@import url(css/site.css);
			-->
		</style>

		<script type="text/javascript" src="js/lib/jquery-1.4.2.min.js">
</script>
		<script type="text/javascript" src="js/lib/taffy-min.js"></script>
		<script type="text/javascript" src="js/lib/json2.js"></script>
		<script type="text/javascript" src="js/site.js"></script>

    </head>
    <body></body>
</html>

Next, we’ll add containers to index.html to display the store, category, and product views. Add the following code inside of the body element:

<div id="content">
    <div id="store"></div>
    <div id="category"></div>
    <div id="product"></div>
</div>

Step 4: Load the Product Catalog in JSON Format from the eCommerce System

Each time the mobile commerce site is viewed, the product catalog will be retrieved from the server in JSON format.

We’ll start by creating a function in the file site.js to get the catalog JSON data using the jQuery ajax function. Open the file site.js, and add the following code:

var demo = {};
demo.categories = null;
demo.products = null;

demo.viewStore = function()
{

}

demo.loadCatalog = function()
{
	$.ajax( {
		url : 'catalog.php',

		success : function(result) {
			// parse json result
			var catalog = JSON.parse(result);

			// init Taffy DB collections
			demo.categories = new TAFFY(catalog.categories);
			demo.products = new TAFFY(catalog.products);

			// view the store
			demo.viewStore();
		},

		error: function (request, status, error) {
	        		alert(request.responseText);
	    	}
	});

}

$(function(){
	demo.loadCatalog();
});

When the document is ready, the function demo.loadCatalog will be called, which will make an ajax request to get the output of the file catalog.php. If the request is successful, the response text will be passed to the success function, which will parse the text into a JavaScript object, and assign the object to a local variable named catalog.

Next, the success function will create Taffy DB collections for the categories and products using the catalog content. The collections will be assigned to the variables: demo.categories and demo.products.

Finally, the success function will call demo.viewStore, which will update the contents of the store view and display the store view to the customer.

If you are not familiar with Taffy DB, it is a great tool that simplifies working with collections of JavaScript objects. We’ll use it in the next sections to populate the data in the store, category, and product views.

Step 5: Display the Store View

Now that the catalog data has been loaded into Taffy DB collections, we can start working to displaying the catalog content to the customer. We’ll start with the store view by adding HTML elements to the div with the id store to hold the store name and the list of store categories. Replace the div with the id store with the following code:

<div id="store">
<nav>
	<h1 class="name">Our Band's Concert Store</h1>
</nav>
    <div class="category-list"></div>
</div>

Next we’ll update the demo.viewStore JavaScript function in order to get the category data from the Taffy DB collections, create the category list HTML content, and bind JavaScipt to the category links. Replace the function demo.viewStore with the following code:

demo.setCurrentView = function(viewId)
{
	// remove the class: current from all the views
	$('#content > *').removeClass('current');

	// add the class: current to the view with the id viewId
	$(viewId).addClass('current');
}

demo.viewStore = function()
{
	demo.setCurrentView('#store');

	// get the data from TaffyDB
	var categories = demo.categories.get({parent_id:1});

	// create the html for the navigation links
	var html = '<ul>';
	for(i in categories)
	{
		html += '<li>';
		html += '<a href="#" id="' + categories[i]['id'] + '">' + 
categories[i]['name'] + '</a>';
		html += '</li>';
	}
	html += '</ul>';

	// add the html to the view
	$('#store .category-list').empty().append(html);

	// bind the navigation links
	$('#store .category-list a').click(function(e){
		e.preventDefault();

		var id = parseInt($(this).attr('id'), 10);
		demo.viewCategory(id);
	});
}

When the function demo.viewStore is called, the function will first set the store view to be the current view by calling the function demo.setCurrentView. This will add the class “current” to the div with the id store.

The function will get the categories from the Taffy DB category collection where the parent_id of the category is equal to 1. This will return an array of category objects, which is then used to create links to the categories.

Next, the onclick function of the category links is changed to open the category view using the function demo.viewCategory.

Finally, we’ll update site.css to hide all the views, except the current view. Open site.css, and add the following code:

#content {
	width: 320px;
	min-height: 480px;
	background-color: lightyellow;
}

#content > div {
    display: none;
    width: 320px;
    min-height: 480px;
    padding: 10px;
}

#content > .current {
    display: block;
}

Step 6: Display the Category View

Similar to store view, we’ll start by adding HTML elements to the div with the id category to hold the category name and the list of category products. Replace the div with the id category with the following code:

<div id="category">
   	<nav>
       	<button class="back">Back</button>
    	<h1 class="name"></h1>
   	</nav>
   	<div class="product-list"></div>
</div>

Next we’ll add the demo.viewCategory JavaAcript function in order to get the category and product data from the Taffy DB collections, create the product list HTML content, and bind JavaScipt to the product links. Open the file site.js, and add the following code after the function demo.viewStore:

demo.viewCategory = function(categoryId)
{
	demo.setCurrentView('#category');

	// get the data from TaffyDB
	var category = demo.categories.get({id:categoryId}).pop();
	var products = demo.products.get({category_id: categoryId});

	// create the html for the navigation links
	var html = '<ul>';
	for(i in products)
	{
		html += '<li>';
		html += '<a href="#" id="' + products[i]['id'] + '">' + products[i]
['name'] + '</a>';
		html += '</li>';
	}
	html += '</ul>';

	// add the thml to the view
	$('#category .product-list').empty().append(html);

	// update the category name
   	$('#category .name').text(category.name);

	// bind the navigation links
	$('#category .product-list a').click(function(e){
		e.preventDefault();

		var id = $(this).attr('id');
		demo.viewProduct(id);
	});

	// bind the back button
	$('#category .back').click(function(e){
		e.preventDefault();
		demo.viewStore();
	});
}

When the function demo.viewCategory is called, the function will first set the category view to be the current view by calling the function demo.setCurrentView. This will add the class “current” to the div with the id category.

Next, the function will get the category from the Taffy DB category collection where the id of the category is equal to categoryId, and the function will get the products from the Taffy DB product collection where the category_id of the product is equal to categoryId. This will return an array of product objects, which is then used to create links to the products.

Finally, the onclick function of the product links is changed to open the product view using the function demo.viewProduct. Also, the onclick function of the back button is changed to open the store view using the function demo.viewStore.

You should now be able to open the store view and browse to a category view.

Step 7: Display the Product View

Similar to the store and category views, we’ll start by adding HTML elements to the div with the id product to hold the product details. Replace the div with id product with the following code:

<div id="product">
	<div class="message"></div>
		<nav>
			<button class="back">Back</button>
			<h1>Product Details</h1>
		</nav>
		<div class="product-details">
			<dl>
				<dt>Name</dt><dd class="name"></dd>
				<dt>SKU</dt><dd class="sku"></dd>
				<dt>Price</dt><dd class="price"></dd>
				<dt>Quantity</dt><dd class="quantity"><input type="text" />
</dd>
			</dl>
			<button class="add-to-cart">+ Add to Cart</button>
		</div>
</div>

Next we’ll add the demo.viewProduct JavaScript function in order to get the product data from the Taffy DB product collection, create the product detail HTML content, and bind JavaScipt to the links. Open the file site.js, and add the following code after the function demo.viewCategory:

demo.formatStringAsCurrency = function(str)
{
	var price = parseFloat(str, 10);
	return '$'+price.toFixed(2);
};

demo.viewProduct = function(productId)
{
	demo.setCurrentView('#product');

	// get the data from TaffyDB
	var product = demo.products.get({id:productId}).pop();
	var category = demo.categories.get({id:product.category_id}).pop();

	// update the product details
	$('#product .name').text(product.name);
	$('#product .sku').text(product.sku);
	$('#product .price').text(demo.formatStringAsCurrency(product.price));

	// bind the back button
	$('#product .back').click(function(e){
		e.preventDefault();
		demo.viewCategory(product.category_id);
	});
}

When the function demo.viewProduct is called, the function will first set the product view to be the current view by calling the function demo.setCurrentView. This will add the class “current” to the div with the id product.

Next, the function will get the product from the Taffy DB product collection where the id of the product is equal to productId, and the function will get the category from the Taffy DB category collection where the id of the category is equal to the category_id of the product. This will return an array of category and product objects. Notice that the array function pop is used to get the category and product objects from the arrays.

The function populates the HTML elements with the product attributes; notice that the function demo.formatStringAsCurrency is used to format the price value. The onclick function of the back button is changed to open the category view using category_id attribute of the product.

Last, we’ll update site.css to format the display of the product details. Open site.css, and add the following code:

dl {
	width: 300px;
}

dt, dd {
    display: inline-block;
    line-height: 30px;
    border-top: 1px dashed silver;
}

dt:first-child, dd:nth-child(2) {
    border-top: none;
}

dt {
    width: 25%;
    font-weight: bold;
}

dd {
    width: 75%;
}

You should now be able to browse the catalog by clicking the category and product links. You can move back up to the previous view by clicking the back button at the top of the view.

For the final step, we’ll update site.css to format the display of the links and buttons. Open the file site.css, and add the following code:

body {
	font-family: Helvetica, sans-serif;
}

a {
	-webkit-tap-highlight-color: rgba(150, 150, 150,.5);
}

h1 {
	margin-bottom: 5px;
}

button {
	height: 30px;
}

nav {
	width: 300px;
	height: 44px;
	line-height: 44px;
	margin-bottom: 5px;
}

	nav h1 {
		display: inline-block;
	}

	nav .back {
		margin-right: 20px;
	}

ul {
	width: 300px;
}

ul a {
    height: 44px;
    line-height: 44px;
    padding-left: 10px;
    border: 1px solid silver;
    border-top: none;
    color: #222;
    text-decoration: none;
    display: block;
    background-color: white;
}

ul li:first-child a {
    border-top: 1px solid silver;
}

#product .add-to-cart {
	margin-top: 20px;
	width: 300px;
}

.message {
	display: none;
}

That’s It

That’s it! You should now have a simple working mobile commerce site that allows you to interactively browse a product catalog using a single web page. In part two of this tutorial, we’ll walk through using an HTML5 database to store a shopping cart and how to submit the shopping cart to a server at the time of checkout.

As a reminder, the final source files for this part of the tutorial are here.

Get Building eCommerce Applications now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.