Salesforce Platform Workshop, Winter '15: @salesforcedocs
Salesforce Platform Workshop, Winter '15: @salesforcedocs
com Workbook
Salesforce Platform Workshop, Winter ’15
@salesforcedocs
Last updated: December 8, 2014
© Copyright 2000–2014 salesforce.com, inc. All rights reserved. Salesforce is a registered trademark of salesforce.com, inc.,
as are other names and marks. Other marks appearing herein may be trademarks of their respective owners.
CONTENTS
This workbook shows you how to create a cloud app in a series of tutorials. While you can use the Salesforce platform to build virtually
any kind of app, most apps share certain characteristics, such as:
• A database to model the information in the app
• A user interface to expose data and functionality to those logged into your app
• Business logic and workflow to carry out particular tasks under certain conditions
In addition, apps developed on the Salesforce Platform automatically support:
• A public website and mobile apps to allow access to data and functionality
• A native social environment that allows you to interact with people or data
• Built-in security for protecting data and defining access across your organization
• Multiple APIs to integrate with external systems
• The ability to install or create packaged apps
The workbook tutorials are centered around building a very simple warehouse management system. Your warehouse contains computer
hardware and peripherals: laptops, desktops, tablets, monitors, that kind of thing. To keep track of how merchandise moves out of the
warehouse, you use an invoice. An invoice is a list of line items. Each line item has a particular piece of merchandise, and the number of
items ordered. The invoice rolls up all the prices and quantities for an invoice total. It’s a very simple data model, but just enough to
illustrate the basic concepts.
Development proceeds from the bottom up; that is, you first build an app and database model for keeping track of merchandise. You
continue by modifying the user interface, adding business logic, etc. Each of the tutorials builds on the previous tutorial to advance the
app’s development and simultaneously help you learn about the platform.
Audience
These tutorials are intended for developers new to the Salesforce platform and for Salesforce admins who want to delve more deeply
into app development.
Version
You should be able to successfully complete all procedures using the Summer ’14 version of Salesforce.
1
About the Workbook Supported Browsers
Supported Browsers
Browser Comments
Microsoft® Internet Explorer® versions 7, 8, 9, 10, If you use Internet Explorer, we recommend using the latest version that Salesforce
and 11 supports. Apply all Microsoft software updates. Note these restrictions.
• The full Salesforce site is not supported in Internet Explorer on touch-enabled
devices for Windows. Use the Salesforce1 mobile browser app instead.
• The Salesforce1 Setup page and the Salesforce1 Wizard require Internet Explorer
9 or later.
• The HTML solution editor in Internet Explorer 11 is not supported in Salesforce
Knowledge.
• The Compatibility View feature in Internet Explorer isn’t supported.
• The Metro version of Internet Explorer 10 isn’t supported.
• Internet Explorer 6 and 7 aren’t supported for login hints for multiple accounts.
• Internet Explorer 7 and 8 aren’t supported for the Developer Console or the
Data Import Wizard.
• Internet Explorer 7 isn’t supported for Open CTI.
• Internet Explorer 7 and 11 aren’t supported for Salesforce CRM Call Center built
with CTI Toolkit version 4.0 or higher.
• Internet Explorer 7 isn’t supported for Force.com Canvas.
• Internet Explorer 7 isn’t supported for Salesforce console features that require
more advanced browser performance and recent Web technologies. The console
features not available in Internet Explorer 7 include:
– The Most Recent Tabs component
– Multiple custom console components on sidebars
– Vertical auto-sizing for stacked console components in sidebars
– Font and font color for console components’ Button CSS
– Multi-monitor components
– The resizable highlights panel
– The full-width feed option on feed-based page layouts
2
About the Workbook Can I Use My Tablet or Phone?
Browser Comments
Mozilla® Firefox®, most recent stable version Salesforce makes every effort to test and support the most recent version of Firefox.
• Mozilla Firefox is supported for desktop users only for Community Templates
for Self-Service.
For configuration recommendations, see “Configuring Firefox” in the Salesforce
Help.
Google Chrome™, most recent stable version Google Chrome applies updates automatically; Salesforce makes every effort to test
and support the most recent version. There are no configuration recommendations
for Chrome. Chrome isn’t supported for the Add Google Doc to Salesforce browser
button or the Console tab (the Salesforce console is supported).
Apple® Safari® versions 5.x and 6.x on Mac OS X There are no configuration recommendations for Safari. Apple Safari on iOS isn’t
supported for the full Salesforce site.
• Safari isn’t supported for the Salesforce console.
• Safari isn’t supported for Salesforce CRM Call Center built with CTI Toolkit versions
below 4.0.
• Safari isn’t supported for Salesforce Analytics Cloud.
3
About the Workbook Optional: Install the Warehouse App
Note: If you installed the package by mistake or you want to delete it, click Setup > Installed Packages, and delete the package.
4
CREATE AN APP AND DATABASE
5
Create an App and Database Step 1: Build a Cloud App and Database
5. Click Create and you see right away some of the functionality that’s automatically added.
6
Create an App and Database Step 2: Try Out the App
1. Force.com app menu—Shows the apps that are available to you. The app you just created is selected.
2. Tabs—Provide an easy way to find and organize objects and records. In the Merchandise tab, which is open, you can create, view,
and edit records. The other tabs are the standard feature tabs that are included with every app.
3. Create records—Click New to add records to your custom object. If you click this button now, you see only one data entry field in
the object, but you’ll create more later.
4. Force.com Quick Access menu—Quickly jump to relevant app customization features. The menu is available from any object list
view page and record detail page, but only for users with the “Customize Application” permission.
Tell Me More....
An app is composed of tabs, but the tabs don’t have to be related to each other. In fact, you can modify custom apps to group all of
your most frequently used tabs together in one place. For example, if you refer to the Accounts tab a lot, you can add that to the
Warehouse app. You can switch between apps you created, bought, or installed by selecting them from the menu.
7
Create an App and Database Step 3: Explore the App
1. Every app has full-text search functionality for all text fields of an object and Chatter feeds.
2. Every object in Salesforce automatically has an attached "feed," called Chatter, that lets authorized app users socialize about and
collaborate on the object. Using Chatter, users can post updates in an object’s feed, comment on posts, and follow (subscribe to)
8
Create an App and Database Access the App from a Mobile Device
the feed to get pushed updates when they happen. For example, on a Merchandise record, one user might post a question about
the record, to which followers and other users can comment in reply.
3. Every DE org has a recycle bin that you can use to view and restore deleted records.
4. Every record in Salesforce has an "owner," which serves as the basis for a powerful security system that supports ownership-based
record sharing.
5. You can also manage activities related to a record from the Open Activities and Activity History related lists. Activities include tasks
to perform (making phone calls or sending email), calendar events, and requested meetings.
6. Every DE org has a Chat window that lets users interact with one another.
9
Create an App and Database Step 2: Try Out the Mobile App
• To use the downloadable app, use your mobile device’s browser to go to www.salesforce.com/mobile, select the
appropriate platform, and download Salesforce1.
• To enable the mobile browser app, from Setup click Mobile Administration > Salesforce1 > Settings, and then Enable the
Salesforce mobile browser app. Now, when you navigate to login.salesforce.com from your mobile browser,
Salesforce will recognize that you’re working from a mobile device and redirect you to the Salesforce1 mobile browser app.
Tell Me More....
The downloadable mobile app is usually preferable because the following features aren’t supported in the mobile browser app.
• Today helps users plan for and manage their day by integrating calendar events from their mobile device with their Salesforce tasks,
contacts, and accounts.
• Push notifications alert users to important things when they aren’t using the app.
3. Enter some text like First post!, and then tap Share.
4. Tap in the left corner to open the navigation menu.
5. Scroll down and tap More.
10
Create an App and Database Step 3: Explore the Mobile App
6. Tap Merchandise.
7. You can easily create a new piece of merchandise from the mobile device. Tap New.
8. Name it E–reader, and then tap Save.
Tell Me More....
You probably noticed that unlike the full Salesforce site, there isn’t a Home tab, and there doesn’t appear to be a Warehouse app.
Additionally, it took some effort to find the Merchandise tab. Why is that?
• Each tab is represented through a menu item in the Recent section of the Salesforce1 navigation menu. Since your app’s Merchandise
tab is new, it doesn’t appear on the Recent section yet until you start using it. After you’ve used the app a bit, the default tabs
(account, case, etc.) are replaced by the tabs you use most frequently.
• Salesforce apps, such as the Sales app or a your custom Warehouse app, don’t appear in Salesforce1, because the mobile app figures
out which records you look at most often. Rather than using the Force.com app menu to customize the tabs a user sees regularly,
the smart search items under the Recent section reorder based on the user’s history of recent objects.
• Don’t get the idea that the layout and navigation are entirely dynamic. You can customize the fields, actions, apps, and the navigation
of virtually the entire mobile app. You’ll get into that in later tutorials.
11
Create an App and Database Step 3: Explore the Mobile App
1. You should still be on the detail page for your new merchandise item. You can Edit, Clone, or Delete this record from its detail page.
2. Swipe left and you’ll see there’s a page for activities related to this item. This is the related information page.
3. Swipe right from the detail view and you’ll see there’s a blank page for the feed. There will be feed items here just as soon as you
make some changes.
4. Tap from the action bar at the bottom of the page, and then notice the list of icons that represent actions. This area is called
the action menu.
5. Try out an action by tapping Post.
6. Enter some text, such as Adding an e-reader to inventory and then tap Share. You can automatically see the post
you created in the feed for the e-reader. Anyone who follows that item will get updates for it.
7. Tap , and this time tap New Task.
8. In Subject, type Enter a price, and for Due Date, tap the calendar and choose Today.
9. Tap Submit.
10. From the detail page, swipe left and tap Open Activities, and you’ll see the task you created for yourself.
As you can see, you get the same functionality from the mobile app as you do in the full site—just the controls and navigation are
different.
Tell Me More....
• In the related information page you saw activities listed, and you might be wondering if you can add other related things. Yes! You
can add notes, attachments, Visualforce pages, and mobile cards to this page, which you’ll get to later.
• You saw a number of things you can do from the action bar, such as create a post, log a call, create a case, and so on. Of course you
can add and remove items from the tray and rearrange the order. This is all done in the page layout editor and is covered in later
lessons.
12
Create an App and Database Add Fields to an Object
13
Create an App and Database Step 2: Add the Quantity Field to the Merchandise Object
• Decimal Places: 2
• Select the Required checkbox
c. Leave the defaults for the remaining fields, and click Next.
d. Click Next again to accept the default field visibility and security settings.
e. Click Save & New to save the Price field and to return to the first step of the wizard.
3. Leave the defaults for the remaining fields, and click Next and Next again.
4. Click Save.
Take a look at this image to familiarize yourself with the Merchandise custom object.
1. Merchandise detail page—Shows you everything you need to know about your Merchandise custom object. Soon you’ll add
relationships, validation rules, and other neat features to this object.
14
Create an App and Database Step 3: Try Out the App
2. API name—When you created the Merchandise object, you didn’t specify an API name, but one was generated for you. This name
is how the object is referenced programmatically. All custom objects end in __c, which differentiates them from standard objects.
3. Standard fields—Some fields are generated automatically; these are standard fields. For example, the Merchandise object has a
standard field for Owner, which means it automatically tracks who created each record.
4. Custom fields—Includes the fields you just created in this step. Like custom objects, custom fields have API names that end in
__c.
Tell Me More....
• The custom fields you created so far are nothing fancy, but you can do fancy! The platform has support for nearly any type of data
you want to track, such as currency, email, geolocation, URLs, date/time, and so on. Fields don't just contain static values, they can
be derived from formulas, or take their values from other objects.
• Why do you need an API name as well as the object and field label? A label is what the user sees, so it should be easy to read and
may contain spaces. The API name is used internally in code, and can’t contain spaces or illegal characters. For example, a field
labeled “Customer ph# :” would be named Customer_ph in the code (the system replaces spaces with underscores and removes
the # and : characters).
15
Create an App and Database Create a New Object
5. If you created the E-reader item in the mobile tutorial, edit that item in a similar manner. If not, create a new Merchandise record
called E-reader with the following field values.
• Price: 100
• Quantity: 1500
6. Click Save & New and create a merchandise record for Desktop with these attributes.
• Price: 1000
• Quantity: 500
7. Click Save & New, and create a merchandise record for Tablet with these attributes.
• Price: 300
• Quantity: 5000
8. Click Save.
Tell Me More....
Take a close look at one of your merchandise records. Notice the Owner, CreatedBy, and LastModifiedBy fields. These are
standard fields which the platform automatically manages. Users have the ability to edit the Name standard field, along with the custom
fields Price and Quantity.
Also take a look at the Recent Items in the sidebar. This handy feature lets you view and navigate to the most recently changed records
in your database. The linked names in this sidebar come from each object’s Name field.
16
Create an App and Database Step 1: Create the Invoice Object Using the Wizard
4. In the Optional Features section, select Allow Reports (in case you create reports later).
5. Select Launch New Custom Tab Wizard after saving this custom object.
17
Create an App and Database Step 2: Add an Invoice Tab to the App
6. Click Save.
Tell Me More....
• The checkbox for vowel sounds ensures that the correct article is used: “a” or “an.”
• The Auto Number data type tells the platform to automatically assign a number to each new record that is created, beginning with
the starting number you specify. Because of the display format you chose, the invoice numbers will be INV-0000, INV-0001, and so
on.
• You could have started invoices at any number, but we started invoices at INV-0000 to remind you that the platform is zero-based.
18
Create an App and Database Step 3: Reorder Tabs in the App
19
Create an App and Database Step 5: Try Out the App
5. Leave the defaults for the remaining fields and click Next, Next, and Save.
Tell Me More....
Before moving on to the next step, recall the Help text you added to the Status field. When users hover their pointer over the Status
field, a pop-up bubble appears with whatever help text you specify. Although it’s beyond the scope of this tutorial, understand that you
can easily create unique translations for app labels and help text so that the app supports multiple languages, again, without writing a
single line of code. Very cool.
20
Create an App and Database Relate Objects
3. Click Save.
4. Click the Invoices tab again and notice there’s a new invoice, with the number INV-0000. Create another new invoice, this time with
a Closed status.
5. Click the Invoices tab again and see your two invoices.
The database is starting to look better, but it’s still incomplete. An invoice is made up of line items that list the type and quantity of
merchandise being ordered. In the next tutorial, you’ll add another object—Line Items—and then relate that object to the other ones
we’ve created.
Tell Me More....
• You only have a few records so far, but how would the page look if you had hundreds of records? Thankfully, the default list view
for a tab shows you only the most recent records you touched and lets you page through sets with standard navigation controls.
• Another built-in feature is list views. A list view is a customized presentation of data that shows only the fields you want, based on
filters you define. For example, suppose you’re only interested in open invoices with a price greater than $1000. You can create a
custom list view that shows exactly those records. This is covered in a later tutorial.
Relate Objects
Level: Beginner; Duration: 10–15 minutes
In previous tutorials you created objects that stood on their own. The fields on the Merchandise object had no relation to the fields on
the Invoice object. In this tutorial, you create a Line Item object, and what’s special about this new object is that its fields are related to
both the Invoice and Merchandise objects.
• An invoice has one or more line items. In fact, you might say that a particular invoice “owns” its line items. That kind of relationship
is called a master-detail relationship, where the detail records refer to a master record.
• Line items also relate to merchandise through another kind of relationship called a lookup. You already saw something similar in the
Status field. When you create a new invoice, you can choose a status from the picklist. A lookup field is different because the
values come dynamically from a custom object rather than statically from a picklist.
Master-detail relationships and lookups might seem confusing now, but once you implement them, it will all be very clear.
21
Create an App and Database Step 1: Create the Line Item Object
22
Create an App and Database Step 2: Add a Quantity Field
3. In the Optional Features section, select Allow Reports, and click Save.
Tell Me More....
You might be wondering why Line Item Number is a text field, when what you enter is a number. If line items are numbered, why not
make it an auto-number field, like Invoice? The short answer is that it’s easier to work with text when working with records, and this
tutorial is intended to be easy.
4. Leave the defaults for the remaining fields, and click Next, Next, and then Save.
23
Create an App and Database Step 3: Relate Line Items to Invoice
Tell Me More....
One way to think of this master-detail relationship is that an invoice now “owns” its line items. In other words, an invoice can now contain
multiple line items. One of the neat things about master-detail relationships is that they support roll-up summary fields, allowing you
to aggregate information about the child records. You’ll use that feature in a later tutorial.
5. Accept the defaults on the subsequent screens by clicking Next, and Next again.
24
Create an App and Database Step 5: Try Out the App
6. On the final screen, deselect the checkboxes for Merchandise Layout and Append related list to users’
existing personal customizations (you don’t want a list of line items on the Merchandise page).
7. Click Save.
Tell Me More....
At this point you have two relationships, a master-detail relationship that allows an invoice record to contain many line items, and a
lookup relationship that relates a particular line item to a piece of merchandise.
Tell Me More....
If you’re familiar with the products in your inventory, you can type the first few letters of a piece of merchandise and click Save. You
don’t need to click the Find icon, the system automatically finds the merchandise and adds it when you save the record. There’s a lot of
built-in functionality!
25
Create an App and Database Step 6: View the Schema
The Schema Builder shows your objects, fields, and relationships in a standard entity-relationship diagram. In a relationship, the “crows
feet” at the end of the line tell you which side is the “many” side of a one-to-many relationship (one invoice can contain multiple line
items). When you’re done looking at the schema, click Close.
Note: Schema Builder isn't just for viewing your schema, it also supports drag-and-drop development for creating new objects
and fields. However, unlike the wizards you used so far, fields added using Schema Builder are not automatically added to page
layouts. You must configure page layouts before your new fields are visible to users. Field visibility and page layouts are covered
in subsequent tutorials.
Summary
At this point, you have created three custom objects: Merchandise, Invoice, and Line Item. On each of those objects you created custom
fields to represent text, numbers, and currency. Two of these fields have system-generated values: the Status picklist, which defaults
to Open, and the Invoice Number field, which is automatically assigned by the Auto-number data type. You also created user-defined
fields, such as the Quantity entered for each line item. Finally, you expanded on the basic data model by creating two fields that
get their values from other objects; these are the relationship fields you created in this tutorial.
The master-detail relationship allows you to aggregate information, so that an invoice can contain multiple line items, and those line
items can be aggregated. The lookup relationship allows you to pull in dynamic content, so that each piece of merchandise on a line
item automatically gets a price. The relationships also provide additional benefits. You can add up the price of each invoice line item
26
Create an App and Database Load Data Using the Custom Object Import Wizard
and create a sum total for the invoice, and you can navigate to the related records in a user interface. You’ll learn how to do those things
declaratively in the next tutorial, and later in code as well. Onward!
Prerequisites
Text Editor
This tutorial requires a text editor and the ability to upload a file from your computer. If you’re using a tablet or mobile device, you
may not be able to complete this tutorial depending on the capability of the device.
Tell Me More....
Note that in the CSV file:
27
Create an App and Database Step 2: Load the Data
• The field names are on the first line. These names match the labels for fields in the Merchandise object.
• Text fields are delimited by quotes, allowing you to include spaces and special characters inside a text field. Fields that have a number
data type don’t require quotes.
28
Create an App and Database Step 3: Try Out the App
Tell Me More....
Once you finish the wizard, the platform queues the data load. For large sets of data, it may take a while for the data load to happen,
and you’ll be notified by email when the data load completes. If you want to monitor this process more closely, in Setup, click Imports.
29
CUSTOMIZE A USER INTERFACE
2. Click Go! to switch from the Recent Invoices view and display a list of All invoices.
Notice how the All view sorts records alphabetically and provides navigation controls for large lists.
30
Customize a User Interface Step 2: Create a New View
Tell Me More....
Right out of the box, you have several pre–built views that list invoices, with navigation and sorting. But what if you need a custom view?
Let’s say you want to see only closed invoices. No problem.
2. Select All Invoices, and specify a filter criteria: Status equals Closed.
3. A custom view shows only the fields you select. Update the Selected Fields list with only Invoice Number, Status, and
Last Modified Date.
31
Customize a User Interface Step 3: Try Out the App
Tell Me More....
Notice that you restricted the visibility of this view. That's a really important feature because you can create views of data for everyone
in your company, groups of people, or a view that only you can see.
32
Customize a User Interface Modify a Page Layout
Tell Me More....
At this point, you might think that views are read-only displays of data for a custom object—not so. In the new Closed Invoices view,
move over the Status field for a specific invoice. Notice that a pencil icon appears in the field, indicating that the field is editable
inline, right from the view. Double-click the Status field and the app provides you a way to edit the field.
33
Customize a User Interface Step 1: Open the Page Layout Editor
This tutorial teaches you more about page layouts and how to modify them.
• From Setup, click Create > Objects, click the object you want to change the layout of, scroll down to the Page Layouts section, and
then click Edit next to the layout you want edit.
34
Customize a User Interface Step 2: Understand a Page Layout
In the page layout itself, notice that there are several sections that organize related information.
• The Highlights Panel is useful for displaying key information at the top of the page.
• The Publisher Actions section is useful for customizing the actions that appear in the publisher.
35
Customize a User Interface Step 3: Rearrange Fields on a Page Layout
• At the top of the Invoice Detail, notice the area for standard buttons (Edit, Delete, etc.) and custom buttons.
• Next comes the Invoice Detail, which has three default sections.
– Information typically contains fields that users can manipulate at some point during the lifecycle of a record (creation and
updates). By default, this section has two columns for fields.
– System Information typically contains fields that the platform automatically maintains—fields that users cannot edit. This section
is also a two-column layout.
– Custom Links typically contains custom navigation links.
• Below Invoice Detail is a section for Mobile Cards. By default, this section is empty, but it’s important to know that mobile cards only
appear in Salesforce1.
• Last on the page is a related list for related Line Items.
You can make many changes to the page layout.
1. Hover over a section title. The mouse pointer changes, indicating that you can drag the section to a new location relative to other
sections.
2. Hover over the upper-right corner of any section. Two buttons appear: one for removing the section (don't click it!) and another for
editing its properties. Go ahead and click . You can now edit the name of the section (only for non-default sections), when to
display the section header, the section layout (one or two columns), and the tab-key order among section fields. Click Cancel.
36
Customize a User Interface Step 4: Add Fields to the Related List
2. That's it—you're done modifying the page layout. At the top of the page, in the toolbox, click Save.
37
Customize a User Interface Step 6: Edit a Mini Page Layout
38
Customize a User Interface Customize a Layout for Mobile Access
Note: There’s another kind of mobile layout called a global publisher layout, which determines where global actions go. You’ll
learn about that layout when you create global actions in Quickly Create Records Using Global Actions on page 96.
39
Customize a User Interface Step 1: Create a Page Layout for Mobile Users
8. Click Save and then No when asked if you want to override users’ customized related lists.
9. Now you need to assign the mobile-optimized page layout to a user profile. Click Page Layout Assignment and then Edit
Assignment.
10. Click System Administrator.
11. In the Page Layout to Use drop-down list, select Account Mobile Layout, and then click Save.
12. Now when you access the Account object, you’ll do so through the mobile-optimized layout. Try it now by going to Salesforce1 and
tapping Accounts in the navigation menu.
Since you just accessed the Burlington Textiles Corp of America account from the full site, you should see that in the Recent Accounts
list.
40
Customize a User Interface Step 2: Display Key Fields Using Compact Layouts
Tell Me More....
Normally, after creating a page layout for mobile users, you’d add it to a mobile user’s profile. To keep things simple (so that you don’t
have to log out and switch users), you simply added the page layout to your own profile instead.
Tell Me More....
• In this exercise you only used three fields, but the first four fields you assign to your compact layout populate the record highlights
section at the top of each record view.
• You don’t need to create compact layouts for Salesforce1. If you don’t create them, records display using a read-only, default compact
layout. After you create a custom compact layout you can replace the default with your new layout.
• Compact layouts aren’t just for mobile. When accessing Salesforce from a desktop browser, compact layouts determine which fields
appear when a feed item is created.
41
Customize a User Interface Step 3: Add Mobile Cards to the Related Information Page
Tell Me More....
• You don’t have any Visualforce pages yet, but once you’ve enabled one for mobile, you can add those pages to the Mobile Cards
section like you just did.
• You can also use the Mobile Cards section to add elements from the Components category. That category doesn’t appear in this
tutorial, because no components are available on custom objects.
• Unlike compact layouts, mobile cards only appear in Salesforce1.
42
Customize a User Interface Enable Social Collaboration
43
Customize a User Interface Step 2: Enable Collaboration on Invoices
44
Customize a User Interface Step 3: Try Out the App
3. Notice two fields are being tracked for Merchandise. Take a look at your Invoice object, and notice no fields are being tracked.
4. To enable feed tracking for Invoice, click Invoice, select Enable Feed Tracking, select Status, and click Save.
45
Customize a User Interface Step 4: Enable Notifications for Mobile
Tell Me More....
This tutorial only touches on Chatter, focusing on the feeds for a custom object. From the app menu in the upper right, select Salesforce
Chatter to see a feed-centric view of data in your organization. The Chatter app lets you securely collaborate with other users in your
organization—kind of like a private, secure Facebook just for you and your coworkers.
46
Customize a User Interface Step 4: Enable Notifications for Mobile
4. Click Save. If you checked the box to include full content in push notifications, a pop-up appears displaying terms and conditions.
Click OK or Cancel. By enabling this option, you’re agreeing to the terms and conditions on behalf of your company. For details, see
Salesforce1 Notifications Overview in the Salesforce help.
Now when someone mentions you in a post or comments on a post you created, you’ll get a notification on your device, even when
your Salesforce1 downloadable app isn’t running! You can’t see any notifications yet, because you need to create another user to make
some updates. You’ll do that in a later lesson.
47
ADD APP LOGIC WITH CLICKS, NOT CODE
48
Add App Logic with Clicks, Not Code Step 2: Create a Unit Price Field
In this tutorial, you create a new field for the Line Item object called Unit Price. You don’t want users creating their own price, and
since the price is already stored in the Merchandise object, you can populate this field automatically using a neat feature called a workflow
rule.
4. Leave the defaults for the remaining fields by clicking Next on subsequent screens until you can Save.
5. Now go back to an existing Invoice and add a new Line Item. Notice there's a new field for Unit Price, but you have to populate
that field manually. You want this field to populate automatically, so click Cancel, and add this new functionality.
49
Add App Logic with Clicks, Not Code Step 3: Automatically Populate the Unit Price Field
6. In the first rule criteria row, for the field select Line Item: Quantity, for the operator select greater or equal, and
for the value enter 1.
7. Click Save & Next.
Note: It makes sense to fire this workflow rule only for new line item records because you are effectively assigning a default
field value when creating a new record. Later on, users might need to adjust the price of merchandise in each line item (for
example, to offer discounts).
Continuing on, the next step is to assign an action to the workflow rule to update the Unit Price field automatically.
1. Click the drop-down list that reads Add Workflow Action and choose New Field Update.
2. In the Name field, enter Copy Unit Price.
3. In the Field to Update list, choose Line Item and then Unit Price.
4. Select the option to use a formula to set the new value. Before continuing, confirm that your screen matches the following.
50
Add App Logic with Clicks, Not Code Step 3: Automatically Populate the Unit Price Field
8. Click Save, and then click Done to return to the detail page of the new workflow rule.
Tell Me More...
In the formula, notice some new syntax, namely "Merchandise__r". You’ve seen __c used already, so what’s with the __r? That’s
the platform’s object notation for a field that’s related to another object. You can use related fields to traverse object relationships and
access related fields. In this case, the formula uses the relationship between the Line Item record and Merchandise object to get the
corresponding Merchandise record's value for Price.
51
Add App Logic with Clicks, Not Code Step 4: Update Total Inventory When an Order is Placed
52
Add App Logic with Clicks, Not Code Step 6: Try Out the App
1. In Setup click Workflow & Approvals > Workflow Rules to get to the All Workflow Rules page.
2. Next to Line Item Updated and Populate Unit Price, you’ll see an Activate link. Click the link next to each workflow rule.
Tell Me More...
Workflow rules are not activated by default because you might turn off workflow rules when running bulk processes. For example, you
might want to update a whole bunch of records at the same time, and firing the workflow rule each time wouldn’t invalidate your
processes. Workflow rules can also do things like send email updates, and you might not want to send thousands of emails when you’re
doing a simple price change.
53
Add App Logic with Clicks, Not Code Step 2: Try Out the App
6. Click the Insert Merge Field drop-down list, and choose Unit Price. You should now see Unit_Price__c in the text box.
7. Click the Insert Operator drop-down list and choose Multiply.
8. In the Insert Merge Field drop-down list, select Quantity. You should now see Unit_Price__c * Quantity__c in the
text box.
Tell Me More....
The Formula field type is great for automatically deriving field values from other values, as you have done here. The formula you entered
was quite straightforward: a simple multiplication of two field values on the same record. There's also an Advanced Formula tab, which
allows you to do much more with these formulas.
54
Add App Logic with Clicks, Not Code Add a Roll-Up Summary Field
2. Add a new line item, select a piece of merchandise, and enter a quantity.
3. Save the line item and you can see the formula field in action.
55
Add App Logic with Clicks, Not Code Step 2: Try Out the App
56
Add App Logic with Clicks, Not Code Step 2: Create a Validation Rule
5. Click Check Syntax to make sure there are no errors. If you do find errors, fix them before proceeding.
57
Add App Logic with Clicks, Not Code Step 2: Create a Validation Rule
6. In the Error Message field, type You must order at least one item.
7. For the Error Location, select Field, then choose Quantity from the drop-down list.
8. Click Save.
Tell Me More....
Take a quick look at the Validation Rule Detail page. Notice that the new validation rule is “Active” meaning that the platform is currently
enforcing the rule. Validation rules, unlike workflow rules, default to active. In certain situations, you might want to deactivate the rule
temporarily (for example, before loading a bunch of data). This is easy to do by simply deselecting the Active box (but don’t do this
now).
58
Add App Logic with Clicks, Not Code Step 3: Try Out the App
Tell Me More....
• If you didn’t see the error message, check the validation formula again. You need to make the rule fire when the condition evaluates
to TRUE.
• The formula in this tutorial is rather simple, but don’t let that fool you. The platform’s formula syntax empowers you to enforce a
wide range of business rules that not only includes one object, but pulls in other related objects as well.
4. Click between the second set of parentheses, then click Insert Field to open the Insert Field popup window.
5. Leave Line Item > selected in the first column, select Quantity in the second column, and then click Insert.
6. Type or insert the greater-than symbol (>).
7. Click Insert Field and select Line Item > in the first column, Merchandise > in the second column, and Quantity
in the third column.
59
Add App Logic with Clicks, Not Code Step 5: Try Out the New Rule
8. Click Insert and verify the code looks like the following:
(Quantity__c <= 0) || (Quantity__c > Merchandise__r.Quantity__c)
Tell Me More....
Take a look at the formula you created.
• Mechandise__r—Because the Merchandise object is related to the Line Item object, the platform lets you navigate from a line
item record to a merchandise record; that's what the Mechandise__r is doing.
• Quantity__c—This is the field you created to track the total amount of stock on a merchandise record.
• Merchandise__r.Quantity__c—This tells the system to retrieve the value of Quantity field on the related merchandise
record.
• Quantity__c—This refers to the Quantity field on the current (line item) record.
Putting it all together, the formula checks that the total inventory on the related merchandise record is less than the number of units
being sold. As indicated on the Error Condition Formula page, you need to provide a formula that is true if an error should be displayed,
and this is just what you want: it will only be true when the total inventory is less than the units sold.
Tell Me More....
• Validation rules and formulas combine to create really powerful business logic, with very little development effort.
• For a list of sample validation rules, make sure to read “Examples of Validation Rules” in the Salesforce Help:
https://help.salesforce.com/HTViewHelpDoc?id=fields_useful_field_validation_formulas.htm.
60
Add App Logic with Clicks, Not Code Step 1: Create an Approval Process
61
Add App Logic with Clicks, Not Code Step 2: Examine the Approval Process Detail Page
9. Now you need to assign the approval to someone. For large companies where multiple people could have the ability to grant
approval, you might assign this to a queue. In DE orgs there are only two users, so click the option for Automatically assign
to approvers and choose Admin User. (If you’ve edited your profile, this will be your name, note that you may need to click
the lookup icon if you don't’s see your name listed.)
10. Make sure your screen looks like this and then Save your work.
11. Click OK in the pop-up, and then click View Approval Process Detail Page.
62
Add App Logic with Clicks, Not Code Step 3: Modify Approval Process Actions
63
Add App Logic with Clicks, Not Code Step 5: Try Out the App
Before you can see how the approval process works, you need to make sure that your users will be able to submit the relevant records
for approval. Otherwise, the approval process will never start! In this step, you add the Submit for Approval button to the Line Item page
layout.
1. From Setup, click Create > Objects, and click Line Item.
2. In the Page Layouts related list, click Edit next to Line Item Layout.
3. From the Buttons category in the palette, drag the Submit for Approval button to the Standard Buttons area.
4. Click Save.
Now all users assigned to this page layout will be able to submit line items for approval.
64
Add App Logic with Clicks, Not Code Step 6: Configure Approvals for Chatter and Salesforce1
Tell Me More....
Approval processes are automatically included on your Home tab. If you click the Home tab, you can see the items you need to approve
and reject right there.
Create a Flow
Note: Visual Workflow isn’t supported in Salesforce1.
65
Add App Logic with Clicks, Not Code Step 1: Add Flow Variables
Field Value
Unique Name vQuantityAvailable
Scale 0
c. Click OK.
Field Value
Unique Name vInvoiceId
Description ID of the invoice to which the flow adds the new line item. A
custom button on the Invoice detail page launches the flow and
passes the invoice ID into this variable.
c. Click OK.
66
Add App Logic with Clicks, Not Code Step 2: Add a Form Screen
c. Click OK.
Ignore any activation warnings for now.
2. For the Name, enter Get Line Item Info From User.
The Unique Name is automatically populated based on this entry.
Field Value
Label Line Item Number
The Unique Name is automatically populated based on this entry.
Default Value 1
67
Add App Logic with Clicks, Not Code Step 2: Add a Form Screen
Field Value
Label Merchandise
The Unique Name is automatically populated based on this entry.
d. In the Choice Settings section, click the drop-down arrow then CREATE NEW > Dynamic Choice.
5. Create the dynamic choice resource, which at runtime dynamically populates the Merchandise field with choice options, each of
which represents a Merchandise record in the database.
a. Enter the following values.
Field Value
Unique Name dcMerchandise
b. Set the filter criteria so that the dynamic choice returns only the merchandise that have items in stock.
Field Value
Field Quantity__c
68
Add App Logic with Clicks, Not Code Step 2: Add a Form Screen
Field Value
Value 0
c. Set the following fields so that the choices are displayed using the Name in each Merchandise record, sorted in alphabetical
order. Also, we want the choice to store the ID of the user-selected Merchandise record.
Field Value
Choice Label Name
d. Save the quantity in stock from the user-selected merchandise record to the flow variable we already created.
Field Value
Field Quantity__c
Variable {!vQuantityAvailable}
e. Click OK.
The Dynamic Choice overlay closes, and the Screen overlay appears.
Field Value
Label Quantity Ordered
The Unique Name is automatically populated based on this entry.
Scale 0
69
Add App Logic with Clicks, Not Code Step 3: Add a Record Create Element
Field Value
Label Unit Price
The Unique Name is automatically populated based on this entry.
Scale 2
The preview pane on the Screen overlay should now include four fields.
8. Click OK.
9. Save the flow.
a. Click Save.
b. Ignore the activation warnings for now.
c. Click OK.
70
Add App Logic with Clicks, Not Code Step 4: Add a Record Update Element
Field Value
Invoice__c {!vInvoiceId}
Merchandise__c {!Merchandise}
Name {!Line_Item_Number}
Quantity__c {!Quantity_Ordered}
Unit_Price__c {!Unit_Price}
5. Click OK.
The Screen and Record Create elements now appear on the canvas.
6. Connect the two elements by dragging the node at the bottom of the Screen element onto the Record Create element.
The node doesn’t move, but a connector line appears as you drag from one node to another element.
9. Click Save.
Notice that the activation warnings no longer appear because we set the start element and linked the elements together.
71
Add App Logic with Clicks, Not Code Step 4: Add a Record Update Element
Field Value
Field Id
Operator equals
Value {!Merchandise}
Field Value
Unique Name fDecrementAvailableStock
Scale 0
8. Click OK.
The Formula overlay closes, and the Record Update overlay appears.
72
Add App Logic with Clicks, Not Code Step 5: Add a Confirmation Screen
9. Click OK.
10. Drag the node from the bottom of the Record Create element onto the Record Update element to connect them.
11. Click Save.
Field Value
Unique Name confirmation_message
73
Add App Logic with Clicks, Not Code Step 5: Add a Confirmation Screen
6. Click OK.
7. Drag the node from the bottom of the Record Update element onto the new Screen element to connect them.
8. Click Save.
9. Click Close.
The flow detail page displays the flow URL. You’ll need this later when you create the custom button for launching this flow.
74
Add App Logic with Clicks, Not Code Step 6: Add a Custom Button
Field Value
Label Add Line Item and Update Stock Qty
The Name is automatically populated based on this entry.
75
Add App Logic with Clicks, Not Code Step 6: Add a Custom Button
d. Click Save.
e. Click OK.
76
Add App Logic with Clicks, Not Code Step 7: Try Out the App
g. Click OK.
3. Verify that the button appears in the preview area for the Line Items related list.
4. Click Save.
2. Click the Invoices tab and either create a new invoice or edit an existing one.
3. Click the Add Line Item and Update Stock Qty custom button you just created.
77
Add App Logic with Clicks, Not Code Step 7: Try Out the App
4. To see results on the invoice detail page, enter the following values for the line item.
Field Value
Line Item Number 11
Merchandise Desktop
Congratulations! You’ve successfully updated your inventory. But what happens if an error occurs? The standard behavior is for the flow
to email the organization administrator a generic message, but you can modify the flow to also immediately notify the user. This is
covered in the next, optional, tutorial.
78
Add App Logic with Clicks, Not Code Step 8: Add a Fault Screen
Field Value
Unique Name fault_message
7. Click OK.
8. Connect both the Record Create and Record Update elements to the fault screen.
a. Drag the node from the bottom of the Record Create element onto the new Screen element.
b. Drag the node from the bottom of the Record Update element onto the new Screen element.
Notice that these new connectors have “FAULT” labels.
79
Add App Logic with Clicks, Not Code Step 8: Add a Fault Screen
9. Click Save.
10. Click Close.
Now, if the flow encounters a validation rule or error, the flow user sees a meaningful error message instead of the generic unhandled
fault message.
If your flow is already working fine, you can still test the fault screen by entering a value that would fail the validation rule you created
in an earlier tutorial. Specifically, while running the flow, enter a Quantity Ordered value that’s obviously greater than the quantity
available for the merchandise.
80
ANALYZE DATA WITH REPORTS AND DASHBOARDS
Create a Report
Level: Beginner; Duration: 15 minutes
The Warehouse app you created with the App Quick Start wizard includes a Reports tab, where you can create, edit, run, and schedule
reports. Start by creating a simple report that tells you how much stock you have for each item in your warehouse. Then you’ll use
groupings and filters to get the most out of the data in your report.
Try out buckets for on-the-fly grouping, and experiment with showing your report data graphically as a chart. And once you’ve got charts
mastered, take a look at how you can provide users with valuable context by embedding charts in record detail pages.
81
Analyze Data with Reports and Dashboards Step 1: Create a Simple Report
5. Click Save, and give your report a meaningful name, such as Merchandise in Stock.
6. In the Report Folder drop-down list, select Unfiled Public Reports, so everyone can access it. (If you didn’t want this report to be
accessible to everyone, you’d create a folder and give different people different levels of access to it. More on that later.)
7. Click Save and Run Report.
That’s it. Your new report is ready to go!
You can get fancy with reports, but that's all you need from this one. And as you'll soon see, even this simple report gives you a lot of
functionality.
• Use the Summarize Information by drop-down list to summarize the report based on any field on the Merchandise object. For
example, you could summarize on Owner Name to see who entered each piece of merchandise, as well as the count.
• Use the Show drop-down list specify whether you want to see just your merchandise, your team's merchandise, or all merchandise.
82
Analyze Data with Reports and Dashboards Step 2: Get More Information Out of Your Report
• In the Time Frame section, you can choose to run this report based on the created, modified, or last activity date, as well as choose
the date range for the data you want to see.
• Click Run Report, and choose to run the report now or on some future date. If you choose the latter, it takes only a few more clicks
to have that report in your inbox every day—or however often you want it.
• If you’d rather see a summary than a bunch of details, click Hide Details.
• Click Customize to make changes to the report, and you'll return to the familiar drag-and-drop interface you used to create the
report.
• And finally, you can export the report as a printed document, spreadsheet, or CSV file by clicking Export Details.
Tell Me More....
• Click the column headers to toggle between ascending and descending order. The Grand Totals indicates the record count as well
as the summaries you chose. Click Customize to make additional changes to this report.
• You can click through to the data records that are being reported on, a characteristic found in all reports on Salesforce. For example,
click the name of any merchandise record listed in the report to view its detail page.
• A report folder's sharing settings determine who can do what with reports in that folder. Click next to the folder in the Reports
tab and click Share. You can give people three levels of access: Viewer, Editor, or Manager. For more information, see “Share a Report
or Dashboard Folder” in the Salesforce Help.
Tell Me More...
Try adding a cross filter from the Add drop-down list in the Filters pane. A cross filter lets you filter on the report's child objects using a
simple with or without condition. To learn more about cross filters, watch Using Cross Filters in Reports.
83
Analyze Data with Reports and Dashboards Step 3: Add Buckets to Your Report
First, create a bucket field based on Quantity with ranges for small, medium, and large. You'll use the bucket field to create the
grouping.
1. Click on Quantity and click Bucket this Field.
2. Enter a bucket field name, Quantity Range.
3. Define ranges as Small (500), Medium (between 500–1000), and Large (greater than 1000).
4. Click OK.
5. Grab the Quantity Range bucket field that's already on the report and make it the first-level grouping by dragging it onto the drop
zone above Merchandise Name.
Now the report shows data grouped in two levels—first, by quantity range (small, medium or large), and second, by merchandise name.
84
Analyze Data with Reports and Dashboards Step 4: Show Your Report Data as a Chart
Tell Me More....
You can filter a bucket field just like other fields in the report. For example, set a filter for Quantity Range not equal to
Small to see only merchandise with quantities in the medium or large range.
To learn more about bucket fields, watch Getting Started with Buckets.
85
Analyze Data with Reports and Dashboards Step 5: Embed the Report Chart in a Record Page
4. Drag the Section element onto the preview pane and place it above the Mobile Cards area. Enter Charts for the section name,
and select 1-column for the layout.
5. In the Quick Find box, type the name of the report and click to find and select the report chart. (You can add two if you want.)
You can browse up to 200 recently viewed reports. But you only see reports that already have charts.
6. Drag the Merchandise In Stock report chart onto the layout.
7. Click Save and go look at a merchandise record. It will look something like:
86
Analyze Data with Reports and Dashboards Create a Dashboard
Now users can quickly see how much merchandise is in stock, without leaving their record detail page! Notice that, by default, the chart
is automatically filtered to show data that’s relevant to the particular record type you’re looking at. You can set different filters back on
the page layout. Just click on the chart to customize it.
To learn more about embedding report charts on record pages, watch Embedding Charts Anywhere.
Tell Me More....
Salesforce provides a Reporting API that lets you access your data remotely and build your own apps and visualizations. There’s an API
resource for almost anything you can do with reports through the standard web interface. For example, say you’ve used Visualforce to
build a custom app, and you want to give that app a Reports tab. Or your users need a special kind of chart that isn’t one of the
out-of-the-box report builder options.
For a quick start on using the Salesforce1 Reporting REST API, see the Salesforce1 Reporting API API Developer Guide.
Create a Dashboard
Level: Beginner; Duration: 15 minutes
Dashboards in Salesforce are like a dashboard in your car, showing you important information at a glance. Dashboards can show data
in charts, gauges, tables, metrics, or Visualforce pages. Naturally, you can customize dashboards to show exactly what you want.
In this tutorial, you create a new dashboard that's powered by the report you created in the previous tutorial.
87
Analyze Data with Reports and Dashboards Step 1: Create a New Dashboard
3. Now click the editor's Data Sources tab, and under Reports > Unfiled Public Reports, drag your report and drop it on top of the
new Vertical Bar Chart component that's in the dashboard.
88
Analyze Data with Reports and Dashboards Step 3: Try Out the App
3. Click Save, name the dashboard Merchandise Overview, and click Save.
2. To access the dashboard at any time, click the Reports or Dashboard tab in the Warehouse app.
Tell Me More....
• When you set a running user for a dashboard, it runs using the security settings of that single, specific user. All users with access to
the dashboard see the same data, regardless of their own personal security settings. To set the running user, click next to the
View dashboard as field.
89
Analyze Data with Reports and Dashboards Step 4: Access Dashboards from Your Mobile App
• Dashboards can be updated either manually or on a schedule, and they can be delivered through email and mobile.
• A dashboard won't automatically refresh unless it is set to do so. Each time you view a dashboard, it indicates in the upper-right
corner when it was last refreshed. To update the data in the dashboard, click Refresh.
• Try adding a filter when editing the dashboard by clicking Add Filter. A filter lets you see different views of dashboard data based
on filter conditions. You can add up to three filters per dashboard with up to ten conditions on a filter. Instead of filtering at the
report level, you directly manipulate dashboard data.
90
Analyze Data with Reports and Dashboards Unleash Your Reports with the Salesforce1 Reporting REST
API
For example, say you’ve used Visualforce to build a custom app, and you want that app to display report data. Or your users need a
special kind of chart that isn’t one of the out-of-the-box options when they build a dashboard. In this tutorial, we’ll take a look at some
ways you might give your users what they want.
Note: This is just a brief overview to show you some of the cool kinds of things you can do with the Salesforce1 Reporting REST
API. For full instructions and a detailed reference, check out the Salesforce1 Reporting API Developer Guide.
To use the API, you have your app send a request to a URL that’s based on the instance where your Salesforce organization is running.
For example, if your organization is hosted on na1.salesforce.com, you could get a list of all the reports you have by sending
a request to https://na1.salesforce.com/analytics/reports.
Here are the basic operations you can undertake with the Salesforce1 Reporting REST API. We’ll be using some of these in the next few
steps.
91
Analyze Data with Reports and Dashboards Step 1: Run a Report Synchronously
Note: We’re using NA1 as the instance for this example. Substitute the instance where your Salesforce organization is hosted.
You've just run your first report via the API! Don't worry about reading the results yet. You'll get to that in the next few pages.
2. To get the results of your asynchronous run, poll the report run instance with GET.
A specific asynchronous run of a report is called an instance. Each instance has an ID. To get the data set that an instance contains,
you send a request to the system, identifying the instance you want by its ID. This is called polling the instance. If the report has
finished running, the response to your poll request is the data set you asked for. (If it’s not finished, you get an “in progress” response.)
curl -s -H 'Authorization: OAuth token ...'
https://na1.salesforce.com/services/data/v29.0/analytics/reports/00OD0000001ZbP7MAK/instances/instance_id
92
Analyze Data with Reports and Dashboards Step 3: Filter Report Data
Now we've run a report synchronously and asynchronously. Next, we'll make our data more useful by narrowing down our results.
2. Change the filter and run the report. It will look something like this, with the edited filter shown in bold type. (This example is
synchronous, but an asynchronous run works the same way.)
curl -s -H 'Authorization: OAuth token ...'
https://na1.salesforce.com/services/data/v29.0/analytics/reports/00OD0000001ZbP7MAK -X
POST -d '{reportMetadata":{"name":"MerchandiseReport","id":"00OD0000001ZbP7MAK",
"developerName":"MerchandiseReport","reportType":{"type":"CaseList","label":"Cases"},
"reportFormat":"MATRIX","reportBooleanFilter":null,"reportFilters":[{"column": "QUANTITY",
"operator":"lessThan", "value":"12"}],
"detailColumns":["MERCHANDISE.NAME","CREATED_DATE","QUANTITY"],
"currency":null,"aggregates":["RowCount"],"groupingsDown":[{"name":"CONTACT2.COUNTRY_CODE",
"sortOrder":"Asc","dateGranularity":"None"}],"groupingsAcross":[{"name":"OWNER",
"sortOrder":"Asc","dateGranularity":"None"}]}}'
You’ve just run a filtered report and retrieved the data. You’re ready to do some cool tricks with it! For some ideas, along with full
instructions and detailed reference information, check out the Salesforce1 Reporting REST API Developer Guide.
93
Analyze Data with Reports and Dashboards Step 4: Find, Show, and Refresh Dashboards
For each dashboard, the Dashboard List resource sends you back something like this. The URL handle stores the status or results for
the dashboard. The list is sorted by the date when the dashboard was last refreshed.
[ {
"id" : "01ZD00000007QeuMAE",
"name" : "Adoption Dashboard",
"statusUrl" : "/services/data/v31.0/analytics/dashboards/01ZD00000007QeuMAE/status",
"url" : "/services/data/v31.0/analytics/dashboards/01ZD00000007QeuMAE"
}]
2. You may want to show users their dashboard data in different ways, depending on the platform or device where they’re using your
app. You can pull the data from the dashboard with a GET request to the Dashboard Results resource.
/services/data/v31.0/analytics/dashboards/01ZD00000007S89MAE
What you get back is the actual data in the dashboard, plus its metadata (the dashboard ID, name, component metadata, and any
filters) and its refresh status. The result will look like this:
{
{
"componentData" : [ {
"componentId" : "01aD0000000a36LIAQ",
"reportResult" : {
// Report result data omitted for brevity.
},
"status" : {
"dataStatus" : "DATA",
"errorCode" : null,
"errorMessage" : null,
"errorSeverity" : null,
"refreshDate" : "2014-04-10T20:37:43.000+0000",
"refreshStatus" : "IDLE"
}
} ],
"dashboardMetadata" : {
"attributes" : {
"dashboardId" : "01ZD00000007S89MAE",
"dashboardName" : "Simple Dashboard",
"statusUrl" : "/services/data/v31.0/analytics/dashboards/01ZD00000007S89MAE/status",
"type" : "Dashboard"
},
"canChangeRunningUser" : false,
"components" : [ {
"componentData" : 0,
"footer" : null,
"header" : null,
"id" : "01aD0000000a36LIAQ",
"properties" : {
"aggregateName" : "s!AMOUNT",
"maxRows" : null,
"sort" : {
"column" : "TYPE",
"sortOrder" : "asc"
},
94
Analyze Data with Reports and Dashboards Step 4: Find, Show, and Refresh Dashboards
"visualizationProperties" : { },
"visualizationType" : "Bar"
},
"reportId" : "00OD0000001g2nWMAQ",
"title" : null,
"type" : "Report"
} ],
"description" : null,
"developerName" : "Simple_Dashboard",
"filters" : [ {
"name" : "Amount",
"options" : [ {
"alias" : null,
"endValue" : null,
"id" : "0ICD00000004CBiOAM",
"operation" : "greaterThan",
"startValue" : null,
"value" : "USD 2000000"
} ],
"selectedOption" : null
} ],
"id" : "01ZD00000007S89MAE",
"layout" : {
"columns" : [ {
"components" : [ 0 ]
} ]
},
"name" : "Simple Dashboard",
"runningUser" : {
"displayName" : "Allison Wheeler",
"id" : "005D00000016V2qIAE"
}
}
}
3. If you’re concerned that users might not be seeing the latest data, you can refresh a dashboard remotely by sending a PUT Dashboard
Results request, specifying the dashboard you want to refresh by its ID.
/services/data/v31.0/analytics/dashboards/01ZD00000007S89MAE
The response contains the status URL for the refreshed dashboard:
{
"statusUrl" : "/services/data/v31.0/analytics/dashboards/01ZD00000007S89MAE/status"
}
95
ENHANCE THE MOBILE EXPERIENCE WITH ACTIONS
96
Enhance the Mobile Experience with Actions Step 2: Customize the Global Layout
After saving, the action layout editor opens. Typically at this point you’d customize the fields that show up here, but there aren’t many
fields on this object, so it’s not necessary yet. Click Save.
Tell Me More....
• You created a custom label called New Merch, but you can also choose one of the generated labels by choosing from the Standard
Label Type drop-down list.
• At the bottom of the global action detail page, there’s a section for predefined values. If you predefine a required field, you don’t
need to display that field on the page. Predefining fields is also a great way to customize the mobile experience, and you’ll learn
about that in just a bit.
4. There’s a warning about the number of actions in the publisher. Remove some of the actions by dragging them to the palette. Click
Save.
5. Now try it out by opening Salesforce1. You’ll see the New Merch action in the action bar.
Tell Me More....
• In Salesforce1, global actions appear in the action bar on pages to which the global publisher layout applies: in the feed, in groups,
and in any layout that hasn’t been overridden by a more specific publisher layout.
• If you’d placed the New Merch action first in the list, anyone using the full Salesforce site would see the expanded list of fields for
that action every time they opened Chatter. That could be an annoying use of space! So it’s better to locate actions that require a
lot of fields somewhere further down the line.
• Just as you can with regular page layouts, you can assign global publisher layouts to different user profiles. This lets different types
of users have different global actions.
97
Enhance the Mobile Experience with Actions Create Related Records with Object-specific Actions
5. Remove the Status field from the layout by dragging it into the palette, and then click Save.
6. You get a warning message about a required field. Click Yes, because you’ll fix that next.
Tell Me More....
You just dragged a required field off the page layout. The platform gives you a warning message, and as well it should, users won’t be
able to create a case from the mobile action! The reason for removing that field will become clear in the next step, when you predefine
that field’s value.
98
Enhance the Mobile Experience with Actions Step 3: Customize an Object-specific Layout
Tell Me More....
Note that predefined values override default values. In the previous example, imagine that cases created on the full Salesforce site are
typically new, and so whenever a case is created there, the default value is set to “Open”. But when a new case is created from a mobile
device, it’s because there’s a mobile technician on site, and they are actually working on that case. New cases logged from the mobile
device overrides the default value and predefines it as “Working”. As you can see, not only do predefined field values free up screen
space, they can also be used to optimize for what people do when they are mobile.
3. In the Publisher Actions section, click override the global publisher layout.
4. Click the Actions category in the palette, then drag Create a Case so that it’s the second item in the list.
Notice there’s also a New Case item in the palette. The New Case item is a default action assigned to the Account object, but it’s
not editable. You don’t want this default action, because you created a custom Create a Case action.
5. Click Save. The new Create a Case action will now show up in the publisher on the Account detail page in the full site and in the
action bar on the Account record pages in Salesforce1 for all mobile technicians.
6. Now test it on your mobile device by navigating to an account.
7. On the detail page for an account, tap the Create a Case action.
You don’t see the required Status field for the case, but it’s there, and so is the association to this particular account.
Tell Me More....
When you create object-specific layouts, keep in mind that only the first four actions in the list appear on the action bar in Salesforce1.
The rest of the actions are accessible from the action menu when users tap in the action bar.
99
SECURE YOUR SYSTEM
Prerequisites
Browser Switching
This tutorial requires you to switch between users. To do that, it’s easier to leave one browser open as your admin/developer (the
login you’ve been using so far), and use a different browser for other users. For example, if you are using Safari for your admin/developer
login, use a different browser such as Mozilla Firefox for the Manager and Salesperson users. That way, you can simply switch between
different browsers to configure security and then test record access without having to log out and log in repeatedly. If you’re using
Google Chrome, you can also use Chrome incognito to log in as multiple users in the same browser.
100
Secure Your System Step 1: Create a Profile
Note: Before you get started creating profiles and permission sets, be aware that the available permissions you can configure for
a profile or permission set depend on the user license you associate with it.
Tell Me More....
The profile you clone is important to consider because it determines what type of user license to use. For example, in a DE org, you have
three Salesforce Platform User licenses that these tutorials intend to use.
101
Secure Your System Step 3: Create the Manager Permission Set
102
Secure Your System Step 4: Create the Salesperson Permission Set
1. From the Warehouse Salesperson permission set detail page, click Object Settings.
2. Click Invoices and then Edit.
3. In Tab Settings, enable Available and Visible.
4. In Object Permissions, enable these permissions: Read, Create, Edit, and Delete.
5. Click Save.
6. In the breadcrumb menu, click Object Settings.
7. Click Line Items.
8. Click Edit.
9. In Object Permissions, enable the following permissions: Read, Create, Edit, and Delete.
10. Click Save.
The Warehouse Salesperson permission set doesn’t give access to Merchandise, only Invoices and Line Items. You can see this on the
Object Settings page for the permission set.
103
Secure Your System Create New Users
4. Click Save.
Repeat the process to create a new that serves as a "salesperson," with the following exceptions:
• First Name: Sales
• Last Name: Person
• Email: enter your email address
• Username: your username.sales@your domain
• Nickname: your username.sales
• Role: Leave this field blank for now, you’ll assign roles later.
• User License: Salesforce Platform
• Profile: Warehouse App User
• At the very bottom, clear the checkboxes for the newsletters, but make sure Generate new password and notify
user immediately: is checked.
You now have two users, both using the Warehouse App User profile. Also, you should have two emails in your email inbox: activation
emails for each new user.
104
Secure Your System Step 2: Test Record Access
Note: This is a good time to switch between browsers, as noted in the Prerequisites.
2. Change your password and then you should see the Home tab.
3. Notice that the default app is Warehouse (if you don’t see Warehouse that’s OK, you just missed that setting in the profile, either
edit the profile or select the Warehouse app now), but that you can't see the Merchandise or Invoices tabs. Why not? Because the
user's profile doesn't provide the permissions necessary to access to the underlying objects that power the app.
105
Secure Your System Configure Org-Wide Defaults
1. Switch back to your other browser that's already logged into the DE org as the Sales Manager, refresh the page, and notice that the
Merchandise and Invoices tabs are now available.
2. Click on the Merchandise tab.
3. Click Go! next to View: All to display all records.
4. Click on the Invoices tab and check those out, too.
5. Now log out and, using the activation link in your email, log in as the Salesperson (and change your password).
6. Confirm that the Salesperson can see the Invoices tab, but not the Merchandise tab, as governed by the user's permission sets.
Tell Me More
As you can see, it’s pretty easy to create profiles and permission sets and then assign them to different users.
106
Secure Your System Step 1: Modify the OWD for Invoices
Tell Me More....
What about the Line Items object? Before you leave this page, notice that the Line Item object's OWD is "Controlled by Parent", which
means it inherits the OWD of the parent Invoice object. This happened automatically because you of the master-detail relationship
between the two objects. Neat, huh?
107
Secure Your System Share Records Using a Role Hierarchy
1. Switch back to the browser that's logged into the DE org as the Sales Person, then click the Invoices tab.
2. Click Go! next to View: All.
3. Notice that the list of available invoices is empty.
Why did this change? Although Sales Person has a permission set that lets the user CRUD Invoice and Line Item records, this permission
only provides the ability to CRUD records that the user owns. Considering that the OWD for these objects is set to Private, and the only
records created were by the admin super-user, Sales Person can’t see that owner’s records. To prove that Sales Person can access only
records that the user owns, complete the following steps to create a new Invoice that Sales Person owns:
1. On the Invoice detail page, click New , then click Save.
2. Click New Line Item and add choose some Merchandise. Click Save.
3. Click the Invoices tab and you’ll see there’s now an invoice there.
4. Now log out, and log back in as the Sales Manager user.
5. Repeat the steps above to prove that you cannot access Invoices and Line Items in the system that the Sales Manager user does not
own due to the Private setting for these objects.
108
Secure Your System Step 2: Assign Users to Roles
7. For This role reports to, use the lookup to select Sales Manager.
8. Click Save.
9. Now go back to the Creating the Role Hierarchy page (under Administration Setup > Manage Users > Roles. Expand the node
for Sales Manager, and you can see the subordinate Salesperson role.
Tell Me More....
There are a lot of extra roles defined based on the sample template you started with. You can delete them if you want, it won’t make
any difference for this set of tutorials. Note that DE orgs come only with two users, so unfortunately you can’t continue to add users.
4. Repeat the process to assign the Sales Person user to the Salesperson role.
109
Secure Your System Step 3: Test Record Access
Tell Me More....
A role hierarchy is just one option for sharing access to private records. For example, organizations often need to share sets of private
records that are related by ownership or other criteria with particular users. For such requirements, you can use groups. All that you need
to do is create a group and your sharing rules using a few more clicks.
110
CODE CUSTOM APP LOGIC
To quickly build apps that are easy to maintain, use the platform’s built-in, point-and-click options for business logic whenever possible.
Sometimes though, features such as workflow rules, formula fields, rollup summary fields, and approvals can't meet all of your needs
— that's when you should consider coding app logic.
In this series of tutorials, you learn how to use Apex and code custom app logic that meets unique requirements for app logic. Apex is
the platform’s programming language that you can use to build things like stored procedures and database triggers that are common
in traditional database-driven application development platforms. Along the way, you’ll learn how to use several tools to develop Apex
classes, methods, database triggers, and unit tests.
111
Code Custom App Logic Step 2: Execute Basic Apex Code
Tell Me More....
Notice the Help link click at the top of the of the console? If you click the link you'll find a bunch of really great resources. If you don’t
have time now, check it out later.
3. Select the checkbox for Open Log and then click Execute.
Tell Me More....
Apex is a programming language that you can learn quickly, especially if you already know similar languages, such as Java, C++, or C#.
Although the example above is extremely simple, you can learn a lot about Apex by studying it closely.
• Notice that it is a strongly typed language that supports common language fundamentals, such as variable declarations, assignments,
flow control structures such as loops, string concatenation, and comments. It's also an object-oriented language, as the call to the
debug method of the standard System class illustrates.
• If you're wondering why it is called anonymous code, that's because you are not naming and saving the code for later reuse — you
simply execute it, and once you leave the console and clear your work, it's gone. So where's your output? Continue to the next step.
112
Code Custom App Logic Step 3: Review the Execution Log
2. To look at the records in a specific log, double-click the log of interest. This action creates a new Log tab below with corresponding
Stack, Execution Log, and Source and Variables section.
3. In the Execution Log section, enter DEBUG (all caps) next to the Filter checkbox. Notice that the log only shows records
corresponding to System.debug calls, which verifies the output of "Hi" plus the value of the loop counter variable as it iterates.
Tell Me More....
There's a lot of information in a log. For example, in the Stack section, the Execution Tree tab shows a hierarchical tree of execution
operations, while the Performance Tree tab shows aggregated operation performance data that you can use to diagnose performance
issues. The Execution Log section shows individual durations and log records for the log that you select above in the Logs tab. Execution
logs can have many records, so it's useful to filter noise out and focus on just what interests you.
113
Code Custom App Logic Create an Apex Class and Method
Feel free to explore the Developer Console and experiment. Remember that it's always there when you need to quickly test, tune, or
debug some Apex code. For more information about the Developer Console, click Help to open Help and Training.
5. Comment the code as follows, and then click File > Save.
public class InvoiceUtilities {
// Class method to renumber Line Items for a given Invoice number.
// Returns a string that indicates success or failure.
}
114
Code Custom App Logic Step 3: Get an Invoice and its Line Items
// Create a copy of the target Invoice object and its Line Items.
2. Now use a SOQL query that orders existing line items and uses a filter to retrieve the target invoice, as given by the method's input
parameter. Notice that the object notation in SOQL is somewhat unique.
Invoice__c invoice = [Select i.Name, (Select Name From Line_Items__r ORDER BY Name)
From Invoice__c i
Where i.Name = :invoiceName LIMIT 1];
3. Don't save yet or you'll get a compilation error because we haven't added a return statement yet.
Note: Remember to Save your class as you go along in this step. On each save operation, make sure to check the Problems pane
and confirm that you don't have any compilation errors.
For source code, see https://gist.github.com/3605645.
public class InvoiceUtilities {
// Class method to renumber Line Items for a given Invoice number.
// Returns a string that indicates success or failure.
public static String renumberLineItems(String invoiceName) {
// Create a copy of the target Invoice object and its Line Items.
115
Code Custom App Logic Step 4: Create the Final Version of the Class Method
Invoice__c invoice =
[SELECT i.Name, (Select Name FROM Line_Items__r ORDER BY Name)
FROM Invoice__c i
WHERE i.Name = :invoiceName LIMIT 1];
Save the updated Apex class. On each save operation, check the Problems pane and confirm that you don't have any compilation errors.
If you do, fix them appropriately and save the corrected code.
Next, update the class with a loop to process and renumber each line item (see lines 13-18).
For source code, https://gist.github.com/3605650.
public class InvoiceUtilities {
// Create a copy of the target Invoice object and its Line Items.
Invoice__c invoice =
[SELECT i.Name, (SELECT Name FROM Line_Items__r ORDER BY Name)
FROM Invoice__c i
WHERE i.Name = :invoiceName LIMIT 1];
Notice in line 14, the FOR loop uses Apex-specific object notation to reference the line items of the invoice. Line 18 includes a
System.debug statement to output some handy information to the debug log.
Now create the final version of the class method so that it updates the database with the new version of the invoice's line items (see
lines 22-30).
116
Code Custom App Logic Step 5: Manually Test the Apex Class Method
// Create a copy of the target Invoice object and its Line Items.
Invoice__c invoice =
[SELECT i.Name, (SELECT Name FROM Line_Items__r ORDER BY Name)
FROM Invoice__c i
WHERE i.Name = :invoiceName LIMIT 1];
This method uses try/catch block to update the database and handle any unforeseen runtime exceptions that might occur.
• In the try block (see lines 22-24), the Database.update method is a standard Apex method that you can use to update one
or more sObjects. Again, notice the object notation to reference the target invoice's related line items
(invoice.Line_Items__r).
• The catch block (see lines 25-27) catches any DmlException. It contains a return statement that returns the exception error
message to the caller.
• If the method continues past the try/catch block, which means that no exception was thrown and the method didn't return the
exception error message, it simply returns a standard message to indicate success (see line 30).
117
Code Custom App Logic Call an Apex Class Method Using a Button
2. Update or insert one or more line items so that there is an unwanted sequence of line item numbers (e.g., 1, 3, 6). If you didn’t have
any test data at the beginning of this step, you may need to create a couple of merchandise records before you can add any line
items.
3. Now you can call the method and target the invoice above to renumber its line items. Switch back to the Developer Console.
4. Execute the following anonymous Apex. For the method input parameter, substitute the invoice number that you noted above.
String s = InvoiceUtilities.renumberLineItems('INV-0004');
5. If you switch back to your browser and refresh the Invoice detail page, you should notice that its line items are now in sequence
without any gaps.
Congratulations! With less than 20 lines of Apex code, you've built an Apex class method to solve a real-world business requirement.
Tell Me More....
The execution output is interesting to inspect if you want to learn more about Apex code execution. Remember from an earlier tutorial,
in the console, you can view logs for code executions. Although a full discussion of the log output for the above class method execution
is outside the scope of this tutorial, here are a few highlights.
• Filter for SOQL_EXECUTE and you see that the embedded SOQL query retrieved one row from the database.
• Filter for DEBUG and you see the output from the System.debug calls in the method.
118
Code Custom App Logic Step 1: Create a Custom Button
8. Make sure your form matches the following screen, and then click Save.
9. When prompted, click OK. We’ll add this button to a page layout in the next step.
Tell Me More....
Examine the code you pasted.
• Lines 1 and 2 load two libraries from the Salesforce AJAX Toolkit, a JavaScript wrapper around the Force.com SOAP API.
119
Code Custom App Logic Step 2: Add the Button to the Page Layout
• Line 3 leverages the AJAX Toolkit to call the method, passing in the Name of the current invoice.
• Lines 4 and 5 are standard JavaScript calls that display an alert message and refresh the current page.
120
Code Custom App Logic Step 4: Test the New Button
// Create a copy of the target Invoice object and its Line Items.
Invoice__c invoice =
[SELECT i.Name, (SELECT Name FROM Line_Items__r ORDER BY Name)
FROM Invoice__c i
WHERE i.Name = :invoiceName LIMIT 1];
When you return to the list of Apex classes, notice that there's a new link for the InvoiceUtilities class: WSDL. If you click it,
you see a WSDL file that apps can use to interface with the class.
121
Code Custom App Logic Create a Database Trigger
Tell Me More....
Another way to call Apex class methods from JavaScript is to use the platform’s JavaScript remoting feature. For more information, see
the Apex Code Developer's Guide.
// loop through the Invoices, attaching errors to those that have Line Items
for (Invoice__c invoice : invoices) {
if (!invoice.Line_Items__r.isEmpty()) {
122
Code Custom App Logic Step 2: Manually Test the Trigger
}
}
}
6. Click Save.
Tell Me More....
• A trigger can fire before or after DML operations. The trigger in this tutorial fires before the execution of a delete operation that
targets one or more records in the Invoice object.
• Triggers have special variables accessible to them called context variables. In a nutshell, old and new context variables provide copies
of old and new sObjects being updated by the call that fires the trigger. As you can see in the code, context variables are handy to
scope processing in a trigger body.
• In the FOR loop, the trigger simply adds a validation error to any Invoice that has Line Items, which in turn causes the Force.com
platform to roll back the transaction that fires the trigger (in this case, delete).
Next, try to delete an invoice that does not have any line items to make sure that the trigger does not prevent the deletion of such
invoices.
123
Code Custom App Logic Step 1: Create a Unit Test
3. In the popup, enter TestDeleteRestrictInvoice for the class name and click OK.
4. Replace the auto-generated code with the following code into the new Apex class editor, and then press CTRL+S to save the class.
For source code, see https://gist.github.com/3605669.
@isTest
private class TestDeleteRestrictInvoice {
// Create test Line Item and insert it into the database, if withLineItem == true
if (withLineItem) {
Line_Item__c item = new Line_Item__c(
name = '1',
Quantity__c = 1,
Merchandise__c = merchandise.Id,
Invoice__c = invoice.Id
);
insert item;
}
return invoice;
}
124
Code Custom App Logic Step 2: Run Unit Tests
Tell Me More....
The comments in the code explain the gist of the test methods. Notice that it’s important, when building and testing triggers, to keep
in mind that triggers can fire as the result of both single-row and bulk triggering statements. Here are a few important points to understand
about building unit tests.
• Use the @isTest annotation to define classes or individual methods that only contain code used for testing.
• Test classes must be top-level classes.
• Unit test methods are static methods that are defined with the @isTest annotation or the testMethod keyword.
125
Code Custom App Logic Step 2: Run Unit Tests
Any time you modify the trigger, make sure to run the corresponding unit tests so that you have confidence that the trigger still works
properly.
126
BUILD A CUSTOM USER INTERFACE WITH VISUALFORCE
3. Click Edit.
4. Select the Development Mode checkbox, and click Save.
127
Build a Custom User Interface with Visualforce Step 2: Create a Visualforce Page
2. Click the Create Page CountSheet link to create the new page.
3. Click the Page Editor link (CountSheet) in the bottom left corner of the page. The Page Editor tab displays the code and a preview
of the new page (which has some default text). It should look like this.
128
Build a Custom User Interface with Visualforce Step 3: Add a Stylesheet Static Resource
4. You don't really want the heading of the page to say “Congratulations”, so change the contents of the <h1> tag to Inventory
Count Sheet, and go ahead and remove the comments. The code for the page should now look like this.
<apex:page>
</apex:page>
5. Click the Save icon at the top of the Page Editor. The page reloads to reflect your changes.
Tell Me More....
• Notice that the code for the page looks a lot like standard HTML. That's because a Visualforce page combines HTML tags, such as
<h1>, with Visualforce-specific tags, which usually start with <apex:>
• If your browser has trouble displaying Developer Mode, you can turn it off in the same way you turned it on. You can create a new
Visualforce page by clicking Setup > Develop > Pages.
129
Build a Custom User Interface with Visualforce Step 3: Add a Stylesheet Static Resource
6. Click Save.
Now you need to modify your Visualforce page to reference the stylesheet.
1. Just as you did when you created the page, add the text /apex/CountSheet to the URL for your Salesforce instance.
2. Modify the attributes of the <apex:page> tag and enter the following code to remove the standard stylesheet, the header, and
the sidebar.
<apex:page standardStylesheets="false" showHeader="false" sidebar="false">
3. Now you need to tell the page where to find the stylesheet, so add a new line below the first <apex:page> tag and type <apex:
4. The editor has code insight, which gives you a drop-down list of the elements that are available in this context. Start typing
stylesheet and when you see apex:stylesheet, select it.
</apex:page>
130
Build a Custom User Interface with Visualforce Step 4: Add a Controller to the Page
Tell Me More....
Let's take a look at that stylesheet code in a little more detail.
• $Resource is a global variable accessible in Visualforce pages. With $Resource.styles, you refer to the resource called
"styles" that you created earlier.
• The URLFOR() function locates the static resource, and a file within that resource, and calculates the URL that should be generated
in your final page. If the syntax looks familiar, it's because you've already encountered it to dynamically evaluate values when the
Visualforce page is rendered.
• Why did you download a .zip file for only one small stylesheet? Usually stylesheets (and other static references) come in bundles of
more than one, and so it's useful to see the code that accesses a .zip file. If you had simply uploaded styles.css you could refer
to it using <apex:stylesheet value="{$Resource.styles}" />. While that code is simpler, you wouldn't know
how to refer to files in an archive. After the stylesheet is uploaded as a .zip file in a static resource, all you need to do is enter the
name of the stylesheet between single quotes: <apex:stylesheet value="{!URLFOR($Resource.styles,
'enter_stylesheet_name.css')}" />.
3. Click the Save icon at the top of the Page Editor. You won't notice any change on the page. However, because you've indicated that
the page should use a controller, and defined the variable products, the variable will be available to you in the body of the page
and it will represent a list of merchandise records.
Tell Me More....
Take a look at what you added to the <apex:page> tag.
• Setting the standardController attribute connects your page to the standard controller for a specific object, in this case,
the Merchandise__c object.
• Setting the recordSetVar attribute puts a standard controller into "list" mode and sets a products variable, which will
contain the list of merchandise records.
131
Build a Custom User Interface with Visualforce Step 5: Display the Inventory Count Sheet as a Visualforce
Page
1. In the line below the </h1> tag, start typing <apex:f on a new line, and highlight <apex:form> when it appears in the
drop-down list. The form will allow you to make updates to the page.
2. Press ENTER, and notice that the system generates the opening and closing tags for you.
3. Place your cursor between the tags and create a data table. Start by typing <apex:d and press ENTER to select dataTable
from the drop-down list.
4. Now you need to add some attributes to the dataTable tag. On one or more lines within the tag, enter the following.
The value attribute indicates which list of items the dataTable component should iterate over. The var attribute assigns
each item of that list, for one single iteration, to the pvitem variable. The rowClasses attribute assigns CSS styling names to
alternate rows.
5. Now you are going to define each column, and determine where it gets its data by looking up the appropriate field in the pitem
variable. Add the following code between the opening and closing dataTable tags.
<apex:dataTable value="{!products}" var="pitem" rowClasses="odd,even">
<apex:column headerValue="Product">
<apex:outputText value="{!pitem.name}"/>
</apex:column>
</apex:dataTable>
The headerValue attribute has simply provided a header title for the column, and below it you'll see a list of rows: one for each
merchandise record. The expression {!pitem.name} indicates that we want to display the name field of the current row.
7. Now, after the closing tag for the first column, add two more columns.
<apex:column headerValue="Inventory">
<apex:outputField value="{!pitem.Quantity__c}"/>
</apex:column>
<apex:column headerValue="Physical Count">
<apex:inputField value="{!pitem.Quantity__c}"/>
</apex:column>
Note: The second column is an inputField, not an outputField. The inputField will display a value, but it will
also allow you to change it.
8. Click Save and you have an inventory count sheet! It lists all the merchandise records, displays the current inventory, and provides
an input field for the physical count.
9. As a final embellishment, add a button that will modify the physical count on any row and refresh the values on the page. To do
this, enter the following code directly above the </apex:form> line.
<br/>
<apex:commandButton action="{!quicksave}" value="Update Counts" />
132
Build a Custom User Interface with Visualforce Step 6: Add Inline Editing Support
Tell Me More....
• The dataTable component produces a table with rows, and each row is found by iterating over a list. The standard controller
you used for this page was set to Merchandise__c, and the recordSetVar to products. As a result, the controller
automatically populated the products list variable with merchandise records retrieved from the database. It's this list that the
dataTable component uses.
• You need a way to reference the current row as you iterate over the list. That statement var="pitem" assigns a variable called
pitem that holds the current row.
• Every standard controller has various methods that exist for all Salesforce objects. The commandButton component displays the
button, and invokes a method called quicksave on the standard controller, which updates the values on the records. Here,
you're updating the physical count of the product and performing a quick save, which updates the product with the new count.
• Although pagination isn't shown in this example, the functionality is there. If you have enough records to page through them, add
the following code below the commandButton for page-flipping action.
<apex:commandLink action="{!next}" value="Next" rendered="{!hasNext}" />
2. Within the inventory column, break up the outputField component so that it has an end tag, as follows.
<apex:outputField value="{!pitem.Quantity__c}">
</apex:outputField>
3. Between the outputField's start and end tag, insert the inlineEditSupport component.
<apex:inlineEditSupport event="ondblclick" showOnEdit="update"/>
133
Build a Custom User Interface with Visualforce Step 6: Add Inline Editing Support
4. Now that you've added the inlineEditSupport component, modify the update button to give it an ID and a style class name.
The ID is referenced by the inlineEditSupport component to show the button during editing. The style class name is used
in styles.css to hide the update button the first time the page renders. Replace the commandButton with the following.
<apex:commandButton id="update" action="{!quicksave}" value="Update Counts"
styleclass="updateButton"/>
6. Save. The page now displays the inventory count table with two columns. Notice that the Update Counts button is hidden initially.
7. Double-click any cell in the inventory column. The field dynamically becomes an input field and the Update Counts button appears.
8. Modify the count value and click Update Counts to commit this update.
Tell Me More....
• The event attribute of the inlineEditSupport component is set to "ondblclick", which is a DOM event and means that
the output field will be made editable when you double-click it. Also, the showOnEdit attribute causes the Update Counts button
to appear on the page during an inline edit. This attribute is set to the ID of the Update Counts button.
• The Update Counts button is hidden through its style specification in the static resource file styles.css. The styleclass
attribute on commandButton links this button to an entry in styles.css.
134
Build a Custom User Interface with Visualforce Summary
Summary
Congratulations! You have created a new interface for your Warehouse app by creating a Visualforce page that uses a standard controller.
Your page is highly configurable. For example, you can easily modify which data is displayed in each row by modifying the column
components. The page also makes use of a lot of functionality provided by the standard controller behind the scenes. For example, the
controller automatically queries the database and finds all merchandise records and assigns them to the products variable. It also
provides a way of saving records, through its quicksave method.
135