Mobile User Interfaces - Development with the Force.com Platform: Building Business Applications in the Cloud, Third Edition (2014)

Development with the Force.com Platform: Building Business Applications in the Cloud, Third Edition (2014)

8. Mobile User Interfaces

Mobile applications are subject to design constraints including processing power, reduced screen size, and limited or unreliable network connectivity. Addressing these constraints while still delivering functional applications is the goal of numerous technology platforms, development techniques, and dedicated technical books. There are endless methods for building mobile applications, all of them equally valid depending on the details of the device, application, and needs of the user.

Salesforce and the Force.com platform support the latest best practices and technology platforms used to develop mobile applications, extending them with dedicated toolkits and hooks in the Force.com platform. This chapter provides exposure to the common approaches to building mobile applications and dives deeper on one specific approach, the mobile Web (also referred to as HTML5) application. It is organized into the following sections:

Image Overview of Salesforce mobile technology—Get familiar with how Salesforce supports mobile devices in terms of its own applications and custom applications.

Image Getting started with mobile Web applications—Walk through the technology components and choices for building mobile Web applications using Force.com.

Image Sample application—Create a phone and tablet-friendly timecard entry feature for the Services Manager sample application.


Note

The code listings in this chapter are available in a GitHub Gist at http://goo.gl/SVU7RT.


Overview of Salesforce Mobile Technology

Mobile devices are by definition always on the go, exposed to vagaries of battery life and network connectivity as well as the physical size constraints of displays and input devices. The formidable technical challenge of these problems and the huge demand for mobile devices have driven rapid innovation. From this innovation comes a proliferation of operating systems, user interface styles, development frameworks, and architectural techniques, all vying for developer attention.

Every significant technology vendor has framed mobile technology in its own terms. Salesforce is no exception. Salesforce offers its own mobile philosophy and supporting technologies, both in the application and platform space. These are discussed in this section, divided into two parts:

Image Salesforce applications—There are three actively supported mobile applications from Salesforce, each with its own unique feature set.

Image Custom applications—Salesforce advocates three distinct approaches to mobile application development, providing tools and frameworks to support them.

Salesforce Applications

Although it is possible to use Salesforce’s standard Web user interface from a browser-equipped mobile device, it has significant drawbacks. The desktop-centric user interface is cumbersome on a smaller screen, requiring lots of zooming and panning to find and click anything. The performance is sluggish due to the large amount of information, media, and code on each page. And if network connectivity is lost, it can also mean the loss of functionality and work in progress.

To improve the experience for mobile users, Salesforce offers three applications specifically designed for mobile phones and tablets:

Image Salesforce Classic—This is the original Salesforce mobile application. It is geared toward users who need offline access to data. Administrators can select data to synchronize with the mobile device by user or profile, and remotely delete the data at any point. By default, the standard Sales and Service Cloud application data is synchronized with the device, including contacts, accounts, and opportunities.

Image Salesforce Touch—Salesforce Touch can be thought of as a reskinned subset of the Salesforce Web application, designed for devices that rely on touch input rather than a keyboard and mouse. All data remains on the Salesforce servers, not on the mobile device. Standard and custom object tabs are available, with limited record creation and editing functionality.

Image Chatter Mobile—Chatter Mobile is focused on collaboration. You can post and comment on feeds, create and edit records, view and add files, participate in groups, and view dashboards and user profiles.

Many independent software vendors have released applications that address the Salesforce market. Some are tailored for a particular workflow, such as sales or service. Others are neutral, adopting the tabs and layouts from your Salesforce organization and providing generic data management in a mobile form factor. Run a search on your mobile device’s application marketplace to learn more.

Custom Applications

There are many ways to develop custom mobile applications that leverage the Force.com platform. Salesforce has assembled tools and techniques for each of the three distinct approaches to mobile development, listed here:

Image Native applications—Native applications have unrestricted access to all of the features of the mobile device. This power can be used to deliver the best possible user experience, but typically comes with a high development cost, especially if an application must be supported on multiple mobile vendors’ devices.

