You can see in this snippet, that we set the default page transition to ‘none’ rather than using the normal slide animation that comes out-of-the box with jQuery Mobile. That’s a personal preference, but I prefer to avoid animation so the performance appears snappy.

Second, I create the basic structure of the app with the different pages in the body. There are four pages in the app:

Homepage with check-in button

Map showing check-ins

Map to confirm your location while checking in

List of opportunities to select which you’re working on

So here’s the HTML to create those:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<div data-role="page"id="one"data-url="one">

<div data-role="content"class="ui-content"role="main">

<button id="checkin">Check-inwith photo</button>

</div><!--/content-->

</div>

<div data-role="page"id="two"data-url="two"></div>

<div data-role="page"id="three"data-url="three"></div>

<div data-role="page"id="four"data-url="four">

<ul data-role="listview">

</ul>

</div>

With that created, moving from page one to two is as simple as:

1

location.href="#two";

Now, SalesSquare uses a native topbar and tabbar to help with the navigation, the camera so you can take a photo of where you are during the check-in process and location look-up to center the map.

You can see snippets covering those features in main.js and map.js, and we’ve blogged in detail before about how to use those features:

You can see here that we specify a redirect url and then make sure it matches the ‘pattern’ parameter that is passed to ‘forge.tabs.openWithOptions’. This is so the modal dialog automatically closes when the success redirect url is reached. And we can then access the token and other parameters that are passed back by Salesforce.

Next, using the access token we’ve just received, we retrieve the user’s identity, you can see this in the ‘getIdentity’ function:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

forge.request.ajax({

url:url,

type:"POST",

data:{

"version":"latest",

"format":"json",

"oauth_token":state.token

},

headers:{

"Authorization":"OAuth "+state.token

},

success:function(data){

if(typeof data=="string"){

data=JSON.parse(data);

}

state.identity=data;

forge.prefs.set('identity',JSON.stringify(state.identity));

salesforce.getOpportunities();

subscribe();//Subscribe for push notification for this organization

},

error:function(data){

forge.logging.log('Error getting identity');

forge.logging.log(data);

}

});

You need the identity object in order to be able to construct the right urls for querying the opportunities and posting to chatter, which, at this point, is simple. Check out the ‘getOpportunities’ and ‘post’ functions in salesforce.js and you’re there:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

forge.request.ajax({

url:state.identity.urls.query.replace("{version}","24.0")+"?q="+encodeURI("SELECT Name FROM Opportunity where StageName='Prospecting' or StageName='Qualification'"),

Finally, we add some bootstrap code to check if we already have the identity and token or if we need to kick off the oauth flow:

1

2

3

4

5

6

7

8

9

10

11

forge.prefs.get('token',function(token){

forge.prefs.get('identity',function(identity){

if(token&&identity){

state.token=token;

state.identity=JSON.parse(identity);

salesforce.getOpportunities();

}else{

salesforce.login();

}

});

});

Setting up push notifications with Parse

Ok, the final tricky part of the app is setting up push notifications so that when one user checks in, others in the organization are notified.

There is some setup to be done here – Trigger.io integrates with parse.com to provide push notifications, so you’ll need to create an account there to get the necessary tokens, and then add lines like the following in your config.json for Trigger.io:

1

2

3

4

5

6

"partners":{

"parse":{

"applicationId":"YourApplicationKeyZdAtirdSn02Qy6NofiU2Hf",

"clientKey":"YourClientKeyZdAtirdSn02QQy6NofiU2Hfy6No"

}

}

Next we’ll set up code to listen and respond to push notifications, you can see this in the ‘subscribe’ function in main.js: