Install and Configure Rhodes Application in Window x64 for cross device

If you’re running Windows, ensure that Java Development Kit is installed. The Sun JDK for Windows is available here.

Download the latest RhoStudio for Windows and run the download file to install RhoStudio.

If you use Symantec Antivirus it can warn about “Suspicious.MLApp” security risk in rubyw.exe file during installation. It is known false positive in Symantec antivirus.
Ignore this warning.
Use Motorola RhoStudio 64-bit to run RhoStudio with x64 JDK.
Use Motorola RhoStudio 32-bit to run RhoStudio with x86 JDK.

Setting path to the Java Development Kit

In RhoStudio Preferences, open RhoMobile and check that the path is set to your JDK installation.

Generating a Rhodes Application

You also can use RhoStudio to generate a RhoConnect application and source adapter. You can see an example in the RhoConnect tutorial.

In RhoStudio, select File->New->Project…

The New Project window opens. Select the RhoMobile application wizard and click the Next button.

Enter the name for your Rhodes application in Project name; in this case, “storemanager”. You may specify a specific folder for your destination where your project is stored, by default, the destination is your RhoStudio workspace folder. Uncheck the RhoElements checkbox if this is to be a strictly Rhodes application. Then press the Finish button.

After pressing the Finish button, you’ll see the Rhodes app generator script output in the output console (Rhomobile build console).

Generating a Rhodes Model

Rhodes applications support a Model-View-Controller (MVC) pattern.  To start our application, we will generate a Model. To generate a Rhodes model and create the associated Controller and View templates, right-click on the application project in the Project Explorer and select New->Rhodes model.

In the Model Information window, enter the name for your model: in this case, Product. Also enter the Model attributes as a string with no spaces and each attribute separated by a comma: in this case, name,brand,price,quantity,sku. (Whitespaces at the field name beginning and end will be trimmed and whitespaces in the middle of the field name will be replaced with an underscore character.)

Click the Finish button to create the model.

After pressing the Finish button, you’ll see the Rhodes model generator script output in the output console (Rhodes build log console).

You should now see a ‘Product’ folder below the ‘app’ folder in your storemanager application. These files constitute the Model, Views and Controller file for the Product Model we just created. The files are organized as follows:

  • product.rb –> This is the Model file which contains the Model definition. Since we are using the default PropertyBag definition, we don’t need to modify this file any further.
  • product_controller.rb –> This file contains the business logic which relates to our Model.
  • *.erb –> The .erb files are the html view template files. We’ll be modifying them in the next section.

Editing Rhodes Views

You may edit the generated ERB files to customize the HTML as you see fit. Typically you will provide links to the model index page from the home screen. In order to accomplish this, a modification needs to be made to the default view for the application, called index.erb. Below is the content for the StoreManager app’s generated top level index.erb file (app/index.erb). Open this file for editing.


<% if SyncEngine::logged_in > 0 %>



<% else %>
<% end %>

To provide a link to the Product model’s index page and templates, replace the list item with the title ‘Add link here’ with the following:

    <a href="Product">
        <span class="title">Products</span>

This change now means that when the index.erb view is displayed (the default view when the app starts), you will see a UI element called “Products” that will take you to the controller for the “Product” Model definition. Because no specific action is provided, the controller will default to displaying the Model’s index page, in this case the Product model’s index page. All further functionality in the app is carried out by the default scaffolding of the generated controller and view files. These generated files provide basic CRUD (Create, Read, Update, Delete) functionality for your Model.

You can edit the top level app page or any of the other view templates with any HTML you wish. We don’t attempt to teach you HTML or Ruby here, but there are many good external references for both topics.

Managing Your Build Configuration

The build.yml file for your application manages your Rhodes build time configuration. Double click on ‘build.yml’ item in your project tree to open the build.yml editor. In the editor you’ll see two tabs: Rhobuild setting for the WYSIWIG editor, and build.yml for the text editor.

Rhobuild setting WYSIWIG editor:

build.yml text editor:

You will have default values for your application name, log file (the log file will be located in your application folder after you run your application), and the path to the Rhodes gem. You can use the WYSIWIG editor to change this. For example, you might want to point to a different RHodes gem if you have more than one Rhodes gem installed.

You can add capabilities to your application, such as camera and vibrate, by pressing the Capabilities: Add button, selecting the capabilities from the popup window, and clicking the Ok button.

