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:
html5resetcss - http://code.google.com/p/html5resetcss/downloads/list
jQuery 1.4.2 - http://jquery.com
Taffy DB 1.7.2 - http://taffydb.com
JSON2 - http://www.json.org
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:
The store view, which displays a list of product categories in the store.
The category view, which displays a list of products in a category.
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.
Step 8: Style the Links and Buttons
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.