Image Mobile Web applications—On the opposite end of the spectrum, mobile Web applications run inside the mobile device’s Web browser based on HTML5. They do not have access to the full set of device capabilities, but with this compromise comes advantages in terms of ease of development and distribution.

Image Hybrid applications—Hybrid applications are mobile Web applications deployed inside a native application that serves as a “container.” The most notable benefits are access to native device features and the ability to promote and distribute the application on device-specific marketplaces.

The Salesforce Mobile Software Development Kit (SDK) provides open source technology to aid in the development of all three types of custom mobile applications. Download it from the following location:

Image iOS—https://github.com/forcedotcom/SalesforceMobileSDK-iOS

Image Android—https://github.com/forcedotcom/SalesforceMobileSDK-Android


Note

The Salesforce Mobile SDK page at http://wiki.developerforce.com/page/Mobile_SDK is an excellent starting point for diving deeper into Salesforce’s mobile development technology.


Native Applications

Native applications are purpose-built for each device platform. For example, a native mobile developer targets one or more mobile platforms such as iOS, Android, Windows Phone, and BlackBerry 10. Although there are vendors that promise shortcuts, strictly speaking each platform adds its own jargon, development tools and frameworks, and unique approach to mobile challenges such as user interface paradigm, hardware abstraction, and software deployment.

The advantages of native applications include usability, integration with hardware and native applications (such as those managing calendars and contacts), access to secure offline storage, and built-in application distribution. Disadvantages vary but typically involve the cost and complexity of supporting multiple devices and operating systems.

Salesforce Mobile SDK provides libraries and sample projects for developing native applications for iOS and Android. Specifically, it helps developers in four main areas:

Image Login—The Mobile SDK simplifies the OAuth login process.

Image Offline data caching—SmartStore is a component of the Mobile SDK that enables the secure storage of data for offline access.

Image REST—The Force.com REST API is provided as a set of friendly infrastructure classes.

Image Application creation—The Mobile SDK includes a tool called forceios that generates a sample native application to connect to a Salesforce organization and run a simple query. This can be a good starting point for your development.

Mobile Web Applications

Mobile Web applications rely on the mobile device’s browser to function. Often they are ordinary Web pages designed to adapt their user interfaces from full-size monitors to tiny mobile screens. This usage of standard Web technology to deliver the same application to desktop and mobile users can be a huge time savings over native application development.

Another significant advantage to mobile Web applications is that they are served up from servers, not stored on the mobile device. This means developers can continually improve the application remotely, and users always see the latest version. Native and hybrid applications have a binary component that is downloaded and installed on the device. Although the binary can be updated after it is installed, that is an additional manual step for the user.

Unfortunately, mobile Web applications are rarely able to deliver the same level of user experience as a native application. Due to size and battery constraints, tablets and phones have a subset of the processing power of laptop and desktop computers. Their Web browser cannot render complex pages or execute code as quickly. Additionally, the standard user interface components that the user is familiar with from the mobile device are either Web-based approximations or entirely different, requiring the user to adapt to the new way of representing data and controls.

Salesforce Mobile SDK includes two libraries that are extremely helpful in building mobile Web applications integrated with Force.com, described next:

Image SmartSync—SmartSync exposes Salesforce records as JavaScript objects, with query and CRUD access seamlessly supported. It extends a popular open source framework called Backbone.js to accomplish this.

Image forcetk.js—This JavaScript library is a wrapper of the Salesforce REST API.

Hybrid Applications

Hybrid applications promise the best of both worlds, combining the flexibility of native with the ease of development of Web. In a hybrid application, some content is shipped in the binary like a normal native application, while some is left out and delivered through Web pages instead. Their distinguishing feature is a “container” that hosts the Web content and grants it access to native resources.

Being a mixture of native and Web, hybrid applications share the pros and cons of both. For example, if your hybrid application relies extensively on Web content, it will suffer the user experience limitations of mobile Web applications. In general, hybrid applications rely on the judgment of the developer to select the best way (native or Web) to implement functionality on a feature-by-feature basis.