The selected application capabilities will appear in the Capabilities: text field in the WISIWIG editor.

Building and Running Your Application

To start the build process, create a Run Configuration: select your project in the Project Explorer, and select Run->Run Configurations… from the menu. The Run Configurations window appears.

To create a new build configuration for your application, select Rhodes Application. Then either right-click on Rhodes Application or click the New button. A new configuration appears under Rhodes Application.

Building and Running with RhoSimulator

You can run your project in RhoSimulator, a simulator type available only in RhoStudio. RhoSimulator allows you to build and run your project on the platform of your choice without having to install the SDK for that platform. Instead, RhoSImulator will mimic the platform. RhoSimulator builds and runs your application quickly, making it useful for testing and debugging.

Once you have done your application development and debugging, you will need to install the SDK to create a build for that device. Or you can upload your project to RhoHub, and use RhoHub to create the build for your device.

To run RhoSimulator for the iPhone platform, select your project from the Project Explorer (in this case, we use the storemanager project created earlier). Then select Run –> Run Configurations from the main menu. The Run Configurations window appears.

In the Run Configurations window, select RhoSimulator for the Simulator type, and select your desired platform type. For example, if you select iPhone, RhoSimulator will mimic an iPhone. The calls to the system will return as though the application was running on an actual iPhone.

Click Run to start the simulator.

In the storemanager example, we can add a couple of products. Click the Products link, then click New, enter the product attributes, and click Create.

Using the Web Inspector

The RhoSimulator also brings up a Webkit Inspector window, allowing you to inspect the web interface for your application.

For example, you can see the web code for the listview. Here is the listview of the products for the storemanager example. You can see the link for the iPhone URL, and you could change the border color and thickness for the iPhone product (changing from 1px to 3px and solid #CCC to #111 would give the iPhone link a thicker, darker border).

Using the Debugger

You can use the RhoStudio debugger to debug the Ruby code in your RHodes or Rhoconnect application.

Debugging a Rhodes Application

To run the RhoSimulator debugger for the iPhone platform, select your Rhodes project from the Project Explorer (in this case, we use the storemanager project created earlier). Then select Run –> Debug Configurations from the main menu. The Debug Configurations window appears.

Click Debug to start the debugger.

You will again get a RhoSimulator showing your device, and the Web Inspector window. And you get a Debug view in your workspace.

To debug your Ruby code in your Rhodes application, click the RhoStudio tab in your workspace, then open the Ruby file in your Rhodes application that you wish to debug.

Now click the Debug tab. You will see the Ruby file opened in the debugger.

Debugging a RhoConnect Application

To run the debugger for RhoConnect, select your RhoConnect project from the Project Explorer. Then select Run –> Debug Configurations from the main menu. The Debug Configurations window appears.

Click Debug to start the debugger.

You will see your RhoConnect project in the debugger; there will be a console window with redis server information messages. (You will not get a RhoSimulator or a Web Inspector, as you do with the Rhodes debugger.)

To debug your Ruby code in your RhoConnect application, you do the same as for a Rhodes application: click the RhoStudio tab in your workspace, then open the Ruby file in your RhoConnect project that you wish to debug.

Setting a Breakpoint

You can perform operations such as setting a breakpoint: double-click in the left margin at the line of code where you want the breakpoint.

For example, in the storemanager code, there is a rendering section in product_controller.rb.

# GET /Product
def index
  @products = Product.find(:all)
  render :back => '/app'

You can set a breakpoint on the line render :back => '/app', then you can go to the RhoSimulator and click on Product. The simulator will stop at the point of rendering.

If you set a breakpoint on a function definition string (the first line of a function definition), as in the following line of Ruby code, that breakpoint will always be disabled. You should not set breakpoints there.
def some_method(value='default', arr=[])

Inspecting the Variables

You can also inspect the variables. When you click “Products” In the debugger simulator, and you have a breakpoint as set earlier in the product_controller.rb on the rendering line, the application will pause just before the rendering of the product listing page. You can then inspect the variables in the variable window. The storemanager example shows that at this point int he app, the local database has been read, showing that a couple of products have been created (an iPhone and an iPhone4S).

Debugger Support for Extensions

The RhoStudio debugger supports extensions, but only pure Ruby extensions or the Ruby part of a native extension.

Debugging Ruby Framework Code

The debugger supports debugging Ruby framework code. With an older project, you may need to recreate the project in RhoStudio in order to enable the debugger. A good way to do this is as follows.

  1. Delete the project in the Project Explorer view without deleting the project content.
  2. Create a new project by creating from existing sources in the RhoMobile application wizard.
  3. Use your old project content as the existing source.

Importing a Rhodes Project from a non-RhoStudio Source

You can have a Rhodes project that you wish to import into RhoStudio. For example, you might have created a project using RhoHub and you have a local repository of that project on your computer). Or you might want to import the sample projects that came with the RhoStudio installer. The import process is similar to importing external projects with standard Eclipse.

Select File –> New –> Project…

From the New Project window, select Rhomobile –> Rhoconnect application or Rhomobile –> Rhodes application. THen click the Next button.

From the Rhodes (or Rhoconnect) application generator wizard window, click the “Create application from existing sources” checkbox.

Click the Browse button, then navigate to and select the folder containing your project. The Project name will change to the name of your project folder.

Click the Finish button. Your project will appear in the Project Explorer.

Creating a Device Build in RhoStudio

Once you have developed your application using the RhoSimulator and debugger, you will need to create a device build of your application. To do this with RhoStudio, you can do this by installing SDKs.

To create a device build with RhoStudio, you need to do the following:

  • Install the SDK for your application’s platform.
  • Set RhoStudio Preferences to that platform’s SDK.
  • In Run Configurations, set to that device, then do the device build and run.
You can do the device build with RhoHub if you wish to avoid installing the SDKs on your computer. To do your device build on RhoHub, upload your application into RhoHub, then use RhoHub to create the device build. Instructions for using RhoHub are in the Rhohub tutorial.

Installing the SDK

On Macintosh computers, once you have installed Xcode, RhoStudio will know the location of the iOS SDK. You do not set any locations.

On other platforms, such as Android, you need to install the SDK, and then set RhoStudio Preferences for that platform’s SDK. For example, on an Android device, you must download and install:

Set RhoStudio SDK Preferences

Once you have the SDK for your platform installed, set RhoStudio Preferences for that SDK. For example, to do Android device builds:

  1. In the Preferences window, open the Rhomobile item and select Android.
  2. Click the Browse button and navigate to the locations where you installed your Android SDK and NDK.

Set Run Configurations to the Device Build and Run

To start the device build process, create a Run Configuration: select your project in the Project Explorer, and select Run->Run Configurations… from the menu. The Run Configurations window appears. Set Run Configurations as follows:

  • Set the Platform to Android.
  • Set the Simulator type to either device to run on the device, or simulator to run on the simulator provided with the Android SDK.
  • If you set the Simulator type to simulator, set the Platform version number and set the AVD name for Android.

Press the Run button to build and run your application. The build output will appear in the Rhodes build output console. The application log will be available in the Rhodes application output console, and will be written into your application folder.

For complete instructions on setting up the SDKs in RhoStudio for each platform, refer to the Build instructions for Rhodes.

Editing the SDK Locations in rhobuild.yml

Use RhoStudio preferences to edit the rhobuild.yml file, which manages the location(s) of the platform SDKs/JDKs that are used to build your Rhodes application. The rhobuild.yml file is located in the Rhodes gem folder (or, if you copied Rhodes from git, in the Rhodes source code folder).

Using Intellisense for Autocompletion

IntelliSense is Microsoft’s implementation of autocompletion, best known for its use in the Microsoft Visual Studio integrated development environment. In addition to completing the symbol names the programmer is typing, IntelliSense serves as documentation and disambiguation for variable names, functions and methods using reflection.

The RhoStudio DLTK implementation supports aspects of Intellisense, such as Ruby keyword completion and block argument name completion. You can use Intellisense in RhoStudio to autocomplete your Ruby code by setting the cursor at a location in your code and pressing Ctrl+Space.

For example, to complete a Ruby keyword beginning with “re”, perform these steps.

  1. Enter “re”.
  2. Press Ctrl+Space. The completion list includes “rescue” and “return”.

Checking Progress and Canceling an Operation

You can check the progress of an operation in RhoStudio, and cancel it if you wish. Open the Progress view to see the progress bar on the left, and click the red square on the right to cancel the operation.

The following RhoStudio operations can have their progress checked and be canceled from the Progress view.

  • Main menu: RhoMobile –> Production build
  • Main menu: Project –> Clean…
  • RhoMobile Application in Project Explorer: Run Configurations, RhoMobile Application
  • RhoMobile Application in Project Explorer: Run Configurations, RhoMobile Application Test
  • RhoConnect Application in Project Explorer: Run Configurations, RhoConnect Application

You can also check progress and perform a cancel for the following operations on existing applications.

  • Create a new project, and then select RhoMobile->RhoMobile application from the New Project window.
  • Create a new project, and then select RhoMobile->RhoConnect application from the New Project window.
  • Select a RhoMobile application in the Project Explorer, and create a New->RhoMobile model.
  • Select a RhoMobile application in the Project Explorer, and create a New->RhoMobile extension.
  • Select a RhoConnect application in the Project Explorer, and create a New->RhoConnect source adapter.

Creating a Production Build in RhoStudio

To create a production build for your application, perform these steps.

  1. Select your application in the Project Explorer.
  2. Select RhoMobile->Production Build from the main menu.
  3. From the Select platform pop-up box, select the platform to which you wish to build and click “Ok”.

Reference :

PhoneGap for Android Native App

PhoneGap is an open source framework for quickly building cross-platform mobile apps using HTML5, Javascript and CSS.

Building applications for each device–iPhone, Android, Windows Mobile and more–requires different frameworks and languages. PhoneGap solves this by using standards-based web technologies to bridge web applications and mobile devices. Since PhoneGap apps are standards compliant, they’re future-proofed to work with browsers as they evolve.

Why PhoneGap?
Mobile app is next regeneration of development work. There are several Mobile OS currently available in the world competition market; Android, IOS, Bada, Blackberry, Symbian, WebOS and Window Phone.

To build an application each platform is required an adequate knowledge and skill for specific platform.
For example, if you want to build application for Android Platform you might have enough knowledge skill on Java. Also for IOS you might need a strong understanding on Objective-C and Coca framwork to applications for IOS platform…etc.

With PhoneGap does not require extra skill that you have already learned since Bachelor degree, they are HTML, Javascript and CSS. It can compile to a native application of your choices of platform.

The practice here I will show about developing native app in Android with Eclipse.
Download PhoneGap here :

After download Eclipse and install Android SDK.
1.) Prepare the file structure as the following image.

2.) Write some few code in the main activity as below:

Here is a result:

Finally it is done. It is simple, right?
You can try yourself for IOS or Window Phone and other platform.

Near field communication

Near field communication (NFC) is a set of standards for smartphones and similar devices to establish radio communication with each other by touching them together or bringing them into close proximity, usually no more than a few centimetres. Present and anticipated applications include contactless transactions, data exchange, and simplified setup of more complex communications such as Wi-Fi. Communication is also possible between an NFC device and an unpowered NFC chip, called a “tag”.

NFC standards cover communications protocols and data exchange formats, and are based on existing radio-frequency identification (RFID) standards including ISO/IEC 14443 and FeliCa. The standards include ISO/IEC 18092 and those defined by the NFC Forum, which was founded in 2004 by NokiaPhilips and Sony, and now has more than 160 members. The Forum also promotes NFC and certifies device compliance.


N-Mark Logo for certified devices

NFC builds upon Radio-frequency identification (RFID) systems by allowing two-way communication between endpoints, where earlier systems such ascontactless smart cards were one-way only. Since unpowered NFC “tags” can also be read by NFC devices, it is also capable of replacing earlier one-way applications.


NFC devices can be used in contactless payment systems, similar to those currently used in credit cards and electronic ticket smartcards, and allow mobile payment to replace or supplement these systems. For example, Google Wallet allows consumers to store credit card and store loyalty card information in a virtual wallet and then use an NFC-enabled device at terminals that also accept MasterCard PayPass transactions. GermanyAustriaLatvia[citation needed]and Italy have trialled NFC ticketing systems for public transport. China is using it all over the country in public bus transport[citation needed] and India is implementing NFC based transactions in box offices for ticketing purposes.

Uses of NFC include:

  • Matching encrypted security code and transporting access key;
  • Due to short transmission range, NFC-based transactions are possibly secure;
  • Instant payments and coupon delivery using your handset, as we do with your credit card or debit card;
  • Marketing and exchange of information such as schedules, maps, business card and coupon delivery using NFC Marketing tags;
  • Pay for items just by waving your phone over the NFC capable devices
  • Transferring images, posters for displaying and printing
  • Social media e.g Like on Facebook, Follow on Twitter via NFC smart stickers in retail stores

