jQuery Mobile Tutorial: How to Convert an Existing Website to a Mobile Website
Walk through the steps to revamp a website to make it mobile web friendly
July 19, 2012
RELATED: "Better Mobile Website Development Using the jQuery Mobile Library" and "Get Started Using jQuery Mobile for Mobile Web Development."
The increasing popularity of "smart" mobile devices such as smartphones and tablets has dramatically changed the structure and the presentation of websites. A business website must be designed so that it renders properly on a variety of mobile devices -- or risk losing customers and business opportunities. The jQuery Mobile framework is a popular technology for developing mobile applications, in large part because it's backed up by the jQuery framework and also because it provides the flexibility required to build mobile websites that look good on a variety of mobile devices. To give you a feel for using jQuery Mobile, in this article I'll walk through an example conversion of an existing website, HighOnCoding, which uses jQuery Mobile code to render the site on a mobile device. (For additional examples of using jQuery Mobile, see the articles listed in the Learning Path at the end of this article.)
Getting Started
When implementing a mobile website, you can either create a new project just for the mobile website, or you can add mobile functionality to an existing project. In this article, I'll use the latter approach. Before you follow along with my implementation example, download the jQuery mobile framework and then visit the website HighOnCoding.com on your mobile device. On HighOnCoding.com, you'll notice that although you can browse the website, it isn't mobile friendly. You continuously need to pinch zoom in and zoom out to interact with the website. In my sample project, I'll convert the existing website to be more mobile friendly.
Implementing HighOnCoding Mobile
The HighOnCoding mobile website will consist of a single HTML page, with each mobile web page represented by a special div element. Before diving into the implementation, make sure that you set up the references to the required JavaScript and Cascading Style Sheets (CSS) files as shown in Figure 1.
-
The home page of the HighOnCoding mobile website will display a list of categories from which the user can select. Each jQuery Mobile page is divided into a number of sections. The data-role="page" attribute represents the complete mobile page. The page section contains the header, content, and footer, as shown in Figure 2.
HighOnCoding
Figure 3 shows what this code looks like when it's rendered.
Figure 3: Basic template for the HighOnCoding mobile website
jQuery Mobile provides many different ways to display content. Since my goal is to render a list that users can use to scroll and select a category, I'll use a listview control to display the site's content. To do so, simply add the data-role attribute of listview to your content div, as shown in Figure 4, which will provide scrollable functionality like the table views on Android and iPhone devices.
HighOnCoding
The data is loaded into the content div by using an Ajax call at the document ready event, shown in the function in Figure 5.
$(document).ready(function () { $.getJSON('/mobile/getcategories', function (data) { for (i = 0; i <= data.length - 1; i++) { var li = $(""); var uniqueId = $(""); $(li).tap(function () { var hiddenElement = ($(this).find("hidden")); loadArticlesByCategory($(hiddenElement).val()); }); $(uniqueId).attr("value", data[i].Id);var a = $("").attr("href", "#articlesbycategory") .attr("data-transition", "slide").text(data[i].Title); $(li).append(a); $(li).append(uniqueId); $("#categories").append(li); } $("#categories").listview("refresh"); });
The call fetches the information from the database and returns a JSON string to the client. The Ajax call triggers the custom MobileController, which is responsible for the communication between the user interface and the back-end services. Figure 6 shows the on-screen result of the code in Figure 4 and Figure 5. Note that I've used data-theme="a", which creates a black gradient visual theme, as shown in Figure 6. You can either use a different theme or roll your own theme using jQuery Mobile's ThemeRoller.
Figure 6: Categories displayed in a listview control
The mobile website now displays the number of categories available but doesn't yet indicate how many articles per category exist. You can add this capability using a built-in feature of jQuery Mobile that adds count bubbles to the listview items. The following code example shows how a simple span tag can be used to represent the count bubbles with the help of the "ui-li-count" class.
$("").addClass("ui-li-count").text(data[i].NumberOfArticles).appendTo(li);
Figure 7 shows the result of this code.
Figure 7: Categories displaying number of articles in count bubbles
Implementing Article and Content Pages
jQuery Mobile provides several different methods for adding navigation to a mobile website. In my scenario, I'll use the slide navigation feature. Here's the code to add slide navigation:
$("").attr("href", "#articlesbycategory") .attr("data-transition", "slide").text(data[i].Title).appendTo(li);
When the user touches the category, this action sends the category ID to the service and fetches the related articles based on the category ID. The code in Figure 8 shows how these actions are accomplished.
$(li).tap(function () { var hiddenElement = ($(this).find("hidden")); loadArticlesByCategory($(hiddenElement).val()); });function loadArticlesByCategory(categoryId) { var params = new Object(); params.categoryId = categoryId; $.getJSON('/mobile/GetArticlesByCategory', params, function (data) { populateArticlesByCategory(data); }); }
In this code, the tap event is triggered by the selection of a category. The event passes the value of a hidden field to the loadArticlesByCategory function. The hidden field represents the selected categoryId. The loadArticlesByCategory function calls the GetArticlesByCategory action of the mobile controller, shown in Figure 9, passing in the selected categoryId as an object parameter.
public JsonResult GetArticlesByCategory(int categoryId) { var articlesViewModel = new List(); using(var entities = new HighOnCodingDbEntities()) { var articles = (from a in entities.Articles where a.CategoryID == categoryId select a).OrderByDescending(c => c.DateCreated).ToList(); foreach(var article in articles) { var articleViewModel = new ArticleViewModel(); articleViewModel.Id = article.ArticleID; articleViewModel.Title = article.Title; articlesViewModel.Add(articleViewModel); } } return Json(articlesViewModel,JsonR
Note that in my example, I implemented the data-access code directly into the controller, which isn't considered a good practice. You should always use a layer to separate your controller with the data access.
The GetArticlesByCategory action returns the article view model in a JSON serialized format, which is consumed by the populateArticlesByCategory function, as shown in Figure 10.
function populateArticlesByCategory(data) { $("#articlesByCategory").children().remove(); $.each(data, function (key, value) { var li = $("").append( $("").attr("href", "#articleDetails").text(value.Title) ).append( $("").attr("value", value.Id) ); $(li).tap(function () { var params = new Object(); params.articleId = $(this).find("hidden").val(); $.getJSON('/mobile/GetArticleById', params, function (data) { loadArticleDetails(data); }); }); $("#articlesByCategory").append(li); }); $("#articlesByCategory").listview("refresh"); }
The populateArticlesByCategory function uses a JSON response to construct a list item to display the articles in the selected category. A hidden field that contains the article's ID is also injected into the Document Object Model (DOM). This field will be used later to fetch the selected article. The tap event is registered with the list item, which calls the GetArticleById action of the mobile controller. Figure 11 shows the results of the code discussed in this section, displaying the article list when a category is selected.
Figure 11: Displaying articles in the selected category
Next I'll implement the article detail screen, which will display the article's content. Figure 12 shows the HTML for the article content page section.
HighOnCoding
Previously I attached the tap function to the list item; this triggers the loadArticleDetails function, shown in the following code
function loadArticleDetails(data) { $("#articleContent").html(data.Description); }
Figure 13 shows the article content page in action.
Figure 13: The article content page
At this point, users can browse the article categories and view the contents of the selected article, but they can't comment on the article. In the next section, I'll add functionality that lets users add comments to the HighOnCoding mobile website.
Implementing User Comments
Comments allow the website to be more interactive and informative. The HighOnCoding mobile website lets the user add comments via a comment button at the end of each article. The button opens the comment window in a new dialog box, which allows the user to submit a comment. The button is placed in the footer of the article details section, as follows:
Add Comment
The anchor tag opens the addComment section in a new dialog box. The addComment section, shown in Figure 14, allows the user to submit a comment.
HighOnCodingNameSubjectCommentSubmit
As you can see, the code isn't complicated. I used the text input element for the name and subject and the textarea for the comment. Figure 15 shows the comment dialog box in action.
Figure 15: Comment dialog box
The submit button is responsible for gathering all the required values and constructing an object that will be sent back to the server to persist the comment in the database. Figure 16 shows the code for the submit button click event.
$("#submit").click(function () { var commentRequest = { ArticleId: $("#articleId").val(), Name: $("#name").val(), Subject: $("#subject").val(), Comment: $("#comment").val() }; $.ajax( { url: "/mobile/AddComment", type: "POST", dataType: "json", data: JSON.stringify(commentRequest), contentType: "application/json; charset=utf-8", success: function (response) { } } ); });
The AddComment action of MobileController takes the CommentRequest object as the parameter. One of the new features in ASP.NET MVC 3 is the automatic mapping of JavaScript parameters to C# classes. Once you get hold of the CommentRequest object with all the information, you can safely store it in a persisted medium.
A Clear Path to the Mobile Web
Companies are putting a lot of effort into modifying their existing websites to be mobile friendly. However, converting an existing website to a mobile website need not be a daunting process. We'll continue the mobile web discussion in "Working with CSS Media Queries and Media Types, Part 1," which will have useful information tips for responsive design in your web apps.
About the Author
You May Also Like