AngularJS application on Visualforce for the Force.com platform and the Salesforce1 mobile application. Dreamforce 2014. Talk is given for experienced Salesforce developers who want to learn common features of AngularJS to build custom applications for the Salesforce1 mobile app.
1. Salesforce1 Events App on AngularJS
in Two Weeks
Peter Chittum
Developer Evangelist
salesforce.com
@pchittum
Adrian Smalley
Lead Salesforce Architect
Acumen Solutions
@adriansmalley
2. Safe Harbor
Safe harbor statement under the Private Securities Litigation Reform Act of 1995:
This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such uncertainties materialize
or if any of the assumptions proves incorrect, the results of salesforce.com, inc. could differ materially from the results expressed or implied by the
forward-looking statements we make. All statements other than statements of historical fact could be deemed forward-looking, including any
projections of product or service availability, subscriber growth, earnings, revenues, or other financial items and any statements regarding
strategies or plans of management for future operations, statements of belief, any statements concerning new, planned, or upgraded services or
technology developments and customer contracts or use of our services.
The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and delivering new functionality for
our service, new products and services, our new business model, our past operating losses, possible fluctuations in our operating results and rate
of growth, interruptions or delays in our Web hosting, breach of our security measures, the outcome of any litigation, risks associated with
completed and any possible mergers and acquisitions, the immature market in which we operate, our relatively limited operating history, our ability
to expand, retain, and motivate our employees and manage our growth, new releases of our service and successful customer deployment, our
limited history reselling non-salesforce.com products, and utilization and selling to larger enterprise customers. Further information on potential
factors that could affect the financial results of salesforce.com, inc. is included in our annual report on Form 10-K for the most recent fiscal year
and in our quarterly report on Form 10-Q for the most recent fiscal quarter. These documents and others containing important disclosures are
available on the SEC Filings section of the Investor Information section of our Web site.
Any unreleased services or features referenced in this or other presentations, press releases or public statements are not currently available and
may not be delivered on time or at all. Customers who purchase our services should make the purchase decisions based upon features that are
currently available. Salesforce.com, inc. assumes no obligation and does not intend to update these forward-looking statements.
6. EventFlex
Before we begin….
• This app is open source and an accelerator for those wishing to take it further.
• It is hosted on github : https://github.com/adriansmalley/eventflex
• Showcases cool features but isn’t quite production ready. You have been warned.
8. Timeline
Acumen’s approach to custom SF1 App creation
Initiate Define Build Deliver Launch
1 2 3 4 5 6 7 8 9 10
UX SF1 Config Angular App Data Layer Front end Dev
9. Who and How?!
The criticalness of UX and Wireframing
Solution
Team
Tools
?!
UX & BA Admin Angluar & SF DEV
Google Docs
Balsamiq
Git Issues
Github
UX
10. Step 1 : Persona’s, Design, Style, UX
Adrian : Bringing user experience to the centre of app development
11. Have the user at the heart and the start
Thinking about User Experience from the beginning
# 1
# 2
# 3
1. Personas 2. Stories 3. Prioritise Stories
4. User Flows 5. Wireframes 6. Design
UX
12. Begin with the end in Mind
The criticalness of UX and Wireframing
4 Version of this
screen before
deciding
Choosing Charts
before development
Single attempt at Build!
UX
31. Angular Community and Directives
There is heaps of awesome open source out there
• Using other peoples components in your app :
– Saves you loads of time
– Is often better tested
– Often more widely tested (cross browsers etc)
• It’s easy to search for components (directives) that will help you out.
• We used :
– Angular Gantt (http://angular-gantt.github.io/angular-gantt)
– Angular Charts (https://github.com/chinmaymk/angular-charts.git)
Front End
32. Installing Apps / Directives
Integrating other components
• Adding to your app is super easy :
1. Install
<apex:includeScript
value="{!URLFOR($Resource.Angula
rD3, 'd3-master/d3.min.js')}"/>
<apex:includeScript
value="{!URLFOR($Resource.Angula
rChartsJS)}" />
2. Inject
var d3App =
angular.module('d3App',
['ngRoute', 'angularCharts']);
3. Add to controller
$scope.config = {}
$scope.data = {}
4. Use Directive in Page
<div ng-controller="d3CTRL">
<div data-ac-chart="'pie'" data-ac-
data="data" data-ac-config="
config" class="chart">
<div>
Front End
34. Understanding the Data Flow
VISUALFORCE
CONTROLLER DIRECTIVES
SERVICES
APEX Classes
The Execution Cycle
Front End
1. Page Loads
2. Angular Controller calls init()
3. Controller Calls the Services
4. Services calls APEX classes via
@remoteAction
5. Data Returned from Apex to
Services
6. Services Returns data to
Controller
7. Controller Refreshes the page
8. VOLA!
35. MVC for Javascript. Remarkably similar to APEX.
APEX Controller Angular Controller
public with sharing class efCharts {
public Id eventId {get;set;}
public list<events> evtList {get;set;}
public pageReference getNewDashboard(){
return null;
}
}
d3App.controller('d3CTRL', function($scope,
chartServices, $routeParams) {
$scope.eventId = $routeParams.id;
$scope.events = [];
$scope.refreshData = function(){
...
}
}
Visualforce Page HTML Page
<apex:page controller="efCharts" >
<apex:repeat value=”{!evtlist}” var=”e”>
{!e.Name}
</apex:repeat>
</apex:page>
<div ng-app="d3App">
<div ng-controller="d3CTRL">
<ul ng-repeat=”e in events”>
<li>{{e.Name}}</li>
</ul>
</div>
</div>
Front End
36. Bindings - putting stuff on the page
• Output bindings are the simplest way to stamp data on your page using {{}}
<span>{{Event.Start_Date__c}}</span>
• However this prints out the wrong format so lets use a formatter. Magic.
<span>{{Event.Start_Date__c | date : ‘dd-MM-yyyy’}}</span>
[Works for Date, Number, Currency, Uppercase, Lowercase]
• If we want a 2 way connection e.g. an input field we use ng-model which will refresh
the page on change of this value. Amazing for live filtering.
<input ng-model=”searchText”/>
Front End
37. Repeats, Repeats, Repeats
• Repeats are key to delivering lists of data. They can be either Arrays OR Objects.
<li ng-repeat=”item in items”>{{item.Name}}</li>
<li ng-repeat=”(key, value) in items”>{{value.Name}}</li>
• Angular Packs some serious punch with filters
–Simple filter that searches for anything in the array
<li ng-repeat=”item in items | filter: searchText”>{{item.Name}}</li>
Front End
–Restricted filter that searches for a field on an object
<li ng-repeat=”item in items | filter: {name:searchText}”>{{item.Name}}</li>
–Add in orderBy for maximum control<li ng-repeat=”item in items | filter:
searchText | orderBy:’Name’”>{{item.Name}}</li>
38. Directives & Partials
• Directives are tags that allow you to create angular components. Directives can be
reused thought out your app.
• You need to specify how you want to register a directive Attribute or Tag:
<span my-directive=””></span> or <my-directive></my-directive>
• Key components of a directive include :
–HTML template / Partial : specify how you want to display data
–Scope : Specify which pieces of data you need
–Link Function : specify how you want to interact with the component.
• On your page now simply reference the directive and pass in the data
<span my-directive=”” data-item=”dataitem”></span>
Front End
39. An Example
1. Use Attribute to get directive &
replace original tag
Front End
1. Allow dataItem to be passed in.
NOTE you use data-item=”” in the
HTML.
1. Template as HTML
1. Create a link function with new scope
and allow access to the HTML
element and attributes. Great for
adding on-click events, jquery etc
myapp.directive(‘myDirective’, function() {
return {
restrict: 'A',
replace: true,
scope: {
dataItem:’=’
},
template:
'<span>{{dataItem.name}}</span>',
link: function (scope, element, attr){
scope.dataitem2 = ‘ABCD’
scope.resetValue = function(){
scope.dataItem = scope.dataitem2
}
element.bind(‘click’,
scope.resetValue);
}
};