This introduces a larger issue of complexity. Although developers have greater flexibility with hybrid applications, building them requires knowledge of both mobile Web and native technology, plus the “container” layer between them. The container in the Salesforce Mobile SDK is called Cordova (formerly PhoneGap).


Note

Due to their significant dependence of technology unrelated to Force.com, hybrid and native applications are outside the scope of this book. Refer to the Salesforce Mobile SDK home page at http://wiki.developerforce.com/page/Mobile_SDK for more information.


Getting Started with Mobile Web Applications

Out of all three types of custom mobile applications, Web applications are arguably those closest to and benefiting most from the Force.com platform, particularly if they are mobile versions of Visualforce pages. Mobile aside, Web applications can be challenging to build due to rapidly moving trends in usability, browser standards, and security practices. Mobile Force.com applications add a number of additional challenges that are addressed in this section.

At a high level, there are three major areas to examine when building mobile Web applications with Force.com:

Image Frameworks—Web development frameworks typically adopt some design pattern such as MVC (Model-View-Controller) or MVVM (Model-View-View Model). These patterns separate logic from presentation and allow the construction of scalable, interactive Web applications. They usually bundle or recommend a templating and data access layer. Some frameworks are specifically tailored for mobile applications.

Image Data access—Assuming that Force.com is the data layer for the mobile application, there are a few options for integrating it.

Image Deployment—Deployment concerns how mobile users will find and start using your mobile application. This is more complex with mobile Web applications than native applications.

Frameworks

Web development frameworks can reduce and manage the complexity of building Web applications, particularly the Single Page Applications (SPAs) that are becoming commonplace. SPAs rely on the Web browser to execute the majority of the user interface code, such as fetching the model and using it to render views. This is in contrast to the original breed of Web applications, which performed these duties on the Web or application server.

Any Web framework could be relevant to mobile Web development, but this subsection divides them into two camps:

Image Mobile Components for Visualforce—This Salesforce-provided open source library blends jQuery Mobile with Visualforce components to make mobile-ready Visualforce pages easier to create.

Image Web MVC frameworks—Web frameworks such as Knockout, Backbone, Ember, and Angular are behind many popular, modern Web applications, including those from Salesforce. Any of these can be used to build mobile Force.com-enabled applications, and Salesforce provides sample applications to get you started.

Mobile Components for Visualforce

Mobile Components for Visualforce is a series of simple Visualforce components that generate HTML for mobile devices. They leverage jQuery Mobile framework, but wrap it to make it easier to use in Visualforce.

There are three types of components in Mobile Components for Visualforce, described here:

1. Structural components—These components help determine the layout of the page. The App component is the container for all other components. SplitView renders the traditional left-side navigation, right-side detail layout, and is typically used with the SplitViewTemplatein an apex:composition component. Page defines a dynamic content page as found in a Single Page Application. The Header and Footer components are children of Page and contain content to be placed at the top and bottom of the page. The Content component, also a child of Page, is the generic container for content.

2. Data components—The List component renders a list of records resulting from a SOQL query. The Detail component uses the page layout definition of an SObject to render its fields in proper position. Both of these components are read-only, meaning they do not allow the users to edit their data.

3. Navigation component—This component generates a navigation bar containing links to show content within the page or URLs outside of the page.

To install Mobile Components for Visualforce in your Salesforce organization, complete the following steps:

1. Download the source code by running git clone https://github.com/forcedotcom/MobileComponents.git or equivalent in a Git client application.

