Capturematic (GitHub repo) is an iOS app that lets you post a photo, audio or video to any Salesforce record with a Chatter feed; it’s a great example of a simple hybrid mobile app that accesses device functionality – in this case, the camera and microphone. You can see the app in action in this short video:
Capturematic uses Cordova to access device features and Backbone.js as a model/view framework, but in this blog entry I’ll focus on the new Salesforce Mobile Templates, which provide the app with a modern mobile look-and-feel. At present, Capturematic is only available as source code, but I may submit it to the AppStore if there is sufficient demand.
Capturematic’s source is located in a single file,
index.html, that is loaded after the Mobile SDK has authenticated the user. I’ll reproduce sections of code here, but you’ll probably find it useful to have that file open for reference.
The first thing you’ll notice, right at the top of the file, is the initial
In a mobile browser, such as Safari on iOS, page content is laid out on the viewport, which can be larger or smaller than the visible area. When you view web pages on Safari that are not optimized for mobile, the viewport is typically larger than the screen, and you pan and zoom around it using touch gestures. In this
<meta> tag, we explicitly specify that the viewport is the same width as the device screen, content is not scaled, and the user cannot zoom in on the page content – we want our app to behave more like an app than a web page. Next, you’ll see references to two stylesheets;
app.css is the standard stylesheet for the Mobile Templates, while
style.css defines some custom styles for Capturematic:
style.css for a moment, you can see how I’ve extended the Mobile Templates to add styling for an icon-panel class (copied from the template’s detail-view-action-panel class and modified from vertical to horizontal orientation), and sliding pages with CSS transitions, inspired by Christophe Coenraets’ PhoneGap Tutorial.
index.html, to the set of
main.min.js. This code implements dynamic template components such as the Map and Carousel.
Moving on down index.html, you’ll see the following code:
Skipping down to the
<body>, we see Capturematic’s HTML markup. As a single-page application, Capturematic contains a top-level
<div> element that acts as a container for dynamic content. The
<div> is initialized with a ‘loading’ message while the app starts up and loads data.
The remaining markup is a series of Underscore templates. Three of the templates represent ‘pages’ in the app – Objects, Records, and Record Detail; the remaining two are list elements that are repeated on the pages – Object and Record.
The list of Force.com object types is rendered via
objects-template. Let’s look at it in detail:
If you’ve already looked at the Mobile Templates, you’ll recognize the structure here. There is a page header, a
<section> containing some text, and a list view. This structure, and the CSS classes such as
right-one-icons, produce an attractive mobile look and feel for the object list:
The list view is populated by a Backbone view,
app.ObjectsView, which renders the Object list items via
Here you can see eRuby-style variable interpolation.
app.ObjectsView iterates over the list of object types retrieved from Force.com, creating a new list item for each one, combining the template with the object metadata. You can see where the
label fields are substituted into the HTML on the second and third lines respectively. The
<%= name %> syntax causes the object name (e.g.
Merchandise__c) to be used verbatim, while
<%- label %> HTML-escapes label text, so labels containing characters such as ‘&’ or ‘<‘ won’t break the markup.
The record list page works in much the same way as the objects list, but the record detail page is worth examining in a little more detail:
The record detail page shares many structural elements, such as the
<div>‘s, with the object list page, but there are some new concepts here.
Look at the link in the page header – the
<a> element doesn’t contain an
href attribute, or any content, apart from a non-breaking space! Take a quick look in
app.css and you’ll see that the left-arrow class is styled with a background image and size:
By using the left-arrow style here and in the record list page, we keep the app DRY by having a single location for the UI element’s look-and-feel.
The record detail page uses the same interpolation for the record name, and more Mobile Template classes,
form-control-textarea, to style the
<textarea> input element. You can see the custom classes here, too –
icon-panel is a horizontal layout of icon buttons for capturing photo, audio and video. The result is an attractively rendered detail page:
I could take Capturematic in any of a number of possible directions – here are a few examples:
- Binary distribution via the Apple AppStore
- Android version
- Move from Backbone.Force to the Mobile SDK 2.0’s SmartSync.js
- Show previously uploaded media content – or perhaps the entire Chatter feed for the record
- Compress audio data, saving it as MP3 rather than WAV format
Let me know in the comments how you think I should prioritize these, or if you think of more, and I’ll blog the process.
I hope this post has demonstrated the potential of the Salesforce Mobile Templates. As well as the basic elements I used in Capturematic, there are many more dynamic components – the Mobile Templates site walks through the current palette – and you’re free to modify and extend the Mobile Templates for your purposes – they’re all open sourced under the Apache 2.0 license. Let us know if you build a cool mobile Force.com app, and we might just feature it in our Mobile App Gallery!