Bluetooth and WiFi connections

NFC offers a low-speed connection with extremely simple setup, and could be used to bootstrap more capable wireless connections. It could, for example, replace the pairing step of establishing Bluetooth connections or the configuration of Wi-Fi networks.

Social networking

NFC can be used in social networking situations, such as sharing contacts, photos, videos or files, and entering multiplayer mobile games.

Identity documents

The NFC Forum promotes the potential for NFC-enabled devices to act as electronic identity documents and keycards. As NFC has a short range and supports encryption, it may be more suitable than earlier, less private RFID systems.

Reference :

Building a Website with PHP, MySQL and jQuery Mobile, Part 2

This is the second part of a two-part tutorial, in which we use PHP, MySQL and jQuery mobile to build a simple computer web store. In the previous part we created the models and the controllers, and this time we will be writing our views.

jQuery mobile

First, lets say a few words about the library we will be using. jQuery mobile is a user interface library that sits on top of jQuery and provides support for a wide array of devices in the form of ready to use widgets and a touch-friendly development environment. It is still in beta, but upgrading to the official 1.0 release will be as simple as swapping a CDN URL.

The library is built around progressive enhancement. You, as the developer, only need to concern yourself with outputting the correct HTML, and the library will take care of the rest. jQuery mobile makes use of the HTML5 data- attributes and by adding them, you instruct the library how it should render your markup.

In this tutorial we will be using some of the interface components that this library gives us – listsheaderand footer bars and buttons, all of which are defined using the data-role attributes, which you will see in use in the next section.

Rendering Views

The views are PHP files, or templates, that generate HTML code. They are printed by the controllers using the render() helper function. We have 7 views in use for this website – _category.php_product.php,_header.php_footer.phpcategory.phphome.php and error.php, which are discussed later on. First, here is render() function:


01 /* These are helper functions */
03 function render($template,$vars array()){
05     // This function takes the name of a template and
06     // a list of variables, and renders it.
08     // This will create variables from the array:
09     extract($vars);
11     // It can also take an array of objects
12     // instead of a template name.
13     if(is_array($template)){
15         // If an array was passed, it will loop
16         // through it, and include a partial view
17         foreach($template as $k){
19             // This will create a local variable
20             // with the name of the object's class
22             $cl strtolower(get_class($k));
23             $$cl $k;
25             include "views/_$cl.php";
26         }
28     }
29     else {
30         include "views/$template.php";
31     }
32 }

The first argument of this function is the name of the template file in the views/ folder (without the .phpextension). The next is an array with arguments. These are extracted and form real variables which you can use in your template.

There is one more way this function can be called – instead of a template name, you can pass an array with objects. If you recall from last time, this is what is returned by using the find() method. So basically if you pass the result of Category::find() to render, the function will loop through the array, get the class names of the objects inside it, and automatically include the _category.php template for each one. Some frameworks (Rails for example) call these partials.

Computer Store with PHP, MySQL and jQuery Mobile

Computer Store with PHP, MySQL and jQuery Mobile

The Views

Lets start off with the first view – the header. You can see that this template is simply the top part of a regular HTML5 page with interleaved PHP code. This view is used in home.php and category.php to promote code reuse.


01 <!DOCTYPE html>
02 <html>
03     <head>
04     <title><?php echo formatTitle($title)?></title>
06     <meta name="viewport" content="width=device-width, initial-scale=1" />
08     <link rel="stylesheet" href="" />
09     <link rel="stylesheet" href="assets/css/styles.css" />
10     <script type="text/javascript" src=""></script>
11     <script type="text/javascript" src=""></script>
12 </head>
13 <body>
15 <div data-role="page">
17     <div data-role="header" data-theme="b">
18         <a href="./" data-icon="home" data-iconpos="notext" data-transition="fade">Home</a>
19         <h1><?php echo $title?></h1>
20     </div>
22     <div data-role="content">

In the head section we include jQuery and jQuery mobile from jQuery’s CDN, and two stylesheets. The body section is where it gets interesting. We define a div with the data-role=”page” attribute. This, along with the data-role=”content” div, are the two elements required by the library to be present on every page.

The data-role=”header” div is transformed into a header bar. The data-theme attribute chooses one of the 5 standard themes. Inside it, we have a link that is assigned a home icon, and has its text hidden. jQuery Mobile comes with a set of icons you can choose from.

The closing tags (and the footer bar) reside in the _footer.php view:


1     </div>
3     <div data-role="footer" id="pageFooter">
4         <h4><?php echo $GLOBALS['defaultFooter']?></h4>
5     </div>
6 </div>
8 </body>
9 </html>

Nothing too fancy here. We only have a div with the data-role=”footer” attribute, and inside it we print the globally accessible $defaultFooter variable, defined in includes/config.php.

Neither of the above views are printed directly by our controllers. They are instead used bycategory.php and home.php:


01 <?php render('_header',array('title'=>$title))?>
03 <p>Welcome! This is a demo for a ...</p>
04 <p>Remember to try browsing this ...</p>
06 <ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="b">
07     <li data-role="list-divider">Choose a product category</li>
08     <?php render($content) ?>
09 </ul>
11 <?php render('_footer')?>

If you may recall, the home view was rendered in the home controller. There we passed an array with all the categories, which is available here as $content. So what this view does, is to print the header, and footer, define a jQuery mobile listview (using the data-role attribute), and generate the markup of the categories passed by the controller, using this template (used implicitly by render()):


1 <li <?php echo ($active == $category->id ? 'data-theme="a"' '') ?>>
2 <a href="?category=<?php echo $category->id?>" data-transition="fade">
3     <?php echo $category->name ?>
4     <span class="ui-li-count"><?php echo $category->contains?></span></a>
5 </li>

Notice that we have a $category PHP variable that points to the actual object this view is being generated for. This is done in lines 24/25 of the render function. When the user clicks one of the links generated by the above fragment, he will be taken to the /?category=someid url, which will show thecategory.php view, given below.

01 <?php render('_header',array('title'=>$title))?>
03 <div class="rightColumn">
04     <ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="c">
05         <?php render($products) ?>
06     </ul>
07 </div>
09 <div class="leftColumn">
10     <ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="b">
11         <li data-role="list-divider">Categories</li>
12         <?php render($categories,array('active'=>$_GET['category'])) ?>
13     </ul>
14 </div>
16 <?php render('_footer')?>

This file also uses the header, footer and _category views, but it also presents a column with products (passed by the category controller). The products are rendered using the _product.php partial:

1 <li class="product">
2     <img src="assets/img/<?php echo $product->id ?>.jpg" alt="<?php echo $product->name ?>" />
3     <?php echo $product->name ?> <i><?php echo $product->manufacturer?></i>
4     <b>$<?php echo $product->price?></b>
5 </li>

As we have an image as the first child of the li elements, it is automatically displayed as an 80px thumbnail by jQuery mobile.

One of the advantages to using the interface components defined in the library is that they are automatically scaled to the width of the device. But what about the columns we defined above? We will need to style them ourselves with some CSS3 magic:


01 media all and (min-width650px){
03     .rightColumn{
04         width:56%;
05         float:right;
06         margin-left:4%;
07     }
09     .leftColumn{
10         width:40%;
11         float:left;
12     }
14 }
16 .product i{
17     display:block;
18     font-size:0.8em;
19     font-weight:normal;
20     font-style:normal;
21 }
23 .product img{
24     margin:10px;
25 }
27 .product b{
28     positionabsolute;
29     right15px;
30     top15px;
31     font-size0.9em;
32 }
34 .product{
35     height80px;
36 }

Using a media query, we tell the browser that if the view area is wider than 650px, it should display the columns side by side. If it is not (or if the browser does not support media queries) they will be displayed one on top of the other, the regular “block” behavior.

Reference :

Building a Website with PHP, MySQL and jQuery Mobile, Part 1

In this two-part tutorial, we will be building a simple website with PHP and MySQL, using the Model-View-Controller (MVC) pattern. Finally, with the help of the jQuery Mobile framework, we will turn it into a touch-friendly mobile website, that works on any device and screen size.

In this first part, we concentrate on the backend, discussing the database and MVC organization. In part two, we are writing the views and integrating jQuery Mobile.

The File Structure

As we will be implementing the MVC pattern (in effect writing a simple micro-framework), it is natural to split our site structure into different folders for the models, views and controllers. Don’t let the number of files scare you – although we are using a lot of files, the code is concise and easy to follow.

The Directory Structure

The Directory Structure

The Database Schema

Our simple application operates with two types of resources – categories and products. These are given their own tables – jqm_categories, and jqm_products. Each product has a category field, which assigns it to a category.

jqm_categories Table Structure

jqm_categories Table Structure

The categories table has an ID field, a name and a contains column, which shows how many products there are in each category.

jqm_products Table Structure

jqm_products Table Structure

The product table has a namemanufacturerprice and a category field. The latter holds the ID of the category the product is added to.

You can find the SQL code to create these tables in tables.sql in the download archive. Execute it in the SQL tab of phpMyAdmin to have a working copy of this database. Remember to also fill in your MySQL login details in config.php.

The Models

The models in our application will handle the communication with the database. We have two types of resources in our application – products and categories. The models will expose an easy to use method – find() which will query the database behind the scenes and return an array with objects.

Before starting work on the models, we will need to establish a database connection. I am using the PHP PDO class, which means that it would be easy to use a different database than MySQL, if you need to.


02     This file creates a new MySQL connection using the PDO class.
03     The login details are taken from includes/config.php.
04 */
06 try {
07     $db new PDO(
08         "mysql:host=$db_host;dbname=$db_name;charset=UTF-8",
09         $db_user,
10         $db_pass
11     );
13     $db->query("SET NAMES 'utf8'");
14     $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
15 }
16 catch(PDOException $e) {
17     error_log($e->getMessage());
18     die("A database error was encountered");
19 }

This will put the $db connection object in the global scope, which we will use in our models. You can see them below.


01 class Category{
03     /*
04         The find static method selects categories
05         from the database and returns them as
06         an array of Category objects.
07     */
09     public static function find($arr array()){
10         global $db;
12         if(empty($arr)){
13             $st $db->prepare("SELECT * FROM jqm_categories");
14         }
15         else if($arr['id']){
16             $st $db->prepare("SELECT * FROM jqm_categories WHERE id=:id");
17         }
18         else{
19             throw new Exception("Unsupported property!");
20         }
22                 // This will execute the query, binding the $arr values as query parameters
23         $st->execute($arr);
25         // Returns an array of Category objects:
26         return $st->fetchAll(PDO::FETCH_CLASS, "Category");
27     }
28 }

Both models are simple class definitions with a single static method – find(). In the fragment above, this method takes an optional array as a parameter and executes different queries as prepared statements.

In the return declaration, we are using the fetchAll method passing it the PDO::FETCH_CLASS constant. What this does, is to loop though all the result rows, and create a new object of the Category class. The columns of each row will be added as public properties to the object.

This is also the case with the Product model:


01 class Product{
03     // The find static method returns an array
04     // with Product objects from the database.
06     public static function find($arr){
07         global $db;
09         if($arr['id']){
10             $st $db->prepare("SELECT * FROM jqm_products WHERE id=:id");
11         }
12         else if($arr['category']){
13             $st $db->prepare("SELECT * FROM jqm_products WHERE category = :category");
14         }
15         else{
16             throw new Exception("Unsupported property!");
17         }
19         $st->execute($arr);
21         return $st->fetchAll(PDO::FETCH_CLASS, "Product");
22     }
23 }

The return values of both find methods are arrays with instances of the class. We could possibly return an array of generic objects (or an array of arrays) in the find method, but creating specific instances will allow us to automatically style each object using the appropriate template in the views folder (the ones that start with an underscore). We will talk again about this in the next part of the tutorial.

There, now that we have our two models, lets move on with the controllers.

Computer Store with PHP, MySQL and jQuery Mobile

Computer Store with PHP, MySQL and jQuery Mobile

The controllers

The controllers use the find() methods of the models to fetch data, and render the appropriate views. We have two controllers in our application – one for the home page, and another one for the category pages.


01 /* This controller renders the home page */
03 class HomeController{
04     public function handleRequest(){
06         // Select all the categories:
07         $content = Category::find();
09         render('home',array(
10             'title'     => 'Welcome to our computer store',
11             'content'   => $content
12         ));
13     }
14 }

Each controller defines a handleRequest() method. This method is called when a specific URL is visited. We will return to this in a second, when we discuss index.php.

In the case with the HomeControllerhandleRequest() just selects all the categories using the model’s find() method, and renders the home view (includes/views/home.php) using our render helper function (includes/helpers.php), passing a title and the selected categories. Things are a bit more complex inCategoryController:


01 /* This controller renders the category pages */
03 class CategoryController{
04     public function handleRequest(){
05         $cat = Category::find(array('id'=>$_GET['category']));
07         if(empty($cat)){
08             throw new Exception("There is no such category!");
09         }
11         // Fetch all the categories:
12         $categories = Category::find();
14         // Fetch all the products in this category:
15         $products = Product::find(array('category'=>$_GET['category']));
17         // $categories and $products are both arrays with objects
19         render('category',array(
20             'title'         => 'Browsing '.$cat[0]->name,
21             'categories'    => $categories,
22             'products'      => $products
23         ));
24     }
25 }

The first thing this controller does, is to select the category by id (it is passed as part of the URL). If everything goes to plan, it fetches a list of categories, and a list of products associated with the current one. Finally, the category view is rendered.

Now lets see how all of these work together, by inspecting index.php:


01 /*
02     This is the index file of our simple website.
03     It routes requests to the appropriate controllers
04 */
06 require_once "includes/main.php";
08 try {
10     if($_GET['category']){
11         $c new CategoryController();
12     }
13     else if(empty($_GET)){
14         $c new HomeController();
15     }
16     else throw new Exception('Wrong page!');
18     $c->handleRequest();
19 }
20 catch(Exception $e) {
21     // Display the error page using the "render()" helper function:
22     render('error',array('message'=>$e->getMessage()));
23 }

This is the first file that is called on a new request. Depending on the $_GET parameters, it creates a new controller object and executes its handleRequest() method. If something goes wrong anywhere in the application, an exception will be generated which will find its way to the catch clause, and then in the error template.

One more thing that is worth noting, is the very first line of this file, where we require main.php. You can see it below:


01 /*
02     This is the main include file.
03     It is only used in index.php and keeps it much cleaner.
04 */
06 require_once "includes/config.php";
07 require_once "includes/connect.php";
08 require_once "includes/helpers.php";
09 require_once "includes/models/product.model.php";
10 require_once "includes/models/category.model.php";
11 require_once "includes/controllers/home.controller.php";
12 require_once "includes/controllers/category.controller.php";
14 // This will allow the browser to cache the pages of the store.
16 header('Cache-Control: max-age=3600, public');
17 header('Pragma: cache');
18 header("Last-Modified: ".gmdate("D, d M Y H:i:s",time())." GMT");
19 header("Expires: ".gmdate("D, d M Y H:i:s",time()+3600)." GMT");

This file holds the require_once declarations for all the models, controllers and helper files. It also defines a few headers to enable caching in the browser (PHP disables caching by default), which speeds up the performance of the jQuery mobile framework.

Continue to Part 2

With this the first part of the tutorial is complete! Continue to part 2, where we will be writing the views and incorporate jQuery Mobile. Feel free to share your thoughts and suggestions in the comment section below.

Reference :

Mobile enabled web apps with ASP.NET MVC 3 and jQuery Mobile

In my previous blog posts, I have demonstrated a simple web app using ASP.NET MVC 3 and EF Code First. In this post, I will be focus on making this application for mobile devices. A single web site will be used for both mobile browsers and desktop browsers. If users are accessing the web app from mobile browsers, users will be redirect to mobile specific pages and will get normal pages if users are accessing from desktop browsers. In this demo app, the mobile specific pages are maintained in an ASP.NET MVC Area named Mobile and mobile users will be redirect to MVC Area Mobile.

Let’s add a new area named Mobile to the ASP.NET MVC app. For adding Area, right click the ASP.NET MVC project and  select Area from Add option. Our mobile specific pages using jQuery Mobile will be maintained in the Mobile Area.


Continue reading

How To: Add Mobile Pages to Your ASP.NET Web Forms / MVC Application

Applies To

  • ASP.NET Web Forms version 4.0
  • ASP.NET MVC version 3.0


This How To describes various ways to serve pages optimized for mobile devices from your ASP.NET Web Forms / MVC application, and suggests architectural and design issues to consider when targeting a broad range of devices. This document also explains why the ASP.NET Mobile Controls from ASP.NET 2.0 to 3.5 are now obsolete, and discusses some modern alternatives.


  • Overview
  • Architectural options
  • Browser and device detection
  • How ASP.NET Web Forms applications can present mobile-specific pages
  • How ASP.NET MVC applications can present mobile-specific pages
  • Additional resources

For downloadable code samples demonstrating this white paper’s techniques for both ASP.NET Web Forms and MVC, see


Continue reading