Managing Navigation

Salesforce1 manages navigation using events. The navigation event framework is made available as a JavaScript object that provides a number of utility functions that make creating programmatic navigation that “just works” a breeze. The advantage is a navigation experience that’s more natural for a mobile context. It also makes creating post-completion navigation, such as redirecting to an order page after the order is successfully submitted, easier for Salesforce1 developers.
In Salesforce1, programmatic navigation for Visualforce pages generally works something like this:
  1. A user invokes a Visualforce page, usually from the navigation menu, or from the publisher.
  2. The Visualforce page loads and runs, including any custom controller or extension code called by the page.
  3. The user interacts with the page in some way, for example, to fill in some form values.
  4. The user submits the form, or performs some other action on the page that commits a change.
  5. Controller or extension code runs, saving the changes to Salesforce, and returning the results of the action.
  6. The Visualforce page, using JavaScript response handlers, receives the results of the action, and when successful, responds by redirecting the user to a new page that shows the results of their action.
This scenario is easily handled by the Salesforce1 navigation framework.

Another common use case is simply adding links or other user interface controls to a page, which move from that Visualforce page to another page in Salesforce1. This navigation is also easily managed by the Salesforce1 navigation framework.

In all cases, navigation is handled by a special utility JavaScript object, sforce.one. The sforce.one object is automatically added to all Visualforce pages when they run inside the Salesforce1 app. This object provides a number of functions that trigger navigation events when they run. To use these functions, you can call them directly from your page’s JavaScript code, or you can attach calls as click handlers to elements on the page.

Here’s a JavaScript function, from the FindNearbyWarehousesPage page introduced in Extending Salesforce1 with Visualforce Pages, which creates markers to add to a Google map.
1function setupMarker(){ 
2
3    // JavaScript nav function call to add to a link
4    var warehouseNavUrl = 
5        'sforce.one.navigateToSObject(\'' + warehouse.Id + '\')';
6
7    // Wrap the warehouse details with the link to 
8    // navigate to the warehouse details
9    var warehouseDetails = 
10        '<a href="javascript:' + warehouseNavUrl + '">' + 
11        warehouse.Name + '</a><br/>' + 
12        warehouse.Street_Address__c + '<br/>' + 
13        warehouse.City__c + '<br/>' + 
14        warehouse.Phone__c;
15   
16    // Create a panel that will appear when a marker is clicked
17    var infowindow = new google.maps.InfoWindow({ 
18        content: warehouseDetails
19    });
20   
21    // ...
22}
The very first line builds a string, warehouseNavUrl, that, when used as a JavaScript URL, navigates to the detail page for the warehouse. The link is created around the warehouse name, and appears in the information panel (put together in the warehouseDetails string) that appears when you click a marker. Clicking the warehouse name takes you to the detail page for that warehouse (the omitted part of the function code deals with the Google Maps API calls to create a marker and add it to the map).
If you have JavaScript code or HTML markup that runs inside of Salesforce1, keep these considerations in mind:
  • Don’t directly manipulate the browser URL using window.location.href. This doesn’t work well with the Salesforce1 navigation management system.
  • Don’t use target="_blank" in navigation URLs; you can’t open new windows inside Salesforce1.

Navigation with the sforce.one Object

The Salesforce1 Platform includes an event mechanism for navigation. This is exposed in Visualforce as a JavaScript object called sforce.one. It’s available in any page that appears in Salesforce1.

The sforce.one object provides the following functions. Reference the function using dotted notation from the sforce.one object. For example: sforce.one.navigateToSObject(recordId, view).

Function Description
back() Navigates to the previous page that’s saved in the sforce.one history. Normally equivalent to clicking a browser’s back button.
navigateToSObject(recordId,view) Navigates to an sObject record, specified by recordId.

view is optional, and specifies the view within record home to select—chatter, related, or detail.

navigateToURL(url) Navigates to the specified URL.

Relative and absolute URLs are supported. Relative URLs retain navigation history, absolute URLs open a child browser window.

navigateToFeed(subjectId, type) Navigates to the specific feed, subjectId.

type is the expected feed type, for example NEWS.

navigateToFeedItemDetail(feedItemId) Navigates to the specific feed item, feedItemId.
navigateToRelatedList(relatedListId, parentRecordId) Navigates to the related list as specified by the relatedListId. The parentRecordId is the record of the parent object. For example, for a related list of Warehouses, the parentRecordId would be Warehouse__c.Id.
navigateToList(listViewId, listViewName, scope) Navigates to the list view as specified by the listViewId and listViewName.
createRecord(entityName, recordTypeId) Opens the page to create a new record for the specified entityName.

recordTypeId is optional, and if provided, specifies the record type for the created object.

editRecord(recordId) Opens the page to edit the record specified by recordId.
Keep the following in mind when using the sforce.one object:
  • Calls to sforce.one.navigateToURL may result in an “Unsupported Page” error if the URL references standard pages for objects or Chatter pages. To avoid this error, ensure that the URL begins with a backslash (/_ui instead of _ui).
  • The sforce.one.createRecord and sforce.one.editRecord methods don’t respect Visualforce overrides on these standard actions.

How sforce.one Handles API Versions

The sforce.one object is frequently improved in new releases of the Salesforce1 Platform. To maintain backward compatibility, sforce.one provides version-specific behavior, and you can use a specific version of sforce.one in your apps.

By default, sforce.one uses the same version as the API version of the requested Visualforce page. For example, if a Visualforce page has an API version of 30.0, JavaScript on that page that uses sforce.one by default uses the API version 30.0 of sforce.one.

