Navigation: Developer Force | Salesforce Mobile Services | Extending Force.com to Mobile

Banner.png

Extending the Force.com Warehouse App to Mobile

by Don Robins

No matter how senior or experienced you may be as a developer, setting up new development environments, learning new coding patterns and languages, and designing and implementing new user experiences can be a challenge. And with so many options for devices and approaches like hybrid versus native available with mobile integration and the Salesforce platform, coming up to speed can seem a bit daunting for someone who's never done mobile development before. Don't worry, help is here. With a firm understanding of the fundamentals, you will be building a new class of enterprise mobile apps that integrate with Force.com in short order.

Considering the Options

There are three primary platform options for mobile development, and the approach you choose will ultimately affect the design of your application. The options include Native (iOS, Android, Windows Phone, Blackberry, etc.), HTML5, (usually augmented with JavaScript and CSS,) and Hybrid, (combining HTML5 running in a native shell executable on a target native platform to access device level functionality such as cameras, the device accelerometer or contacts.) Understanding Your Mobile Application Development Options provides an excellent overview.

While this article focuses on just one of these options, HTML5, it’s important to understand these options and choose the approach that’s right for you. However, the one inescapable point is that native adds complexity, thus raising the learning curve. For Android, this goes beyond selecting from multiple devices and form factors to target your development effort. It also requires targeting and selecting from multiple versions of Java, various IDEs, numerous SDKs, differing versions of the Android Development Tools and even the Android OS. iOS is far more homogeneous, and hence less complex regarding choice. But while it's true that the Apple development tools and the XCode IDE have evolved significantly over the last few years providing a much better development experience, you still have to learn the intricacies of Objective-C, Cocoa Touch and the Xcode development environment.

By leveraging Visualforce, HTML5 and JavaScript, many of the complexities of native development fall away, allowing for a faster ramp-up as long as you're already at least a little familiar with and have a foundation level understanding of HTML and JavaScript.

Building A Mobile Warehouse

We're going to build a very simple mobile app to display information from the Warehouse application that is built out with the Force.com Workbook tutorial. The Force.com Workbook application tracks Merchandise records containing inventory information, as well as Invoices and their line items with a lookup to the Merchandise inventory data.

The completed tutorial application includes validation and workflow, and introduces you to many other Force.com features. However, we're just going to leverage the Merchandise data object to support building a simple mobile application that will display a list of Merchandise records, and allow basic CRUD operations.

We'll host our HTML5, JavaScript and CSS app in a single Visualforce page and use some Visualforce components for modularity. Our app will be built using mobile web technology leveraging the jQuery Mobile open source JavaScript library plus some additional code libraries and samples built by the Force.com developer evangelists, (one of the great advantages we have working on the Force.com platform is the leverage of the developer community and its core team of evangelists.)

REST vs Remoting

For this exercise, we're going to avoid using OAuth to reduce complexity, and we'll use Ajax and JavaScript Remoting instead as our data transport mechanism to push and pull data from @RemoteAction methods in an Apex controller class. An added advantage of this approach over using the REST services layer, is that we don't have an API call limit to deal with. However, one trade-off is that we can't leverage the Connected Apps feature of the Platform Mobile Services.

There are two similar JavaScript libraries that have been made available for use in an open source Github repository by the Force.com developer evangelists. The first, Forcetk.js uses REST and OAuth. The other, Remotetk.js uses JavaScript Remoting and Apex, and we'll use the latter. Keep in mind that our web based mobile application will be very simple, and that the basic user interface, although attractive and styled for a mobile form factor, will not be very robust. Our effort will be a "just enough" exercise; just enough to give you a taste of what kind of apps you can build with a mobile web approach.

Also keep in mind that there are a number of considerations with taking the HTML5 mobile web approach. The first is that a mobile web touch experience still does not quite match the performance and feel of a true native app, but it continues to get closer and closer. Another key point is that JavaScript will almost always be an integral part of the package.