2. Zip the source code so that it can be deployed. For example: cd MobileComponents/Visualforce; zip -r mobile_components.zip src/*

3. Visit the Workbench home page at http://wiki.developerforce.com/page/Workbench. Click the Login to Workbench Now on Developerforce link or https://workbench.developerforce.com directly, authenticate to your organization by clicking the Login with Salesforce button, and select Deploy from the Migration menu. Check Rollback on Error and click the Choose File button in Google Chrome (the Browse button in Firefox) to locate your locally stored zip file. Proceed through the wizard to upload the file.

4. Test the deployment by visiting /apex/MobilePage in your Web browser.


Notes

The full documentation and source code for Mobile Components for Visualforce are available at http://wiki.developerforce.com/page/MobileComponents.


Web MVC Frameworks

Web MVC frameworks include jQuery Mobile, AngularJS, and Backbone.js. Although these frameworks can be used directly to build mobile Web applications with Force.com, Salesforce has put together open source projects called Salesforce Mobile Packs to make this process easier. There is one Mobile Pack for each of the supported frameworks. The Mobile Packs contain fully functional sample applications leveraging each of the frameworks with Force.com data.

Salesforce also provides Mobile Design Templates, which provide attractive and functional CSS and HTML for common Force.com data-rendering scenarios.


Note

Salesforce Mobile Packs can be found at http://www2.developerforce.com/mobile/services/mobile-packs. Mobile Design Templates are located at http://www2.developerforce.com/mobile/services/mobile-templates.


Data Access

Data access is one of the major design decisions involved in building a Force.com mobile Web application. There are a few different ways to use the Force.com REST API. This includes authenticating to Force.com and reading and writing its data.

There are two choices for authentication, described next:

Image OAuth—In OAuth, the developer creates a Connected Application in Force.com and uses it when creating the application. For the user who has not yet authenticated, he or she is directed to a special Salesforce login page. After login, the user is prompted to share his or her information with the application. If granted access, the user is redirected back to the mobile Web application, which now has an access token that grants it permission to access Force.com on the user’s behalf. Like a session with the Salesforce Web interface, the token eventually expires and must be refreshed by the application to obtain a valid one.

Image Session sharing—If the mobile Web application is hosted inside Force.com or an application already authenticated to Force.com, a session identifier can be embedded in the page. This can be used to make requests to Force.com without asking the user to log in again.

These two authentication methods can also be combined in a single application, granting more flexibility in how the application is hosted.

When it comes to accessing Force.com data, the decisions depend on how you build your application. For example, some data access methods are available only for a specific Web MVC framework. Others only work when hosted within Visualforce pages. A few of the most common methods follow:

Image SmartSync—SmartSync keeps your Web page’s data model in sync with the Force.com data. As you retrieve or make changes to a collection or model in your Web application, SmartSync makes the necessary calls to Force.com to mirror them persistently in the Force.com database. SmartSync is an extension of the Backbone framework, so your application must be using Backbone to leverage it.

Image JavaScript remoting—Available only to Visualforce pages, JavaScript remoting involves adding a RemoteAction annotation to a static controller method. This makes the method accessible to JavaScript without any of the overhead of the Visualforce view state. Keeping data access as lightweight as possible is critical for mobile applications, so JavaScript remoting is a best practice when building mobile applications in Visualforce.

Image actionFunction component—This method of data access is only available to Visualforce pages. Like JavaScript remoting, it makes a call from the browser’s JavaScript to the Visualforce controller. It requires less code than JavaScript remoting to call it, but performance is not as good due to its reliance on view state.

Image Force.com REST API—The forcetk.js library wraps the Force.com REST API so that it is easier to use from JavaScript. Because your Web page will be served from a server other than the REST API endpoint, accessing the endpoint violates same-origin security policy in modern Web browsers. This policy states that a script on a page cannot access a host other than the one serving the page itself. To address this, a proxy is provided by Salesforce, called the AJAX Proxy. For more information, refer to the online documentation athttp://www.salesforce.com/us/developer/docs/ajax/Content/sforce_api_ajax_queryresultiterator.htm#ajax_proxy.

Deployment

Because mobile Web applications are just Web pages, deployment ultimately requires that the user simply visit your application’s URL. If you’ve built your application to use OAuth for authentication, you can host its Web pages anywhere. If you’re using session sharing, you need to host it in an application, referred to here as a container that the user has already used to authenticate to Salesforce.

The advantage of a container is that users don’t need to authenticate to Salesforce again just to use your application. Additionally, they have all of the other features included in the container application. But don’t be fooled. At the end of the day, the container is purely a Visualforce page viewer and bookmarker. To be successful, your Visualforce page has to be mobile ready.

The mobile applications that can serve as containers for Visualforce pages are Salesforce Classic and Salesforce Touch. To enable a Visualforce page to be shown in Salesforce Classic, follow these steps:

1. In the App Setup area, click Create, Tabs. Click the Visualforce tab you’d like to make available in Salesforce Classic, and check the Mobile Ready check box.

2. Create a configuration to make the Visualforce page visible. In the Administration Setup area, click Mobile Administration, Salesforce Classic, Configurations. Click the New Mobile Configuration button. Enter a name for the configuration, make it active, and select the users and profiles who will use this mobile configuration.

3. With your new configuration, you make tabs visible to the mobile device. Click the Customize Tabs button in the Mobile Tabs section of the configuration. Select a tab from the list of available tabs, click the Add button, and click the Save button.


Note

Refer to the Salesforce Classic Implementation Guide for more information, which can be found at http://www.salesforce.com/us/developer/docs/mobileImplGuide/index.htm.


The steps to add your Visualforce pages to Salesforce Touch are next:

1. In the Administration Setup area, click Mobile Administration, Salesforce Touch, Settings. Check the Enable Visualforce in Salesforce Touch check box. This step needs to be performed only once for an entire organization.

2. For each Visualforce page to be displayed in Touch, go to the App Setup area, click Develop, Pages. Click the Visualforce page, and check the Available in Touch check box. You also need a Visualforce tab for each page. To create one, go to the App Setup area; click Create, Tabs; and click the New button in the Visualforce Tabs section. Select the Visualforce page to be displayed in Touch, give your tab a label and name, pick a style, and click the Next button. On the following two pages, select the profiles that can access the tab and which custom applications include it. Then click Save to finish the Visualforce Tab Creation Wizard.


Note

Unless you plan to use your new Visualforce tabs with Salesforce Classic, there is no need to enable the Mobile Ready option. It has no effect on Salesforce Touch.


Sample Application: Mobile Timecard Entry

The goal of this section is to build a mobile-ready timecard entry interface for consultants. The requirements for this interface are as follows:

1. Users are already using Salesforce Touch. They do not want to install a new mobile application on their phones and tablets. They also don’t want to authenticate to an additional application or page.

2. Allow hours to be entered on a project as quickly as possible, with minimal clicking around.

3. Timecards are precreated based on the current week and available assignments, so they are always valid. There is no need to know the assignment or look up any additional information.

4. Hours can be entered and saved, but do not need to be submitted right away. This allows the consultant to keep track of his or her hours on a daily basis rather than waiting until the end of a week.

5. Five of the most recent timecards can be displayed. Timecards in an Approved or Submitted status are locked and cannot be edited. Other timecards can be edited and saved or submitted.

The finished page is shown in Figure 8.1 on an iPhone and in Figure 8.2 on the Web. Upon viewing the page, the consultant is immediately able to see the timecards he or she is responsible for entering based on his or her assignments. The page is responsive, so in the mobile browser the list of timecards is shown at the top. With a wider screen, this navigation list is pulled to the left. Clicking on a timecard displays its hours, which are totaled dynamically as they are entered.

Image

Figure 8.1 Mobile timecard entry page in iPhone

Image

Figure 8.2 Mobile timecard entry page in Web browser

The mobile timecard entry page can be constructed in three steps, described next:

1. List timecards—Write a controller method that returns the five most recent timecards. If no timecards exist yet for the current week and projects that the consultant is assigned to, create and return them in the list of recent timecards. Render each timecard in a list that includes the week ending date, project name, and timecard status.

2. Navigate to timecard—Allow the user to navigate to a timecard by clicking it. This causes the panel described in the next step to be refreshed.

3. View and edit timecard—Display the hours (Monday through Friday only) and total hours for the currently selected timecard. If the timecard is not in an Approved or Submitted status, allow the hours to be edited. Provide a button to save changes made to the hours and another button to save changes and submit the timecard.

Listing 8.1 is the controller to implement the first step. It uses JavaScript remoting rather than ActionFunction to provide the best performance for the Visualforce page. The load method looks up the current user’s Contact record and looks for Assignment records within the current week. For every Assignment record without a Timecard record, a Timecard record is created. Finally, the most recent five Timecard records by Week_Ending__c are returned.

Listing 8.1 Visualforce Controller for Mobile Timecard


public with sharing class MobileTimecardController {
@RemoteAction
public static List<Timecard__c> load() {
Contact c = currentResource();
if (c == null) {
return null;
}
Date currentWeekEnding =
Date.today().toStartOfWeek().addDays(6);
// Create a current week's timecard for each assignment
for (Assignment__c a : [ SELECT Project__c
FROM Assignment__c WHERE Contact__c = :c.Id
AND Status__c = 'Scheduled'
AND Start_Date__c < :currentWeekEnding
AND End_Date__c >= :currentWeekEnding
]) {
if ([ SELECT Id FROM Timecard__c
WHERE Contact__c = :c.Id
AND Week_Ending__c = :currentWeekEnding
AND Project__c = :a.Project__c
LIMIT 1].size() == 0) {
insert new Timecard__c(Project__c = a.Project__c,
Week_Ending__c = currentWeekEnding,
Contact__c = c.Id);
}
}
List<Timecard__c> timecards = [ SELECT Project__r.Name,
Week_Ending__c, Status__c,
Monday_Hours__c, Tuesday_Hours__c, Wednesday_Hours__c,
Thursday_Hours__c, Friday_Hours__c
FROM Timecard__c
WHERE Contact__c = :c.Id
ORDER BY Week_Ending__c DESC
LIMIT 5 ];
return timecards;
}
private static Contact currentResource() {
List<Contact> contacts =
[ SELECT Id, Name FROM Contact
WHERE User__c = :UserInfo.getUserId() ];
if (contacts != null && contacts.size() == 1) {
return contacts.get(0);
}
return null;
}
}


Listing 8.2 is a Visualforce page that provides the timecard list functionality for the first step. It does not include the Visualforce header, sidebar, or standard stylesheets to improve load performance. It uses Twitter Bootstrap for simple styling and responsive grid system, and AngularJS to dynamically bind data from the Visualforce controller to and from the HTML elements. The AngularJS aspects of the page are important to examine closely:

Image MobileTimecardCtrl is the name of the AngularJS controller. MobileTimecardController is the Visualforce controller, which is referenced when RemoteAction methods are called. Note the usage of its load method. This sets a scope variable called timecards, which is bound to the HTML list items using the ng-repeat attribute.

Image Ignore the use of the ng-click attribute and the navClass callout in the list items for now. Those are part of the second step, for navigation.

Image Bootstrap is an open source project consisting of CSS and JavaScript to help produce clean, consistent, responsive Web applications for desktop and mobile browsers. For more information, see https://github.com/twbs/bootstrap. In this page, the important parts of Bootstrap are the grid. The row-fluid CSS class sets up a row in the visual grid system that positions the elements in your page. The span family of CSS classes (span1 through span12) makes up the columns of your page. A single row can consist of a single span12, or 12 span1 elements, and everything in between. In the mobile timecard page, the navigation bar on the left is a span3, and the detail area, shown when a timecard is clicked, is span9.

Listing 8.2 Visualforce Page for Mobile Timecard


<apex:page showHeader="false" standardStylesheets="false"
sidebar="false"
controller="MobileTimecardController">
<head>
<meta name="viewport"
content="width=device-width,initial-scale=1.0,
maximum-scale=1.0,user-scalable=0"/>
<link
href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap.css"
rel="stylesheet" />
<style>
input[type="number"] { width: 30px; }
</style>
</head>
<body>
<script>
function MobileTimecardCtrl($scope, $rootScope, $location) {
MobileTimecardController.load(function(result, event) {
if (event.status) {
$scope.timecards = result;
$rootScope.$apply();
}
}, { escape: false });
}
</script>
<apex:outputPanel html-ng-app=""
html-ng-controller="MobileTimecardCtrl" styleClass="container-fluid">
<div class="row-fluid">
<div class="span3">
<div class="well sidebar-nav">
<ul class="nav nav-list">
<li ng-class="navClass('{{timecard.Id}}')"
ng-repeat="timecard in timecards">
<a ng-click="nav('{{timecard.Id}}')">
{{timecard.Project__r.Name}}:
{{timecard.Week_Ending__c | date:'M/d/yyyy'}}
<br /><span class="label">{{timecard.Status__c}}</span>
</a></li>
</ul>
</div>
</div>
<div class="span9">
</div>
</div>
</apex:outputPanel>
<script
src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.min.js">
</script>
</body>
</apex:page>


Listing 8.3 implements the second step, in-page navigation, with the addition of two functions for the MobileTimecardCtrl AngularJS controller. Insert it after the load function in the first script tag.

For a simple page like this, creating many Visualforce pages, one for each view, adds unnecessary overhead. An alternative is to allow the user to navigate but stay within the page, providing the page with the logic and visual templates necessary to encompass all of the user interactions. Clicks on anchors change the “route” understood by the Web framework, but it is handled entirely by the Web framework. The browser does not load a new Web page. This type of dynamic navigation within a page is typical of a Single Page Application, described in Chapter 7, “Advanced User Interfaces.”

The navClass method returns the HTML class needed to display highlighting around the “active” (selected) timecard by comparing the list element’s route to the current path reported by the browser. With every timecard displayed in the list, this method is called to determine its style class.

The nav method is called when the user clicks a timecard. Rather than using the standard href attribute, the ng-click attribute allows the navigation to stay within AngularJS. The method first finds the selected timecard in the model, the list of timecards previously retrieved using the Visualforce controller’s load method. It then sets that timecard to the edit variable so that it can be bound to the detail region of the page, to be added in the third step. It also checks to see if the timecard is in an editable state, setting a readOnly variable accordingly.

Listing 8.3 Angular Controller Addition for Navigation


$scope.navClass = function(page) {
var currentRoute = $location.path().substring(1) || '';
return page === currentRoute ? 'active' : '';
}
$scope.nav = function(timecardId) {
$location.path(timecardId);
for (var idx in $scope.timecards) {
if ($scope.timecards[idx].Id == timecardId) {
$scope.edit = $scope.timecards[idx];
$scope.readOnly = $scope.edit.Status__c == 'Submitted' ||
$scope.edit.Status__c == 'Approved';
return;
}
}
$scope.edit = null;
}


Listings 8.4, 8.5, and 8.6 implement the changes needed to allow timecards to be viewed and edited. Listing 8.4 adds a new method to simply save the timecard. The AngularJS code in the browser maintains edits made to the timecard data and passes it into the Visualforce controller where it is updated in the Force.com database.

Listing 8.4 Visualforce Controller Addition to Edit Timecard


@RemoteAction
public static void save(Timecard__c timecard) {
update timecard;
}


Insert the code in Listing 8.5 into the div element with class span9. This is the right side of the page and will contain the detail of the selected timecard. There are two portions of HTML, but only one is visible at any given moment. They are displayed conditionally using the ng-showattribute. If there is a currently selected timecard, the edit variable will contain it; otherwise, it is null. The timecard fields are rendered using input elements, and they are disabled if the timecard is not editable. The bidirectional data binding of AngularJS is demonstrated with the dynamic calculation of total hours in the timecard from the user input fields.

Listing 8.5 Visualforce Page Addition to Edit Timecard


<div class="row-fluid">
<div class="span12" ng-show="edit != null">
<form><fieldset>
<legend>Timecard for {{edit.Project__r.Name}},
Week Ending {{edit.Week_Ending__c | date:'M/d/yyyy'}}
</legend>
<div class="control-group">
<div class="controls">
<input type="number" ng-model="edit.Monday_Hours__c"
placeholder="M" ng-readonly="readOnly"></input>
<input type="number" ng-model="edit.Tuesday_Hours__c"
placeholder="T" ng-readonly="readOnly"></input>
<input type="number" ng-model="edit.Wednesday_Hours__c"
placeholder="W" ng-readonly="readOnly"></input>
<input type="number" ng-model="edit.Thursday_Hours__c"
placeholder="Th" ng-readonly="readOnly"></input>
<input type="number" ng-model="edit.Friday_Hours__c"
placeholder="F" ng-readonly="readOnly"></input>
<label>Total Hours: {{edit.Monday_Hours__c + edit.Tuesday_Hours__c +
edit.Wednesday_Hours__c + edit.Thursday_Hours__c +
edit.Friday_Hours__c}}</label>
<div ng-hide="readOnly">
<button ng-click="save('Saved')" type="submit"
class="btn">Save</button>
<button ng-click="save('Submitted')" type="submit"
class="btn">Submit</button>
</div>
</div>
</div>
</fieldset>
</form>
</div>
<div class="span12" ng-show="edit == null">
Please select a timecard to edit it.
</div>
</div>


Listing 8.6 is the final piece to the timecard entry page. Insert it into the AngularJS controller. It adds a save method, which is wired up to the Save and Submit buttons in Listing 8.5. It sets the status of the timecard and calls the Visualforce controller’s save action to save it. It then resets the page so that no timecard is selected.

Listing 8.6 Angular Controller Addition to Edit Timecard


$scope.save = function(status) {
$scope.edit.Status__c = status;
MobileTimecardController.save($scope.edit,
function(result, event) {
if (event.status) {
$location.path('/');
$scope.edit = null;
$rootScope.$apply();
}
}, { escape: false });
}


To test this feature, install Salesforce Touch on your mobile device and perform the following steps:

1. Enable the page for Touch access. Go to the App Setup area and click Develop, Pages. Click the Visualforce page, click the Edit button, check the Available in Touch check box, and click the Save button.

2. Add a Visualforce tab for your new page. In the App Setup area, click Create, Tabs. Click the New button in the Visualforce Tabs section. Select the MobileTimecard Visualforce page, give the tab a label and name that you’d like to see on your mobile device. Select a tab style, profiles, and application visibility, and save the tab.

3. Launch Salesforce Touch on your mobile device and log in.

4. Click the List icon in the upper-left corner to overlay the list of accessible pages. You should see your Mobile Timecard page as an option. Select it to start using the mobile timecard entry feature.

Summary

Mobile development with Force.com is a rapidly changing subject, with an active open source community around it. There are a wealth of options for building mobile applications, some directly baked into Salesforce products, some born within Salesforce but supported by the community, and many other general-purpose technologies that can be helpful.

Before moving on to the next chapter, take a moment to review a few highlights related to mobile development:

Image Salesforce provides three mobile applications that are ready to download and use for Android and iOS devices: Salesforce Classic, Salesforce Touch, and Chatter Mobile. Of the three, the first two are the most interesting to mobile developers because they can be extended with custom Visualforce pages.

Image There are three major types of custom mobile applications: native, Web, and hybrid. Native is the closest to the mobile device’s hardware and therefore offers the best performance and depth of features. Web runs within the mobile device’s Web browser, and offers the least control to the developer but can be easier to develop and deploy. Hybrid strives to be the best of both approaches, a mix and match of native and Web. Pick the option that makes the most sense for your application, users, and development skill set.

Image Although Visualforce is a good starting point for mobile Web applications, your Visualforce controllers and pages need to be optimized for this purpose. Visually they should be responsive, adapting to the screen resolution of the device. In terms of data, they should be frugal, requesting data only as needed and avoiding page navigation. Using Visualforce as the container for a Single Page Application is a helpful pattern. A number of open source projects are available to help with Web applications, from data management to responsive design.