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:

navigator.geolocation.getCurrentPosition(function(position){
    lat = position.coords.latitude;
    lon = position.coords.longitude; 

    Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.FindNearby.getNearby}', lat, lon,
    function(result, event){
        if (event.status) {
            console.log(result);
            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:

@RemoteAction
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';

    return(database.Query(queryString));
}

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 sforce.one.navigateToSObject() function to navigate to the detail page for the relevant venue:

clubNavUrl = 'javascript:sforce.one.navigateToSObject(\'' + 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: "publisher.post", onData:function(e) {
    insertPerformer();
}});

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(){
    CreatePerformerController.insertPerformer('{!ClubEvent__c.Id}',
        $('#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="{!$Resource.style}"/>
    <img class="center" width="90%" 
      src="/sfc/servlet.shepherd/version/download/{!Performer__c.Image_ID__c}"/>
</apex:page>

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.