While JavaScript is a powerful, extensible and challenging programming language to master, there are numerous libraries and frameworks evolving that provide both structure and leverage to the language to help prevent your complex business logic from devolving into a pile of unstructured, unmanageable and brittle code.

JavaScript Framework Options

The JavaScript language has been around for well over a decade, but more recently numerous open source and commercial frameworks and libraries have evolved to help developers with much of the heavy lifting required to manage user interface coding and data binding for dynamic HTML content.

Frameworks usually provide scaffolding and structure within which your custom functionality will reside. There's usually less flexibility than with libraries, but more powerful functionality that's managed for you as a developer. On the other hand, libraries are typically light weight collections of utility routines, providing a variety of functionality that can be easily combined with other libraries and frameworks. Here is a sampling of some of the most popular JavaScript offerings:

Sencha Touch provides a structured and extensible class system along with dozens of UI widgets, controls and graphics, allowing rapid and robust mobile app development. It also includes a complete data package with typed MVC data binding and proxy interfaces that communicate with a variety of back-end data services.

Angular.js is somewhere between a library and a framework; more of a toolset that provides an elegant MVC (Model, View Controller) pattern with dynamic data binding of JavaScript objects to HTML markup.

Backbone.js is a very flexible open source library that provides light weight MVC data functionality for your apps and integrates easily with other JavaScript libraries and frameworks.

Knockout.js is yet another open source library that has been around for a while, providing dynamic data binding using a MVVM (Model, View, ViewModel) approach.

jQuery Mobile is what we'll use to build the user interface for our application. It is a lightweight framework that integrates with its popular sibling, the jQuery JavaScript library. Designed to render an HTML mobile user interface using standard HTML markup, it is very easy for web developers to learn quickly. While particularly useful for rapid development of mobile web sites and simple applications, it typically requires additional integration with other JavaScript libraries to provide more structured data binding for complex enterprise mobile applications.

Force.com Supporting Libraries

We'll use the Force.com Remotetk.js library for our Force.com data transport layer with Apex, and some simple custom JavaScript code to reside between our HTML markup and the Remotetk.js generic JavaScript library that will connect to the remoting engine on the Force.com platform. It may not be as elegant an overall solution, but this less abstract approach may allow you to better visualize how the various moving parts of a mobile web app all hook together.

Later, you will likely want to explore working with some of the other more sophisticated data binding frameworks and libraries, in particular the JavaScript based Force.com Mobile Packs as you follow your learning path outlined at the close of this article.

In the end, it's all about trade-offs and picking the best tools for the tasks at hand. For our purpose, which is just an introduction to the mobile web concept, our choices will serve us well.

Please take note that the custom JavaScript code in the MobiWareApp.component that is integrated with the Remotetk.js library is based on the sample project built by Force.com Developer Evangelist Pat Patterson, and explained in his blog post NOT Calling the REST API from JavaScript in Visualforce Pages. In addition, I have made some small modifications to both the app code and the Remotetk.js files found in the developerforce JavaScript-REST-Toolkit Github repository. If you have any of that original code, do not use it in this project.

Prerequisite: Setup The Force.com Workbook Warehouse Database

This tutorial is dependent on the data model from the Force.com Workbook, but you will only need to work through Tutorial #1 (of 11) to build out the foundation of the Warehouse application. We will need only enough functionality to be able to access the Merchandise__c custom object so that you can fill in some sample data.

If you don't have one yet, go to the Force.com Getting Started page and set yourself up with a Developer Edition org. Come back when you have the Warehouse app built and its Merchandise__c custom object loaded with about a dozen completed Merchandise records; that's all you'll need for this tutorial.

Time To Jump In

We're going to build out the application from the bottom up. We will assume you have completed the Force.com Tutorial #1, and have the Merchandise__c custom object configured and loaded with some sample data in a working Force.com org. We'll start our app implementation with the Apex controller and its unit tests, and build out the components based on the dependencies between them.

Our Code Is In Github

I'm going to have you cut and paste Apex and Visualforce code snippets from a GitHub repository and slowly build up the application with the following parts:

  1. RemoteTKController.cls: an Apex class with supporting @RemoteAction CRUD methods.
  2. TestRemoteTKController.cls: an Apex class providing unit test coverage for the controller.
  3. RemoteTK.component: a Visualforce component containing a JavaScript utility library for Remoting access to the Controller methods.
  4. MobiWareApp.component: a Visualforce component containing the app's custom JavaScript code.
  5. MobiWareView.component: a Visualforce component containing the markup for the three mobile pages.
  6. MobiWare.page: a single Visualforce page that will host your app.

As we add these six components to your org, we'll review what they do and a little bit about how they work; the key is to quickly get you a working app that you can then dissect and explore on your own.

The completed code resides in a Github repository and you have the options of cloning the repository to your hard drive, or simply navigating to it in a browser, and by selecting the 'Raw' link in the upper right corner of the code panel. You can do a 'Select 'All' and 'Copy', and then 'Paste' it into your Force.com code editor. All of the code is under the /src folder, and positioned in the appropriate classes, components, and pages subdirectories that match the structure of a Force.com metadata package.

By the way, if you are not yet familiar with Git and Github, now's as good a time as any to learn. It has quickly become a new standard as a source code repository, and you will quickly come up to speed on its use, as well as become addicted to it as a source code repository. Here's a link to a great presentation that will explain how Git works, and another link to the Top 10 learning resources to help you quickly ramp up.

Develop In The Cloud

You can choose to build out the components of our app in the Force.com development environment of your choice. You can use the UI editors under the Setup->Develop area, the Developer Console Repository, or the Eclipse Force.com IDE; any of these will do just fine. The manner in which Apex classes, pages and components are named upon creation varies from devenv to devenv. For example, you must first name the class if in the Force.com IDE or Developer Console, but in the UI editor, just pasting the class code into the code window will establish the class name when the code is saved.

I'll admit that it's a better practice to build out an application one piece at a time, in an incremental approach, testing first and then adding more and more functionality with each iteration to insure that everything is working well before adding too much complexity.

However in our case, since the code is complete and tested, I'm just going to run you through the steps of creating each component from the code base in the Git repository, and we'll test when we're all done. The one exception will be running the Apex unit tests after creating the controller and its test class.

Some JavaScript Caveats

Before we get started, I want to share some words of caution to those of you not too familiar (yet) with JavaScript:

First: unlike Apex, JavaScript is case sensitive, and also very sensitive about matching block delimiters (those funny curly braces '{}' ) and semi-colon statement terminators. You're mostly going to be pasting completed code, but if you decide to experiment and change that code, (and I heartily recommend you should!) you'll have to remember to be very careful. Later, down the road, you can (and should) ramp-up on JavaScript Unit Testing practices with frameworks and tools such as Jasmine to help you avoid and manage any regression related bugs. You can go here to find out more.

Second: JavaScript typically 'fails silently.' In other words, you won't necessarily see errors appearing in the user interface if there are problems with your code at run-time, and you will have to rely on your browser's developer tools to visualize what's going on behind the scenes to inspect errors and the HTTP data stream. You can use the developer tools that come with Safari, or whatever other browser you're using, to monitor console output and to examine your requests and responses.

Step 1: Build The Apex Controller

  1. Navigate to the src\classes directory and copy the code for the RemoteTKController.cls
  2. Create a new Apex class, which will be named RemoteTKController, and paste the copied apex code from the Git repository to overwrite the class template code.
  3. Make sure that your code saves properly and that there are no compilation errors.

Let's take a closer look at one of the @RemoteAction methods, there's one for each CRUD operation including UPSERT and for both SOQL queries and SOSL searches. The method arguments typically include the string name of the sObject, an Id (if applicable to the operation,) and a field list. Below is the UPDATE method named updat() to avoid use of the reserved word. This class is a good example of dynamic Apex, as it is designed to handle any sObject type generically by iterating on the fields collection parsed from the JSON packet, deserializing the sObject in memory and executing the DML operation. Notice the substantial amount of error handling logic, as errors must be handed back gracefully to the mobile client.

    @remoteAction
    public static String updat(String objtype, String id, String fields) {
        Schema.SObjectType targetType = Schema.getGlobalDescribe().get(objtype);
        if (targetType == null) {
            return makeError('The requested resource does not exist', 'NOT_FOUND');
        }
        
        SObject obj = targetType.newSObject(id);
        
        Map<String, Object> fieldMap = null;
        try {
            fieldMap = (Map<String, Object>)JSON.deserializeUntyped(fields);
        } catch (JSONException je) {
            return makeError(je.getMessage(), 'JSON_PARSER_ERROR');
        }

        try {
            for (String key : fieldMap.keySet()) {
                obj.put(key, fieldMap.get(key));
            }
        } catch (SObjectException soe) {
            return makeError(soe.getMessage(), 'INVALID_FIELD');
        }
        
        try {
            update obj;
        } catch (DMLException dmle) {
            String fieldNames = '';
            for (String field : dmle.getDmlFieldNames(0)) {
                if (fieldNames.length() > 0) {
                    fieldNames += ',';
                }
                fieldNames += '"'+field+'"';
            }
            return '[{"fields":['+fieldNames+'],"message":"'+dmle.getDmlMessage(0)+'","errorCode":"'+dmle.getDmlType(0).name()+'"}]';
        }
        
        return null;
    }

Step 2: Add The Apex Controller Test Class

  1. Navigate back to the src\classes directory in the Git repository and copy the code for the TestRemoteTKController.cls
  2. Create a new Apex class, which will be named TestRemoteTKController, and paste the copied apex code from the Git repository to overwrite the class template code.
  3. Make sure that your code saves properly and that there are no compilation errors.
  4. Now run the tests; the exact manner in which you run them will depend on where you're doing your development. If you just created the test class in the UI Editor, you can click the 'Run Test' button at the top of the page.
  5. Verify that all of your tests pass.

We're not going to dive into the test class, but simply remind you that it would of course be needed to deploy your Apex controller into a production org.

Step 3: Add The RemoteTK.component

  1. Navigate to the src\components directory and copy the code for the RemoteTK.component.
  2. Create a new Visualforce component, set the name (and Label if in the UI Editor) as RemoteTK and paste the copied Visualforce code from the Git repository to overwrite the component template code.
  3. Make sure that your code saves properly and that there are no compilation errors.

We're using a custom Visualforce component to host this JavaScript library which manages our generic sObject data transport between our mobile web client and the Apex controller. It's a bit unusual to host JavaScript in this manner, as usually our JavaScript libraries are stored as static resources. However, while the latter approach provides the additional benefits of caching and compression, this practice is very useful when in a learning or development mode when you want to have easy access to your JavaScript code.

This library was designed to provide generic CRUD and query operations using JavaScript Remoting rather than the REST API, and you'll find a JavaScript method for each of the public @RemoteAction methods on the Apex controller. For example, below is the CREATE method that calls the @RemoteAction creat() method in Apex:

   /*
     * Creates a new record of the given type.
     * @param objtype object type; e.g. "Account"
     * @param fields an object containing initial field names and values for 
     *               the record, e.g. {Name: "salesforce.com", TickerSymbol: 
     *               "CRM"}
     * @param callback function to which response will be passed
     * @param [error=null] function to which jqXHR will be passed in case of error
     */
    remotetk.Client.prototype.create = function(objtype, fields, callback, error) {
        Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.RemoteTKController.create}', objtype, JSON.stringify(fields), function(result){
            handleResult(result, callback, error);
        }, { 
            escape: false
        });
    }

Notice the call to the Visualforce.remoting.Manager.invokeAction(), the reference to the mated controller action, and the callback method which returns a response object with results from the Apex method containing either data or messages.

Step 4: Add The MobiWareApp.component

  1. Navigate to the src\components directory and copy the code for the MobiWareApp.component.
  2. Create a new Visualforce component, set the name (and Label if you are using a UI Editor) as MobiWareApp and paste the copied Visualforce code from the Git repository to overwrite the component template code.
  3. Make sure that your code saves properly and that there are no compilation errors.

This is custom JavaScript code to manage our application logic, handle the display and mobile page transitions, and process application user events. Once again, we are hosting it in a custom Visualforce component as above.

Here is some code from the function that loads the main list view. Notice the call to the client.query() method to fetch the data; the client object is an instance of a Remotetk class from the library. This call is quite complex, and includes setting up a click handler on each item in the populated list with a callback method that will both load the detail form with data from the selected record, and transition the user to the form page to display the data.

//Populate the record list and set up list item click handling.
function getRecords(callback) {
    $j('#lstMerchandise').empty();
    client.query("SELECT Id, Name, Description__c, Price__c, Total_Inventory__c FROM Merchandise__c ORDER BY Name LIMIT 20"
    ,
    function(response) {
        $j.each(response.records,
        function() {
            var id = this.Id;
            $j('<li style="height:45px;"></li>')
            .hide()
            .append('<a href="#"><b>' + this.Name + '</b></a>')
            .click(function(e) {
                e.preventDefault();
				$j.mobile.loading( 'show' );               
    
    			// We could do this more efficiently by adding these fields to the fields in the SELECT, 
    			// but we want to show dynamic use of the retrieve function.
                client.retrieve("Merchandise__c", id, "Name,Id,Description__c,Price__c,Total_Inventory__c"
                ,
                function(response) {
					//Load the inputs on the form with the field values from the reponse object 
					//passed back from the apex controller retrieve method.
       				$j('#Name').val(response.Name);
                    $j('#Description__c').val(response.Description__c);
                    $j('#Price__c').val(response.Price__c);
                    $j('#Total_Inventory__c').val(response.Total_Inventory__c);
    				$j('#Id').val(response.Id);
    
		    		//Refresh the page.
    				$j.mobile.loading( 'show' );
                    $j.mobile.changePage('#pagDetail', "slide", false, true);

                }, errorCallback);
            })
            .appendTo('#lstMerchandise')
            .show();
        });

   		//Refresh the list.
        $j('#lstMerchandise').listview('refresh');

        if (typeof callback != 'undefined' && callback != null) {
            callback();
        }
    }, errorCallback);
}

Notice also how the returned response object is parsed and used to populate the various input controls on the appropriate form. You'll see similar patterns through out this component which has been left intentionally verbose. Much of the logic could be re-factored into a more generic pattern which would result in less code to write and maintain, but that's a more sophisticated topic for a later post.

Step 5: Add The MobiWareView.component

  1. Navigate to the src\components directory and copy the code for the MobiWareView.component.
  2. Create a new Visualforce component, set the name (and Label if in the UI Editor) as MobiWareView and paste the copied Visualforce code from the Git repository to overwrite the component template code.
  3. Make sure that your code saves properly and that there are no compilation errors.

Let's take a closer look at how the HTML5 markup is broken out into three sets of DIV tags, each one representing a different page in the mobile UI: the List View, the Detail View, and the Edit View. It is the data-role attribute that binds the DIV in the jQuery framework, which is then responsible for rendering the DIV in a touch form factor. Notice also the two HTML FORMS and the standard HTML inputs that we will bind to the fields from our sObject, and notice that the Detail View form has its fields set as ReadOnly.

<apex:component >

<!-- Merchandise List Page -->
<div data-role="page" id="pagList" data-theme="b" data-title="Merchandise" >

    <div data-role="header" data-position='fixed' >
        <h1>Merchandise List</h1>
        <a href="#" id="btnNew" class="ui-btn-right" data-theme="b" data-icon="plus">New</a>
    </div>

    <div data-role="content">
        <ul id="lstMerchandise" data-role="listview" data-theme="c" data-filter="true" data-autodividers="true">
        </ul>
    </div>

    <div data-role="footer" data-position="fixed">
		<h4>MobiWare</h4>
    </div>
    
</div>

<!-- Merchandise Detail Page -->
<div data-role="page" data-theme="b" id="pagDetail">
    
	<div data-role="header" data-position="fixed">
        <a href="#pagList" data-iconpos="left" data-icon="back" data-rel="back">Back</a>
        <h1>Merchandise Detail</h1>
        <a href="#" data-iconpos="left" data-icon="check" class="ui-btn-right" id="btnEdit" data-theme="b" >Edit</a>
    </div>    
    
    <div data-role="content">
		<form action="" method="post" id="frmDetail">
            <input type="hidden" name="Id" id="Id" />
            <label for="Name">Merchandise Name:</label>
			<input type="text" name="Name" id="Name" value="" readonly="readonly" style="background-color:lightgrey;"/>
        	<label for="Description__c">Description:</label>
        	<input type="text" name="Description__c" id="Description__c" value="" readonly="readonly" style="background-color:lightgrey;"/>
	        <label for="Price__c">Price:</label>
	        <input type="text" name="Price__c" id="Price__c" value="" readonly="readonly" style="background-color:lightgrey;"/>
            <label for="Total_Inventory__c">Total Inventory:</label>
	        <input type="text" name="Total_Inventory__c" id="Total_Inventory__c" value="" readonly="readonly" style="background-color:lightgrey;"/>
        </form>
    </div>

    <div data-role="footer" data-position="fixed" >
        <a href="#" class="ui-btn-left" data-icon="delete" id="btnDelete" data-theme="a">Delete</a>
		<h4>MobiWare</h4>
    </div>

</div>

<!-- Merchandise Edit Page -->
<div data-role="page" data-theme="b" id="pagEdit">

    <div data-role="header">
	    <a href="#pagList" data-iconpos="left" data-icon="back" data-rel="back">Cancel</a>
    	<h1>Merchandise Detail</h1>
		<button data-role="button" id="btnSave" data-iconpos="left" data-icon="check" data-theme="b">Save</button>
    </div>
    
	<div data-role="content">
		<form action="" method="post" id="frmEdit">
            <input type="hidden" name="Id" id="Id" />
            <label for="Name">Merchandise Name:</label>
			<input type="text" name="Name" id="Name" value="" />
        	<label for="Description__c">Description:</label>
        	<input type="text" name="Description__c" id="Description__c" value="" />
	        <label for="Price__c">Price:</label>
	        <input type="text" name="Price__c" id="Price__c" value="" step="0.01"/>
            <label for="Total_Inventory__c">Total Inventory:</label>
	        <input type="text" name="Total_Inventory__c" id="Total_Inventory__c" value="" step="0" />
        </form>        
    </div>

    <div data-role="footer" data-position="fixed">
		<h4>MobiWare</h4>
    </div>
    
</div>
    
</apex:component>

Step 6: Add The MobiWare.page

  1. Navigate to the src\pages directory and copy the code for the MobiWare.page.
  2. Create a new Visualforce page, set the name (and Label if in the UI Editor) as MobiWare and paste the copied Visualforce code from the Git repository to overwrite the component template code.
  3. Make sure that your code saves properly and that there are no compilation errors.

Let's take a closer look at this last piece of our app, the Visualforce page. It acts primarily as a host container for our modular Visualforce components, as well as for the links to any remote libraries. There's really not much here, but take note of the attributes in the apex:page tag to set the doctype for HTML5, and to turn off the standard Salesforce.com look and feel.

Note the embedded Visualforce component references, and the jQuery bootstrapping logic. You also must take care to manage the dependent order of the components and JavaScript library links, insuring that they are loaded on the page in the correct sequence. Finally, while you'll notice that we include links to hosted jQuery libraries, you can of course host your own libraries as static resources.

