Salesforce1 Cures the App Boogie Fever

App Boogie Fever!This last Dreamforce, in our Mobile Theater session on building a Salesforce1 app (watch the recording on YouTube!), Samantha and I decided to have a bit of fun: we built an app to manage music venues, events and performers, and got into character by dressing up… disco style! Behind the wigs, loud shirt and outrageously bad puns (thanks, Ryan, for being an awesome MC!), there was a serious message – you really can build mobile functionality incredibly quickly with Salesforce1. Here’s a quick rundown of what we achieved in just 30 minutes:

1. Locate the User and Show Nearby Venues on a Map

First, Samantha created a Visualforce page to show nearby venues. The page uses HTML5 Geolocation to get the user’s current latitude and longitude, and uses JavaScript Remoting to call FindNearby(), a controller method:

    lat = position.coords.latitude;
    lon = position.coords.longitude; 

    Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.FindNearby.getNearby}', lat, lon,
    function(result, event){
        if (event.status) {
            createMap(lat, lon, result); 
    }, {escape: true});

FindNearby() executes a SOQL query with the DISTANCE() and GEOLOCATION() formula functions to find the 10 closest venues within 7 miles of the user’s position, returning the venue data as JSON:

global static List<Venue__c> getNearby(String lat, String lon) {
    String queryString =
        'SELECT Id, Name, Address_Geo__Longitude__s, Address_Geo__Latitude__s, ' +
            'Street_Address__c, Phone__c, City_Address__c ' +
        'FROM Venue__c ' +
        'WHERE DISTANCE(Address_Geo__c, GEOLOCATION('+lat+','+lon+'), \'mi\') < 7 ' +
        'ORDER BY DISTANCE(Address_Geo__c, GEOLOCATION('+lat+','+lon+'), \'mi\') ' +
        'LIMIT 10';


With the JSON data in hand, it’s a snap to display it via Google Maps – see the FindNearbyVenues Visualforce page for the full code. One detail that is worth calling out is the link on each map marker; this uses the function to navigate to the detail page for the relevant venue:

clubNavUrl = '\'' + club.Id + '\')';

2. Add a child record via a Publisher Action

Next, Samantha created a Publisher Action on the Venue custom object to create an Event record, and added it to the Page Layout for Venue. Rather than describe the click path, I’ll just send you to the relevant spot in the session recording. Note – no code was required for this step – it was all ‘clicks, not code’.

3. Invoke a Visualforce Page via a Publisher Action to Capture a Photo

Now it was my turn. I showed a Visualforce Page that gathered data to create a Performer record and associate it with an Event. Again, the whole page is online, in the Github repo for the Boogie Fever app; I’ll just walk through the highlights here.

To interact with the Salesforce1 container, my Visualforce Page includes the Salesforce1 Publisher library:

<script type="text/javascript" src="/canvas/sdk/js/publisher.js"></script>

Next, when my page is loading, it calls two Salesforce1 Publisher methods:

Sfdc.canvas.publisher.publish({name: "publisher.setValidForSubmit", payload:"true"});
Sfdc.canvas.publisher.subscribe({name: "", onData:function(e) {

The first call tells Salesforce1 to enable the ‘Submit’ button. Usually, you would do this after performing some client-side validation, checking that required fields are populated, for instance, but my page is very simple, so it just enables the Submit button as it loads. The second call registers a callback on the ‘post’ event – this function will be called when the user clicks the ‘Submit’ button.

The insertPerformer() method is very straightforward – it just calls an insertPerformer() @RemoteAction method on the controller with the Event ID, Performer name and Performer email, supplying a callback that closes the publisher action.

function insertPerformer(){
        $('#name').val(), $('#email').val(), function(performerId){
            Sfdc.canvas.publisher.publish({name: "publisher.close", payload:{ refresh:"true"}});

With all this in place, I can create an Action on the Event custom object, just like Samantha did on Venue, but this time invoking my Visualforce Page, rather than declaratively creating a record. You can see the setup on the recording.

The remainder of the Create Performer code is concerned with capturing a photo of the performer. I covered this in detail a few weeks ago, so I won’t repeat it here.

4. Create a Mobile Card to Show a Photo on a Standard Record Layout

Having captured a Performer’s photo, we need a way to display it. Mobile Cards allow you to add custom UI to the standard page layout in Salesforce1. I used Visualforce to simply display the Chatter File content as an image:

<apex:page standardController="Performer__c" sidebar="false" 
  showheader="false" standardStylesheets="false">
    <apex:stylesheet value="{!$}"/>
    <img class="center" width="90%" 

Again, you can see in the recording how I added the Mobile Card to the Performer Page Layout.

So with Salesforce1, in just 30 minutes, Sam and I turned an existing schema for Venues, Events and Performers into a mobile app, including features such as geolocation, mapping and photo capture, seamlessly interleaving custom Visualforce Pages with standard Page Layouts. We set this session up as a ‘battle’ between the two presenters, but, as Ryan says at the end of the recording, “I don’t know if Samantha won, or Pat won, but I do know that… wait for it… Salesforce1!”
tagged , , , , Bookmark the permalink. Trackbacks are closed, but you can post a comment.
  • Missed this session, thanks for the revisit.

    Samantha Ready. Best. Afro. Ever.

    • Samantha Ready

      Thanks 🙂

  • Thanks for update, I loved these

  • Jason Venable

    Heads up there is an issue with Android version of Salesforce1 that will not return accurate GPS coordinates for the device.

  • Greg Jacobi

    This is a great post and really helped me figure out how to upload an image.

    For my implementation, I decided to not use forcetk (I just have no experience with it) and I want my pictures as attachments and not part of the chatter feed.

    I’m running into an issue though where for large image files I get the error: Remoting Exception: Input too long.

    I’m wondering if your solution would have the same issue or if I used the forcetk approach would it solve it for me?

    Any help would be great!


  • Erik Solis

    Great stuff my sf friends, i’ve modified some of this code and works perfectly for what i’m looking for. thank you a lot and keep up the good code.

  • SK Tayal

    Hi i have used it, great , working fine for option of pick image from gallery, but when i use it to take picture form camera and save it, it takes so many time and show error(because of image size approx 2 MB). Guys please help me regarding it, how can i solve this issue.