This means that when a Visualforce page is updated to a new API version, the page automatically uses the updated version of sforce.one. In the preceding example, if that Visualforce page is updated to API version 31.0, app functionality that uses sforce.one uses the API version 31.0 of sforce.one.

If updated behavior in a new API version of sforce.one causes compatibility problems with the page’s features, you have three options for correcting the problem.
  • Revert the Visualforce page’s API version to the prior version. This action requires no code changes.
  • Update the code for the page’s features to fix the problem. This solution is best, but it might require some debugging, and it will definitely require code changes.
  • Use a specific version of sforce.one. This solution often requires minimal code changes.

sforce.one was added in Winter ’14 (API version 29.0) and wasn’t versioned until Summer ’14 (API version 31.0). All versions of sforce.one earlier than version 31.0 are identical to version 31.0. You can specify a version of sforce.one for any version that’s valid for Visualforce, that is, from version 15.0 to the current API version.

Note

Using a Specific Version of sforce.one

To use a specific version of sforce.one, use the sforce.one.getVersion() function and provide it with the API version and a callback function that needs to use a specific version of sforce.one. The appropriate versions of sforce.one are automatically loaded by this call.

The signature for sforce.one.getVersion() is:
1sforce.one.getVersion(versionString, callbackFunction);

versionString is the API version that your application requires. It’s always two digits, a period, and one digit, such as “30.0”. Calls with invalid version strings fail silently.

callbackFunction is a JavaScript function that uses a specific version of sforce.one. sforce.one.getVersion() operates asynchronously, and your callback function is called when it finishes loading the requested version of sforce.one. Your callback function receives a single parameter, an sforce.one object for the specified API version. Use the object passed in instead of the global sforce.one to make calls to sforce.one that conform to the API version that your app requires.

Examples of Using a Specific Version of sforce.one

The next examples all add a Create Account function to the following input button:
1<input type="button" value="Create Account" onclick="btnCreateAccount()" id="btnCreateAcct"/>

Defaulting to the Visualforce Page’s API Version

App code that should use the default version of sforce.one—the version that corresponds to the Visualforce Page’s API version—doesn’t need to ask for a version. Using that version happens automatically, and the code is straightforward.
1<script>
2    function MyApp() {
3        this.createAccount = function() {
4            sforce.one.navigateToURL("/001/e");
5        };
6    } 
7
8    var app = new MyApp();
9
10    function btnCreateAccount() {
11        app.createAccount();
12    }
13</script>

App functionality is created in a MyApp object, and then an event handling function calls the app function when that event, a button click, occurs. Separating application functionality from application event handling is a best practice, and it sets you up for using version-specific versions of sforce.one.

Using a Specific sforce.one API Version (Simple)

To use a specific version of sforce.one, get and save a reference to a versioned instance of the object. Then use this object to make sforce.one calls. The simplest way is to save it in the MyApp object. In the next sample, references to the versioned instance of sforce.one are in bold.
1<script>
2    function MyApp(sfone) {
3        this.createAccount = function() {
4            sfone.navigateToURL("/001/e");
5        };
6    } 
7        
8    var app30 = null;
9
10    function btnCreateAccount() {
11        // Create our app object if not already defined
12        if(!app30) {
13            // Create app object with versioned sforce.one
14            sforce.one.getVersion("30.0", function(sfoneV30) {
15                app30 = new MyApp(sfoneV30);
16                app30.createAccount();
17            });
18            return;
19        }
20        app30.createAccount();        
21    }
22</script>

In the preceding example, the event-handling function is expanded from the first example to include the creation of a version-specific instance of sforce.one. If your app needs to mix multiple versions, you can create multiple MyApp instances with appropriate versions and names. More than one or two, though, are cumbersome to manage. We recommend the next approach instead.

Using a Specific sforce.one API Version (Best)

A better way to organize your app code is to create version-specific instances of sforce.one in an app initialization block of code so you can keep the event handling separate.
1<script>
2    function MyApp(sfone) {
3        this.createAccount = function() {
4            sfone.navigateToURL("/001/e");
5        };
6    } 
7        
8    var app30 = null;
9
10    // Initialize app: get versioned API, wire up clicks
11    sforce.one.getVersion("30.0", function(sfoneV30) {
12        // Create app object with versioned sforce.one
13        app30 = new MyApp(sfoneV30);
14
15        // Wire up button event
16        var btn = document.getElementById("btnCreateAcct");
17        btn.onclick = btnCreateAccount;
18    });
19
20    // Events handling functions
21    // Can't be fired until app is defined
22    function btnCreateAccount() {
23        app30.createAccount();
24    }
25</script>

In this sample the app initialization is separated only by white space and comments, but you can separate it into functions for better encapsulation.

Using a Specific sforce.one API Version (Synchronous)

You can trigger a synchronous mode for sforce.one by manually including the specific version of sforce.one’s JavaScript on your page. The format for the URL to the library is:/sforce/one/sforceOneVersion/api.js. Here’s an example:
1<script src="/sforce/one/30.0/api.js"></script>
2<script>
3    function MyApp(sfone) {
4        this.createAccount = function() {
5            sfone.navigateToURL("/001/e");
6        };
7    } 
8        
9    var app = null;
10
11    sforce.one.getVersion("30.0", function(sfoneV30) {
12        app = new MyApp(sfoneV30);
13    });
14
15    // Events handling function
16    // Can't be fired until app is defined
17    function btnCreateAccount() {
18        app.createAccount();
19    }
20</script>

Although some situations require synchronous mode, the asynchronous version is preferred. If you forget to manually include the correct versions of the sforce.one library, your code will contain bugs that are difficult to diagnose.