<apex:page docType="html-5.0" 
           showHeader="false" 
           sidebar="false" 
           standardStyleSheets="false" 
           contentType="text/html"
>

<!-- 
Use the RemoteTK component with all necessary JavaScript to connect with the 
Apex controller @RemoteAction methods for secure CRUD operations.
-->
<c:RemoteTK />

<!--  
Load the custom application JavaScript that will manage all client side application logic.
-->
<c:MobiWareApp />

<html> 
    <head> 
        <title>MobiWare</title> 

        <!-- Set Content type for the HTML -->
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

        <!-- Set a viewport to insure that the target device properly sets the form factor perspective -->
        <!-- <meta name="viewport" content="width=device-width, initial-scale=1" />  -->
		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
        
        <!-- We will use the cloud based jQuery libs to avoid loading them as static 
        resources. You can of course download them and maintain your own versions as 
        static resource. Take note to BE CAREFUL to correctly control ordering of the 
        JS includes! Testing in a desktop webkit browser such as Safari will work fine, 
        BUT Chrome will not load insecure content libraries without clicking on the 
        'Load Anyway' shield link in the URL bar!
        -->
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
        <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>

        <!-- This is the bootstrapping JavaScript code -->
        <script type="application/javascript">

            //Get a reference to jQuery that we can work with - Salesforce.com also uses jQuery!
            $j = jQuery.noConflict();
            
            //Create the RemoteTK client. 
            var client = new remotetk.Client();

			//Pass it the Visualforce session id so it can handle all CRUD 
			//operations using JavaScript Remoting calls rather than the REST API.
            client.setSessionToken('{!$Api.Session_ID}');            
            
            //Kick things off...
            $j(document).ready(function(){
                 
                //Set up the listerners for the button clicks.
                addClickListeners();
            
                //Display a loading animated icon.    
                $j.mobile.loading( 'show', {
                    text: 'MobiWare...',
                    textVisible: true,
                    theme: 'z',
                });

                //Load the main page with data.                
                getRecords(function(){
                	$j.mobile.loading('hide');
                });

            });

        </script>
    
    </head> 

    <body> 

        <!-- MobiWare main view -->
        <c:MobiWareView />
 
    </body>

</html>
</apex:page>

Step 7: Launch The Application

You should now be able to launch the MobiWare application, and we'll see if everything works as planned. I suggest that you run your desktop tests in a Safari browser for two reasons. The first, is that in addition to being a WebKit based browser, (it can render a touch style user interface and emulate multiple Apple device form factors,) it also has no problem loading unsecured content linked to across the web. Since we're linking to our jQuery libraries residing on an unsecured server, we don't want the browser blocking those calls, and Safari won't.

You can also use Chrome, but you will have to configure it to show the unsecured content each time you launch the mobile page, or configure it to launch with a special flag to turn off the security check. That's one extra step I think you'd rather avoid, as the fewer moving parts the better. The second reason is the available developer tools to monitor our JavaScript execution and our data transport, and the Safari developer tools work great for those tasks.

So, launch your browser and login to your org. To launch your mobile page, modify your URL address to include only the salesforce.com service instance and add '/apex/MobiWare' and then press enter. You should see the MobiWare application load in your browser with a display of up to twenty Merchandise records from your database.

https://c.{SERVER_NAME}.visual.force.com/apex/MobiWare

You should see the MobiWare List View:

RampingUpOnForceDotComMobileWeb Image01.PNG


And you can drill down to the Detail View for an item:

RampingUpOnForceDotComMobileWeb Image02.PNG


From which you can launch the Edit View:

RampingUpOnForceDotComMobileWeb Image03.PNG


You can do the same thing on a mobile device, logging into your development application as usual. Of course, Salesforce.com will display in a very small presentation, but once logged in, you can change the URL to add the name of the Apex page.

When you're ready to put a mobile web application into production, it can be launched through a Force.com Site, exposing mobile Visualforce pages in a secure and sensible manner. Your users will simply need to navigate to a custom domain that you can be configured with your company name, and keep in mind that a mobile Visualforce application can also be used to create a mobile website for your company.

On an iPhone, once displayed, users can save the link on their device home screen to launch at the click of an icon. There are even open source JavaScript libraries that you can add to your app that will cause a popup bubble message to prompt users to 'Add to Home.' You might try adding one such library to the MobiWare app as an exercise. You will find one such popular library from cubiq.org here.

You will need to download their JavaScript library and add it to the MobiWare project as either a static resource or embedded in a Visualforce component. As mentioned above, I've kept the JavaScript for this project in Visualforce components for easy access to the code from the UI editor or Developer Console, but you are of course free to move it all into static JavaScript library files.

Your Mobile Learning Path

I hope you're encouraged to continue your mobile ramp-up, and to explore all of the options to build out applications targeting mobile devices, particularly with the recently released Force.com JavaScript based Mobile Packs.

Here's what I'd suggest as a Mobile Learning Path:

1. Start with a deeper understanding of the Touch user experience paradigm from the people who wrote the book - Apple. It's critical to keep in mind that mobile applications are often most successful when they provide solutions for one or more small, (though not necessarily unimportant,) tasks that need to be performed anywhere and anytime. This is perfect with regard to Salesforce.com implementations, where often there can be a multitude of such operations or user interactions. You don’t have to build large or complex mobile applications to benefit greatly from a mobile addition to your org, but you do need to think carefully about what kind of tasks would be most beneficial to be managed from a mobile device by your user community. So here's the link to the Apple Human Interface Guildelines (HIG) to give you some ideas as to what kind of apps would be an appropriate target for your user community.

2. Go install all three sample JavaScript framework based Force.com Mobile Packs into a DE org and dissect them. These are three versions of the same simple Contact manager application written using three different JavaScript frameworks, Backbone.js, Angular.js and jQuery.js. These implementations provide the structured approach missing from our exercise, and also introduce alternate ways to approach your mobile web development effort. They also install really easily into your DE org for you to be able to explore them quickly and painlessly.

3. If you liked the copy and paste experience, you might try my tutorials on Force.com and Sencha Touch. It's spread across multiple posts, and will definitely keep you busy for a few evenings. Here's a link to the Sencha Touch website to find out more about the framework.

4. If you're interested in learning more about jQuery, try these on-line tutorials by Jorge (AKA the 'MiamiCoder') and the jQuery Mobile Home Page.

5. Dig into the primary mobile knowledge repositories on the developer.force.com portal, starting with the new Platform Mobile Services home page with links to all of the mobile SDKs.

6. Dig into some of the many deep dive wiki articles and tutorials on the Force.com wiki, and dozens of Dreamforce presentations on YouTube.com covering various aspects of mobile development related to Salesforce.com, here are just a few about security:

And last, but certainly not least, check out the Pluralsight website where you'll find hundreds of beginner to hard core developer online courses, including many on JavaScript, HTML5, Hybrid, iOS and Android, (not to mention developer courses on Force.com too.)

I found the following JavaScript courses particularly helpful with regard to the more intricate aspects of the language:

The list goes on and on, but this should give you plenty to chew on.

So...what are you waiting for? Jump in and ramp-up!

About the Author

Don Robins has been building custom business applications with framework-based architectures for over two decades. He found his way into Force.com as a consultant and architect in 2009, and has recently been immersing himself in Force.com mobile development, integration and training. A Salesforce.com Certified Advanced Developer and award winning Certified Instructor, he delivers all of the Salesforce.com Developer Classes (DEV401, 501, 502, 531), both domestically and internationally, in both public and private workshops when not consulting or mentoring privately. His background and experience in the trenches as Developer, Architect, Team Lead, Tech Mentor, Certified Agile Scrum Master, and Developer Community Leader shapes his training and mentoring approach with developers of all skill levels, from novice to architect. Don is a principal of Outformations, Inc. and teaches under the banner of ForceMentor.com.