Force.

com Workbook: Winter '11

Force.com Workbook

Last updated: November 6, 2010
© Copyright 2000-2010 salesforce.com, inc. All rights reserved. Salesforce.com 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.

Table of Contents

Table of Contents
About the Force.com Workbook...........................................................................................................................................................3 Tutorial #1: Creating a Warehouse Application....................................................................................................................................5 Step 1: Create a Merchandise Custom Object..........................................................................................................................5 Step 2: Add Description, Price, and Total Inventory Fields......................................................................................................7 Step 3: Create a Tab..................................................................................................................................................................9 Step 4: Create a Warehouse App.............................................................................................................................................10 Step 5: Create a Merchandise Record.....................................................................................................................................11 Summary.................................................................................................................................................................................12 Tutorial #2: Adding Relationships......................................................................................................................................................13 Step 1: Create an Invoice Statement Custom Object..............................................................................................................13 Step 2: Create a Line Item Object...........................................................................................................................................16 Step 3: Relate the Objects.......................................................................................................................................................17 Step 4: Add Invoice Statements to the App............................................................................................................................18 Step 5: Create an Invoice Record............................................................................................................................................18 Summary.................................................................................................................................................................................20 Tutorial #3: Using Formulas and Validation Rules..............................................................................................................................21 Step 1: Calculate a Value for Each Line Item..........................................................................................................................21 Step 2: Calculate a Value for the Invoice Statement With a Roll-Up Summary Field............................................................22 Step 3: Check Inventory With a Validation Rule....................................................................................................................23 Step 4: Test the Validation Rule..............................................................................................................................................25 Step 5: Improve the Validation Rule........................................................................................................................................25 Summary.................................................................................................................................................................................26 Tutorial #4: Using Workflow and Approvals.......................................................................................................................................28 Step 1: Populate the Line Item Price Using a Workflow Rule................................................................................................28 Step 2: Update Total Inventory When an Order is Placed......................................................................................................30 Step 3: Test the Workflow Rules.............................................................................................................................................32 Step 4: Create an Email Template...........................................................................................................................................33 Step 5: Create an Approval Process.........................................................................................................................................34 Step 6: Create a Custom Profile..............................................................................................................................................36 Step 7: Create a User...............................................................................................................................................................37 Step 8: Test the Approval Process............................................................................................................................................38 Summary.................................................................................................................................................................................40 Tutorial #5: Adding Business Logic with Apex..................................................................................................................................41 Step 1: Create an Apex Trigger Definition..............................................................................................................................42 Step 2: Define a List Variable..................................................................................................................................................43 Step 3: Iterate Through the List and Modify Price.................................................................................................................44 Step 4: Test the Trigger...........................................................................................................................................................45 Summary.................................................................................................................................................................................46 Tutorial #6: Adding Tests to Your Application....................................................................................................................................47 Step 1: Create an Apex Test Class...........................................................................................................................................47 Step 2: Add Test Methods to the Class...................................................................................................................................48

i

.......................................74 Tutorial #10: Creating a Desktop App with Force.....49 Step 4: Execute the Test...................................................................................................................................................................95 ii ........................................................com Flex............................................94 Delivering Your Application.........................................................................................................................................................................................................................................93 Appendix...................64 Step 3: Create a Force.......................................................................................................................................69 Step 3: Create the Store Front................................................................................................................................54 Step 1: Enable Visualforce Development Mode..............................................................................................................................82 Step 7: Set the Force........................................................................................................................................................................com IDE...............84 Step 9: Testing the Inventory Tracker application......................................................................................62 Step 2: Register a Force..........com Domain Name...............................................................83 Step 8: Create the Inventory Tracker Window Component.......62 Step 1: Create a Product Catalog Page......................................................................................................................................................................................94 Creating and Logging into a Sandbox....................................................................................................................................51 Summary.........................76 Step 2: Create an Offline Briefcase Configuration..........................................................................................................................................................................................................................................................................................................................................................................................68 Step 1: Create a Controller.....................Table of Contents Step 3: Write Code to Execute the Trigger.......................65 Summary........................68 Step 2: Add Methods to the Controller.....................................................59 Summary........................................................53 Tutorial #7: Building a Custom User Interface Using Visualforce......................com Flex Application Component Attributes........................................................58 Step 5: Display the Inventory Count Sheet as a Visualforce Page.............................................................................................................................................................................................................................................................................................................................................................................................................................................................75 Step 1: Configure Your Salesforce.......................................................................................................................80 Step 6: Import Your Enterprise WSDL....................................................................................................65 Step 4: Configure and Test the Site.......................71 Step 4: Bonus Step—Updating the Page with AJAX................................................................................com Site........72 Summary..........................67 Tutorial #9: Creating a Store Front.............................................................................................................................................................................90 Summary..........................................50 Step 5: View Code Coverage and Improve Tests...................................................................................................................................................77 Step 3: Generate Your Enterprise WSDL......54 Step 2: Create a Visualforce Page..........................................................................................................................................................................................com Flex Project....................................................................................55 Step 3: Add a Stylesheet Static Resource............com Flex.......................................................56 Step 4: Add a Controller to the Page..................................................................................................................................................................................................79 Step 4: Install and Launch Force...........................................................................................................................................................................................................61 Tutorial #8: Creating a Public Web Page Using Sites........................................................................................................................................................79 Step 5: Create a Force.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................94 Creating a Project in the Force.................................................................................................................................................................................com Personal Information...............................................................

Developer Edition uses a Start Here tab. you can migrate the changes from your sandbox to production.com Flex is only available in Developer Edition.About the Force. Force.com/form/signup/freeforce-platform.com Workbook About the Force. 3 . most applications share certain characteristics such as: • • • • A database to model the information in the application Business logic and workflow to carry out particular tasks under certain conditions A user interface to expose data and functionality to those logged in to your application A public website to show data and functionality on the Web The tutorials are centered around building a very simple warehouse management system. As a developer preview. If you have not created a sandbox yet. and trigger logic to update the prices in open invoices. To sign up for a Free Edition organization. For example. For more information. approvals to send email notifications for large invoice values. which has all of the required features and functionality. workflow to update inventory when something is sold. Once the database and business logic are complete. that is. a public website to display a product catalog.com Flex. You'll continue by adding business logic: validation rules to ensure that there is enough stock. If you'd like to develop offline and integrate with the app. these differences are trivial. You can't use Free Edition to complete Tutorial #10: Creating a Desktop App with Force. navigate to developer. you'll create a user interface to display a product inventory to staff.com Flex. • • • • Some of the tutorials require that you use a sandbox. you'll first build a database model for keeping track of merchandise. How is the Workbook Organized? The tutorials in this workbook build on one another and are designed to be done in order.com platform to build virtually any kind of application. To sign up for a free Developer Edition organization.com Workbook The Force.com/join. we've added a final tutorial to use Force. you can also use Free Edition with the following considerations. It may sound like a lot. The pictures in the workbook may be slightly different from what you see on your screen. and then the start of a simple store front. When you complete the application. navigate to salesforce. Each of the tutorials builds on the previous tutorial to advance the application's development and simultaneously showcase a particular feature of the platform.com Workbook shows you how to create an application in a series of tutorials. However. While you can use the Force. see Creating and Logging into a Sandbox on page 94.jsp. but it's all quite easy—as you'll soon see. see Delivering Your Application on page 95. Choosing a Development Environment This workbook is designed to be used with a Developer Edition organization.force. You'll start developing the application from the bottom up. In most cases. while Free Edition has a Getting Started tab. so it's easiest if you complete all of the tutorials within your sandbox organization.

com.com Workbook Tutorial Create the App Tutorial #1: Creating a Warehouse Application Tutorial #2: Adding Relationships Add Logic Tutorial #3: Using Formulas and Validation Rules Tutorial #4: Using Workflow and Approvals Tutorial #5: Adding Business Logic with Apex Write Tests Tutorial #6: Adding Tests to Your Application Extend the User Interface Tutorial #7: Building a Custom User Interface Using Visualforce Tutorial #8: Creating a Public Web Page Using Sites Tutorial #9: Creating a Store Front Offline Integration Tutorial #10: Creating a Desktop App with Force. • • To learn more about Force. if you're a smell-the-roses type.. 4 .com/workbook. You can find the latest version of this Workbook and additional tutorials that extend the app at developer. move on to the next step..com IDE Delivering Your Application Difficulty Estimated Time to Complete Beginner Beginner 20-30 minutes 20-30 minutes Beginner Intermediate Advanced 20-30 minutes 30-45 minutes 20-30 minutes Advanced 20-30 minutes Intermediate Intermediate Intermediate 30–45 minutes 20-30 minutes 30 minutes Advanced 30 minutes Tell Me More. However. If you like to do things quickly.force.force. visit Developer Force at developer.com Flex Appendix Creating and Logging into a Sandbox Creating a Project in the Force. there's a lot of useful information here and some additional steps to flesh out your app.com and to access a rich set of resources.. At the end of each step there is an optional Tell Me More section.About the Force.

as well as screens that allow you to view and edit all of this information. 3.com platform includes predefined standard objects. these data objects are called custom objects. When you complete this tutorial. description. and a custom object that tracks the name. Click Your Name ➤ Setup in the upper right corner. The first step is to create a custom object that will hold information about merchandise. So you'll begin by creating a data object that keeps track of all the elements of a particular merchandise item. 1. See Also: Step 1: Create a Merchandise Custom Object Step 2: Add Description. Duration: 20-30 minutes At the heart of this application is what you want to sell: merchandise.salesforce. and price of all your merchandise. but you can also create custom objects to track anything you want. An object comes with standard fields. Launch your browser and go to https://login. and screens that allow you to list. 5 . Price. such as its name.com platform. you will have a working application with its own menu. and then click Create ➤ Objects in the sidebar menu to display the Custom Objects page. But you can also add your own fields to track or list just about anything you can think of. and Total Inventory Fields Step 3: Create a Tab Step 4: Create a Warehouse App Step 5: Create a Merchandise Record Summary Step 1: Create a Merchandise Custom Object The Force. On the Force. and so on. 2. a tab. you can think of a custom object as representing a table. description. If you are familiar with databases. price.Tutorial #1: Creating a Warehouse Application Tutorial #1: Creating a Warehouse Application Level: Beginner. Enter your username (in the form of an email address) and password. view and edit information about the object.com.

After you save the new custom object. • • • For the Label.. 6 . Click New Custom Object to display the New Custom Object wizard. Fill in the custom object definition.. Take a look at the following image to familiarize yourself with the Merchandise custom object. the detail page for the custom object opens.Tutorial #1: Creating a Warehouse Application 4. 5. 6. Tell Me More.. enter Merchandise. enter Merchandise. For the Plural Label. Click Save to finish creating your new object. Leave all other values as they are.

a. which means it will automatically track who created each record. how much it costs. Standard fields—Some fields are generated automatically. and inventory. and how many are in stock. Price.Tutorial #1: Creating a Warehouse Application 1. 1. and Total Inventory Fields A merchandise object should have fields that are used for tracking various information. c. Scroll down to the Custom Fields & Relationships related list. Soon you'll be adding fields. you'll do that in the next step. API name—When you created the Merchandise object. See Also: Tutorial #1: Creating a Warehouse Application Step 2: Add Description. price. but one is generated for you. Merchandise detail page—This page shows you everything you need to know about your Merchandise custom object. you're right. validation rules. select Text Area and click Next. For Data Type. Price. 4. 7 . This name is how you reference the object programmatically. Follow the steps below to create custom fields for the description. Custom fields—You haven't defined any custom fields yet. these are called standard fields. and other neat features to this custom object. If you guessed that custom fields have names that end in __c. such as a description. relationships. 3. You can add custom fields to list or track just about anything you can think of. which differentiates them from standard objects and makes them easier to identify. the Merchandise object has a standard field for Owner. Create the Description field. For example. you didn't specify an API name. All custom objects end in __c. b. 2. Click New to launch the New Custom Field wizard. and Total Inventory Fields Step 2: Add Description.

For Data Type. One of your business rules says that you can't create new merchandise without providing a description. In the next step. e. accept the defaults. Click Save & New to save the Description field and return to the first step of the wizard.Tutorial #1: Creating a Warehouse Application d. Check the Required checkbox. d. enter Price. f. and click Next again. Optionally. and click Next. Fill in the custom field details. e. Create the Price field. The Field Name field should already be populated with the field name: Description. a. and click Next. Making Description a required field fulfills that business rule. accept the defaults. In the next step. 2. b. For the Length enter 16 and for Decimal Places enter 2. but for the sake of brevity we leave these out in the remainder of the workbook. Click Next. click Save & New to save the Price field and to return to the first step of the wizard. and click Next. 8 . • • • • • For the Field Label. Select the Required checkbox. Do not fill in the Default Value field. c. Leave the defaults for the remaining fields. enter Description and press the Tab key. Fill in the custom field details: • • • For the Field Label. It's a good idea to fill these in. select Currency. fill in the Description and Help Text fields.

For Data Type. accept the defaults. click Create ➤ Tabs. Accept the defaults for the remaining fields. and click Next. We've also recorded the total number of items (Total Inventory) that we have for each piece of merchandise. Tell Me More. Create the Total Inventory field. and we'll use that for both the stock price and retail price. See Also: Tutorial #1: Creating a Warehouse Application Step 1: Create a Merchandise Custom Object Step 3: Create a Tab Step 3: Create a Tab Tabs provide an easy way to find and organize objects and records. enter Total Inventory.. select Number and click Next. So why do you need both? A Field Label is what the user sees. Fill in the custom field details: • • For the Field Label. Click Save to create the Inventory field and to return to the Merchandise Custom Object page. just follow the same steps above and use the Stock Price name.. a description. you can make another Stock Price field now if you want to. c. view. In this step you will create a tab for the Merchandise custom object. e. 9 . a. and edit records.. they will be able to create. However. In the next step. the system automatically populates the Field Name as well. 1. You may have noticed that when you enter a Field Label.Tutorial #1: Creating a Warehouse Application Note: This app has only one Price field. In the Custom Objects Tabs related list. and click Next. and a price. When users click this tab. At this point we have a nice representation of our warehouse items: they each have a name. 3. a field labeled “Customer ph# :” would be named Customer_ph in the code (the system replaces spaces with underscores and removes the # and : characters). d. and must not contain spaces or illegal characters. The Field Name is used internally in code. b. 2. click New to launch the New Custom Tab wizard. Within the Setup area. Select the Required checkbox. For example. and so it should be easy to read and may contain spaces.

3. See Also: Tutorial #1: Creating a Warehouse Application Step 2: Add Description. In this step you create a Warehouse application and add a tab to it. click the lookup icon and select the Box icon. 5. From the Object drop-down list. Tell Me More. you can see it at the top of the screen. enter Warehouse. select Merchandise. you're not stuck with a standard set of icons and colors. and Total Inventory Fields Step 4: Create a Warehouse App Step 4: Create a Warehouse App An application is a set of tabs.. Click New to launch the New Custom App wizard. When you create a tab. Later.Tutorial #1: Creating a Warehouse Application 3. you'll add more tabs to the app. Accept the remaining defaults. Fill in the custom app details. 6. 2. Click Next and then Save to finish creating the tab. • For the App Label. As soon as you create the tab.. and click Next. Price. 10 . Navigate to Your Name ➤ Setup ➤ Create ➤ Apps. For the Tab Style. 4. 1. you can choose your own color and custom image by clicking Create your own style.

Tutorial #1: Creating a Warehouse Application • For the App Name. update. Click Next. 4. In the Available Tabs list. You can switch between applications you have created. using the default logo for the app. Click Save to create the Warehouse application. Accept the defaults on the next page. The tabs in an application don't have to be related to each other. 5. 8. read. Leave the Default Landing Tab set to the Home tab. and click Next. or installed by simply selecting any one of them from the menu. See Also: Tutorial #1: Creating a Warehouse Application Step 3: Create a Tab Step 5: Create a Merchandise Record Step 5: Create a Merchandise Record At this point you've created a functioning application. if you refer to the Start Here tab a lot. Select the Visible checkbox to make the application available to all user profiles. 9. 6. Tell Me More. and delete records. For example.. In fact.. bought. locate the Merchandise tab and click Add to add it to the list of selected tabs. the platform automatically generates a user interface that lets you create.. enter Warehouse. 7. and click Next.com app menu in the upper right corner of the page.com. When you define an object on Force. you can add that to the Warehouse app. As soon as you create the application. you can modify custom applications to group all of your most frequently used tabs together in one place. Now check to see how your new application works. it appears in the Force. 11 .

Fill in all the fields. Tell Me More. As you can see. 3. The next step is to use an invoice to track how your merchandise moves in and out of your warehouse. Click Save. as shown in the following image. Select the Warehouse application from the Force. it's easy to use the online interface and wizards to create a custom object. For Description field enter A small plane. but it would be more realistic if you had more merchandise.com app menu. such as the ability to view and create merchandise.. Go ahead and create some more. Click the Merchandise tab and then click New to create a new product. Your warehouse will work just fine with only one product. it already has a lot of built-in functionality. fields. 4.99. and a tab.. See Also: Tutorial #1: Creating a Warehouse Application Step 4: Create a Warehouse App Summary Summary Congratulations! You have just built a Warehouse application that keeps track of products you have in stock. and then pull it all together into an application that lets you create and track information about your merchandise. In the Price field enter 9. In the Total Inventory field enter 2000. 2. Although the application is far from complete.. See Also: Tutorial #1: Creating a Warehouse Application Step 5: Create a Merchandise Record 12 . Tip: use Save and New to create new records rapidly.Tutorial #1: Creating a Warehouse Application 1. • • • • In the Merchandise Name field enter Wee Jet.

Click Your Name ➤ Setup ➤ Create ➤ Objects. • • • • • In the Label field . you can think of relationship as foreign keys. This relationship lets you compose multiple line items and associate them with a single invoice statement.com takes care of the underlying implementation for you. 2. enter Invoice Statement. the difference being that Force. and all you need to do here is establish how the objects are related. you create two new objects. select Auto Number. and a description.Tutorial #2: Adding Relationships Tutorial #2: Adding Relationships Level: Beginner. an invoice statement and a line item. If you're familiar with relational databases. and associate them to each other in a master-detail relationship. 1. a status. you create an invoice statement with a unique number. In this step. enter Invoice Number. so you'll also add a relationship between the merchandise and line item objects. Each line item is an indication of how many units of a particular merchandise item was sold. In the Plural Label field. Click New Custom Object and fill in the custom object definition. enter INV-{0000}. 13 . enter Invoice Statements. In the Record Name field . See Also: Step 1: Create an Invoice Statement Custom Object Step 2: Create a Line Item Object Step 3: Relate the Objects Step 4: Add Invoice Statements to the App Step 5: Create an Invoice Record Summary Step 1: Create an Invoice Statement Custom Object An invoice statement is required to move inventory into or out of the warehouse. Duration: 20-30 minutes In this tutorial. Prerequisites Warehouse App You first need to create the basic Warehouse application as described in Tutorial #1: Creating a Warehouse Application on page 5. In the Data Type field . In the Display Format field.

Open Closed Negotiating Pending • Select the checkbox for Use first value as default value. 14 . • • In the Field Label field . Leave all other values as they are and click Save. Scroll down to the Custom Fields & Relationships related list and click New. select Picklist and click Next. each entry on its own line. Enter the following picklist values in the box provided. a. enter 1.Tutorial #2: Adding Relationships • In the Starting Number field. c. Add a Status field. For Data Type. b. 4. 3. enter Status. Fill in the custom field details.

In the Data Type field.Tutorial #2: Adding Relationships d. Click Save & New. select Read Only and then click Next. and also supplied a Display Format... accept the defaults. When displayed. Click Next. Tell Me More. as shown here. b. enter Description. Note how we set the invoice name data type to Auto-Number. beginning with the starting number you specify. the format will look as follows: INV-002. 5. c. f. Your Invoice Statement object should now have two custom fields. select Text Area and click Next. The platform will now automatically assign a number to each new unique record that is created. In the Field Label and Field Name fields. Now create an optional Description field. Click Next. a. d. See Also: Tutorial #2: Adding Relationships Step 2: Create a Line Item Object 15 . Click Save to the detail page for the Invoice Statement object. e. For Field Level Security. and click Next again..

and for Decimal Places enter 2.Tutorial #2: Adding Relationships Step 2: Create a Line Item Object Each invoice is going to be made up of a number of invoice line items. The field is read-only because the value will be retrieved from the Merchandise object in a later tutorial. You are first going to create the Line Item object. b. In the Data Type field. click Next. Click Previous and deselect Required. Change the Record Name to Line Item Number. select Currency and click Next. 5. Note: If Read-Only is not available. d. Click Next. 2. Scroll down to the Custom Fields & Relationships related list and click New. Click New Custom Object and fill in the custom object definition. 1. e. 3. a. 16 . c. Leave the Data Type field set to Text. enter Line Item. • • In the Field Label field. In the Plural Label field . and then click Save & New. you probably selected Required by mistake. You follow similar steps to add a Units Sold field. enter 16. which represent the number of Merchandise items being sold at a particular price. enter Unit Price. 4. Fill in the custom field details. Click Your Name ➤ Setup ➤ Create ➤ Objects. and then later relate it to the Invoice Statement and Merchandise objects. enter Line Items. In the Length field. • • • • In the Label field . We'll call it Unit Price so that we don't get confused with the Merchandise object Price field. Select Read-Only for all profiles. Leave all other values as they are and click Save. Add a read-only Unit Price field.

See Also: Tutorial #2: Adding Relationships Step 2: Create a Line Item Object Step 4: Add Invoice Statements to the App 17 . and the Invoice_Number field. which defaults to Open. Click Next. select Number and click Next. Tell Me More. Deselect the checkbox next to Merchandise Layout so that Line Items don't appear on the Merchandise related list. 2. these get their values from other objects. select Master-Detail Relationship and click Next. accepting the defaults. Click Save & New. 4. select your Invoice Statement custom object and click Next. 9. Tell Me More.. and currency. Click Save to return to the detail page of the Line Item custom object. select Master-Detail Relationship and click Next. enter Units Sold and click Next. In the Data Type field. which is automatically assigned by the Auto-number data type. On each of those objects you created custom fields to represent text. and that the Invoice Line Items are related to Merchandise... scroll down to the Custom Fields & Relationships related list and click New. numbers. See Also: Tutorial #2: Adding Relationships Step 1: Create an Invoice Statement Custom Object Step 3: Relate the Objects Step 3: Relate the Objects Now that you have all the objects representing the data model. All of those fields have something in common: the values are provided by the user. Unlike the previous fields. 6. 3.. In the Data Type field. The Line Item is related to both an Invoice Statement (a statement is composed of a number of line items) and Merchandise (a line item takes its price from the merchandise).. Accept the defaults on the next three screens by clicking Next. c. You also created two custom fields that have system-generated values: the Status picklist. In the Related To field. b. You have just created two master-detail relationships ensuring that your Invoice Statement records are related to Invoice Line Item records. You'll use that feature in a later tutorial. 5. and Line Item. In the Related To field. and then click Save to return to the Inventory Item detail screen.Tutorial #2: Adding Relationships a. In the Field Label field. Master-detail relationships also support roll-up summary fields. Accept the defaults on the following screens by clicking Next. At this point you've created three custom objects: Merchandise. 8. Inventory Statement. On the detail page of the Line Item object. allowing you to aggregate information about the child records. 7. d. select your Merchandise custom object and click Next.. In the next step you will create two more fields. 1. you want to relate them to each other. In the Data Type field.

For the Tab Style. Because you also related the objects. edit. In the Custom Object Tabs related list. click New to launch the New Custom Tab wizard. and click Next and then Next again. click Create ➤ Tabs. and update records. Your Invoice Statements tab is now part of your app. This will add the Invoice Statements tab to your Warehouse app. the platform automatically generates a user interface for the objects you create. Click the Invoice Statements tab. 3. On the Add to Custom Apps page. 1. delete. This will expose the user interface that Force. 6. select Invoice Statement.Tutorial #2: Adding Relationships Step 4: Add Invoice Statements to the App Just as you did before. click the lookup button and select the Form icon. so that you can view. for the Merchandise custom object. the user interface provides a way of navigating between related records as well. Within the Setup area. 4. 2. deselect all the checkboxes except Warehouse. Click New. The detail page of your invoice statement should look like this. enter First Invoice and then click Save.com automatically generates for this object. From the Object drop-down list. See Also: Tutorial #2: Adding Relationships Step 3: Relate the Objects Step 5: Create an Invoice Record Step 5: Create an Invoice Record As you saw in the previous tutorial. you'll want to create a tab for the Invoice Statement object and add it to your Warehouse app. 7. Accept the remaining defaults. 2. 1. Click Save to finish creating the tab. In the Description field. 5. 18 . 3.

click the lookup button and select a product. and this tutorial is supposed to be easy. when what you enter is a number. If line items are numbered. 2. like Invoice Statements? The short answer is that it's easier to work with text when we work with records. Fill in the fields. • • • • In the Line Item Number field enter 1. In the Unit Price field enter 10. but it makes a later tutorial. and how the user interface displays an empty Line Items related list below it. 1. 3. Tell Me More. Next you'll add a line item to the invoice.. For the Merchandise field. The Invoice Statement is linked to the Line Item via a master-detail field—that's how you created this relationship and why there's a related list on the Invoice Statement detail page.. You can make Line Item an auto number field if you want to. Click New Line Item. See Also: Tutorial #2: Adding Relationships Step 4: Add Invoice Statements to the App Summary 19 .Tutorial #2: Adding Relationships Notice how the invoice was automatically assigned a number. Tutorial #8: Creating a Public Web Page Using Sites. You might be wondering why Line Item Number is a text field. a bit more difficult. In the Units Sold field. Click Save. enter 4. why not make it an auto-number field..

The relationships work like foreign keys in relational databases. you can add business logic with formulas and validation rules in Tutorial #3: Using Formulas and Validation Rules on page 21. See Also: Tutorial #2: Adding Relationships Step 5: Create an Invoice Record 20 . and in the next tutorial you'll see how to sum the price of each invoice line item into the invoice statement. You'll learn about that later as well. The master-detail relationship allows you to aggregate information. you created relationships between the objects in your data model.Tutorial #2: Adding Relationships Summary In this tutorial. Now that you have built the basic application. The relationships also provide additional benefits: you can navigate to the related records in a user interface and a query language. yet they operate at a more abstract level. letting you concentrate on what matters (the relationships) instead of the underlying implementation.

where you can reference values in other cells of the spreadsheet. 3. and return a result. you will add a formula to perform an inventory check. This field will multiply the number of items with the price and act as a total for each line item. as described in Tutorial #2: Adding Relationships on page 13. and click New. perform calculations. 2. you will enhance the Warehouse app by adding a formula field to automatically calculate the total value for each line item.com platform lets you create formulas and field validation rules to help maintain and enhance the quality of the data entered in your app. and calculate other values based on your data. Duration: 20-30 minutes The Force. with formula fields and validation rules. ensuring that you can't create a line item for more merchandise than you have in stock. you reference fields in your app's records. you will add a new calculated field called Value to the line item. Navigate to the Line Item custom object page by clicking Your Name ➤ Setup ➤ Create ➤ Objects ➤ Line Item. The functions you use in formula fields and field validation rules are a lot like the functions you would use in a spreadsheet program. You will also use this new line item value and a property of the master-detail relationships to automatically total an invoice value.Tutorial #3: Using Formulas and Validation Rules Tutorial #3: Using Formulas and Validation Rules Level: Beginner. validate your data. Scroll down to the Custom Fields & Relationships related list. Finally. Choose Formula as the field type. In this tutorial. and click Next. 21 . Both formula fields and field validation rules use built-in functions that allow you to automatically manipulate your data. See Also: Step 1: Calculate a Value for Each Line Item Step 2: Calculate a Value for the Invoice Statement With a Roll-Up Summary Field Step 3: Check Inventory With a Validation Rule Step 4: Test the Validation Rule Step 5: Improve the Validation Rule Summary Step 1: Calculate a Value for Each Line Item In the first step of this tutorial. 1. However. Prerequisites Warehouse App You first need to create the basic Warehouse application and add relationships.

3. which allows you to do much more with these formulas. When you return to the detail page for the custom object. you can see there's a new field called Value. 2.Tutorial #3: Using Formulas and Validation Rules 4. In the Field Label and Field Name fields. choose Currency. as you have done here. enter Value. You should now see Unit_Price__c * Units_Sold__c in the text box. and then click Save. See Also: Tutorial #3: Using Formulas and Validation Rules Step 2: Calculate a Value for the Invoice Statement With a Roll-Up Summary Field Step 2: Calculate a Value for the Invoice Statement With a Roll-Up Summary Field Now that you have the total for each line item. In the Insert Merge Field drop-down list.. 8. Click Next. 22 . Scroll down to the Custom Fields & Relationships related list. 4. select Units Sold. select Unit_Price. In the Formula Return Type field. Because the line items have a master-detail relationship with the invoice statement. There's also an Advanced Formula tab. Click Next.. 9. you want to sum the value of each line item. 10. we can use a roll-up summary field to calculate this value. 7. 1. In the Field Label field. Click the Insert Operator drop-down list and choose Multiply. Tell Me More. You should now see Unit_Price__c in the text box. and click New. In the Insert Merge Field drop-down list. The formula you entered was quite straight forward: a simple multiplication of two field values on the same record. and click Next. The Formula field type is great for automatically deriving field values from other values. it makes sense to add them all to get the invoice total. Choose Roll-Up Summary as the field type.. enter Invoice Value and click Next. In this case. 5. 6. click Next again. Roll-up summary is a special type of field that lets you aggregate information about related detail (child) objects. Navigate back to the Invoice Statement custom object page by clicking Your Name ➤ Setup ➤ Create ➤ Objects ➤ Invoice Statement.

written in the same formula language that you used to create the formula field. 23 . displaying the total value of all the invoice line items. b. wait a few seconds and then refresh. 3. enter Order in stock. If the field shows an hour glass. For Roll Up Type field. Verify that your screen looks like the following and then click Next. The error condition formulas should evaluate to true when you want to display a message to the user.Tutorial #3: Using Formulas and Validation Rules 5. 1.. In the Rule Name field. Click Insert. and to display a message to the user if a field value is not valid. 7. You can test this new functionality by adding a new line item. In the Error Condition Formula area. Tell Me More. 2.. If you navigate back to an invoice statement record. 8. Scroll down to the Validation Rules related list. and click New. click Insert Field to open the Insert Field popup window. Select Merchandise > in the second column. In the Summarized Object list choose Line Items. d. c.. a. Navigate back to the Line Item custom object page by clicking Your Name ➤ Setup ➤ Create ➤ Objects ➤ Line Item. See Also: Tutorial #3: Using Formulas and Validation Rules Step 1: Calculate a Value for Each Line Item Step 3: Check Inventory With a Validation Rule Step 3: Check Inventory With a Validation Rule The fields that you define in objects can have validation rules. 4. In the Field to Aggregate list choose Value. Select Line Item > in the first column. Click Next again and then click Save. The validation rules can be used to determine what range of input is valid. 9. you'll see your new roll-up summary field in action. choose Sum. 6. Select Total Inventory in the third column.

Click Check Syntax to make sure there are no errors. 7.Total_Inventory__c < Units_Sold__c 5. If you do find errors. h. select Field. Tell Me More. Type the less-than symbol < so that the formula looks like this: Merchandise__r. Click Save.. that's what the Mechandise__r is doing. • Mechandise__r—Because the Merchandise object is related to the Line Item object. You can enter a formula directly into the Error Condition Formula area. fix them before proceeding.Total_Inventory__c < f. In the Error Message field. but as you saw here. 8. you can easily traverse the available objects and find the components you need for the formula.. i. Let's analyze the formula you created. then choose Units Sold from the drop-down list.Tutorial #3: Using Formulas and Validation Rules e. the platform automatically provides a relationship field that lets you navigate from a Line Item record to a Merchandise record. Click Insert and verify the code looks like the following. enter You have ordered more items than we have in stock. Select Units Sold in the second column. 24 . Select Line Item > in the first column. g. • • • Total_Inventory__c—This is the field you created to track the total amount of stock on a Merchandise record. Click Insert Field again. For the Error Location.Total_Inventory__c—This tells the system to retrieve the value of Total Inventory field on the related Merchandise record. Merchandise__r. 6. Merchandise__r.. Units_Sold__c—This refers to the Units Sold field on the current (Line Item) record.

See Also: Tutorial #3: Using Formulas and Validation Rules Step 2: Calculate a Value for the Invoice Statement With a Roll-Up Summary Field Step 4: Test the Validation Rule Step 4: Test the Validation Rule Now test the validation rule you created in Step 3. 5. you should only need to verify that the number of additional items is in stock. 1. Modify the Units Sold value to a number larger than the amount in stock. Click Cancel. Click Cancel. you shouldn't need to check inventory. and this is just what you want: it will only be true when the total inventory is less than the units sold. You can improve the validation rule to include these scenarios by using the ISNEW() function in your formula. In this case. you'll need to use the PRIORVALUE() function to tell you the prior value of the field before it was modified. Or if you increased the number of units sold. 2. 3. See Also: Tutorial #3: Using Formulas and Validation Rules Step 3: Check Inventory With a Validation Rule Step 5: Improve the Validation Rule Step 5: Improve the Validation Rule The logic in the validation formula is a little bit flawed! Imagine that you edit a record and decrease the number of units sold. which determines whether you are creating a new record. You should see an error indicating that there are not enough items in stock. As indicated on the Error Condition Formula page. Click Save. Scroll down to Line Items and click Edit next to one of the line items. Click on the Invoice Statements tab and select an existing invoice. the formula checks that the total inventory on the related merchandise record is less than the number of units being sold.Tutorial #3: Using Formulas and Validation Rules Putting it all together. 4. 25 . If it's not a new record. you need to provide a formula that is true if an error should be displayed.

then you've updated the record and decreased its units. this time to determine if the number of units has gone up or down. Tell Me More. For new records. Replace the existing formula with the following. FALSE. so you perform another conditional check. so you created a roll-up summary field to automatically add up the line item subtotals. ISNEW is the condition. not creating a new record. Merchandise__r. ensuring that at run time one of the two branches will be taken depending on the condition... IF( ISNEW().Total_Inventory__c < (Units_Sold__c . An invoice could be made up of multiple line items. 26 . If ISNEW is false. and next to Order in stock click Edit. 5. false otherwise.Tutorial #3: Using Formulas and Validation Rules 1. If the prior value was greater. then you've increased the number of units. you know that you're performing an update to an existing record. Navigate back to the Line Item custom object page by clicking Your Name ➤ Setup ➤ Create ➤ Objects ➤ Line Item. Click Check Syntax to make sure there are no errors.Total_Inventory__c < Units_Sold__c . Click Save.PRIORVALUE(Units_Sold__c)) ) ) 4. Scroll down to the Validation Rules related list. you return FALSE to indicate that there's no validation failure. 3. IF ( Units_Sold__c < PRIORVALUE(Units_Sold__c). This function returns true if you're creating a new record. If the prior value was smaller.. For the first formula you created a subtotal for each line item by multiplying the price of a product by the number of units that were ordered. so you have to check whether there's enough inventory to hold the difference between the new number of units and the old. by comparing it to its prior value using the PRIORVALUE function. Since you have enough stock. Merchandise__r. Let's look at this formula in a little more detail. 2. If ISNEW is true. you need to check that you have • • not sold more than you have in stock. then you simply check inventory as you did previously. • • • • IF is a conditional. See Also: Tutorial #3: Using Formulas and Validation Rules Step 4: Test the Validation Rule Summary Summary In this tutorial you created formula fields and validation rules that enhance and validate your app's data.

The first version of the rule was simple. and existing records with updates. These kinds of modifications can be applied to any field in your app when you want to make sure the data entered meets certain criteria. but you enhanced it to work with both new records. See Also: Tutorial #3: Using Formulas and Validation Rules Step 5: Improve the Validation Rule 27 .Tutorial #3: Using Formulas and Validation Rules You also learned how to define a validation rule to make sure you have enough items in stock.

In this tutorial. you've created the Line Item and the Merchandise objects with Price fields. The first carries the current price of a merchandise item into the newly created line item record. and formulas. Duration: 30-45 minutes Your company can operate more efficiently with standardized internal procedures and automated business processes. and the second updates the inventory whenever you update a product line item. Not only do they save time. Workflow rules can trigger actions (such as email alerts. you create and test two workflow rules. field updates. and outbound messages) based on time triggers.com app. Approval processes can automate all of your organization's approvals—from simple to complex. though you probably didn't notice that in the user interface because your default user is an administrative user. you can use workflow rules and approval processes to automate your procedures and processes. they also enforce consistency and compliance within your company's business practices. 28 . You will also create an approval process that requires explicit approval from the manager if an invoice is over $2000. See Also: Step 1: Populate the Line Item Price Using a Workflow Rule Step 2: Update Total Inventory When an Order is Placed Step 3: Test the Workflow Rules Step 4: Create an Email Template Step 5: Create an Approval Process Step 6: Create a Custom Profile Step 7: Create a User Step 8: Test the Approval Process Summary Step 1: Populate the Line Item Price Using a Workflow Rule At this point. Prerequisites Formulas and Validation You first need to create the roll-up summary field and validation rules as described in Tutorial #3: Using Formulas and Validation Rules on page 21. criteria. Now you'll create a workflow rule to populate the unit price on the line with the unit price on the merchandise at the time the line item is created. You can create this complex logic quite easily with a declarative workflow rule. You've also marked the Line Item Price field as read-only. In your Force.Tutorial #4: Using Workflow and Approvals Tutorial #4: Using Workflow and Approvals Level: Intermediate. tasks. who has access to all data.

Click Show Formula Editor. Make sure your page looks like the following and then click Save & Next. click Add Workflow Action and choose New Field Update. Select Line Item > in the first column. Select Use a formula to set the new value. In the Field to Update drop-down list.Tutorial #4: Using Workflow and Approvals 1. 14. 5. select Line Item as the object and click Next. click New Rule. 9. 13. Merchandise > in the second column. Click Your Name ➤ Setup ➤ Create ➤ Workflow & Approvals ➤ Workflow Rules. enter Line Item Created. 29 . select formula evaluates to true. and Price in the third column. In the text box. 6. select Line Item in the first box and Unit Price in the second. 4. in the Immediate Workflow Actions section. 8. The New Field Update wizard opens. 15. In the Name field. click Continue. Click Insert. In the Rule Name field. 12. 16. On the All Workflow Rules page. 10. 2. For Evaluation Criteria. 7. 11. Click Insert Field. In Step 3 of the Workflow Rule wizard. enter Insert Merchandise Price. In Step 1 of the Workflow Rule wizard. In the Rule Criteria field. enter true. If you see the Understanding Workflow page. 3. select Only when a record is created.

The reason this workflow rule runs only when a record is created (and never afterward) is that we don't want to increase the invoice price of an item after the item has been added to the invoice. If you now create a new line item. you want the total inventory of the Merchandise records to be automatically maintained. and that's always true. However. You can also use a formula to evaluate an expression. you will see that line item's unit price will automatically be set to the price of the related merchandise record. Click Save to close the New Field Update wizard and return to Step 3 of the Workflow wizard. As you create new invoices (which will default to "Open" status).Tutorial #4: Using Workflow and Approvals 17. The only trick to it is changing the 30 . if the item's price goes down.. click Done. But your users won't see that field because it was set to read-only. You'll make that happen later. click Activate. 19. The reason is that we want the field update to happen every time a record is created. it just wasn't necessary this time.. save it. the customer would appreciate being updated with the new price. its criteria are not evaluated when records are created or saved. 18.. Tell Me More. On the Specify Workflow Actions page. you see an input field for price. This can be accomplished with another workflow rule. Important: Forgetting to activate a new workflow rule is a common mistake. Remember that because you are an administrator. It would confuse a customer to suddenly find out the item's price is higher than what was advertised. See Also: Tutorial #4: Using Workflow and Approvals Step 2: Update Total Inventory When an Order is Placed Step 2: Update Total Inventory When an Order is Placed Ideally. You might be wondering why we've created a rule whose formula always evaluates to true. On the Workflow Rule page. If your rule is not active. and then view it. you want any updates to the line items to be reflected in the Total Inventory field you created on the Merchandise object.

otherwise proceed to the next step. select Invoice Statement: Status. you need to adjust the total inventory by the difference between the numbers of old and new units sold. select Line Item as the object and click Next. Click Insert Selected. IF ( ISNEW(). Click Check Syntax and make corrections if necessary. select Total Inventory. 6. 11. In the second. In the Rule Criteria field. For Evaluation Criteria select Every time a record is created or edited. Enter the following code. click Add Workflow Action and choose New Field Update. select Merchandise. In Step 1 of the Workflow Rule wizard.Total_Inventory__c . 31 . 8. In the Rule Name field.PRIORVALUE(Units_Sold__c)) ) 16. enter Line Item Updated. 2. 13. In the first Field to Update drop-down list. The New Field Update wizard opens. 9. If you see the Understanding Workflow screen. enter Update Stock Inventory. in the Immediate Workflow Actions section. Merchandise__r. Then for Operator. click New Rule. Under Value click the lookup icon and choose Open. In the Name field. 4. Select Use a formula to set the new value. 5.Units_Sold__c .(Units_Sold__c . Make sure your screen looks like the following and then click Save & Next. 14. But if you're updating a line item. select equals. On the All Workflow Rules page. Click Show Formula Editor. In the Field drop-down list. 3.Tutorial #4: Using Workflow and Approvals total inventory value. click Continue.Total_Inventory__c . 12. 7. 1. 15. In Step 3 of the Workflow Rule wizard. select criteria are met. If you're creating a new line item. Merchandise__r. 10. Click Your Name ➤ Setup ➤ Create ➤ Workflow & Approvals ➤ Workflow Rules. you need to decrease the total inventory by the number of units sold.

Click the Invoice Statements tab. 1. Click Save to close the New Field Update wizard and return to Step 3 of the Workflow wizard. 18. 4. Set Units Sold to 1000. 3. click Done. Click Save. On the Specify Workflow Actions page. Leave the Unit Price field blank. 5. 19. 2. • • • • In the Line Item Number field enter 2. 32 . On the Workflow Rule page. Then verify that its unit price is automatically set and that the total inventory on the stock has decreased. Next to the Merchandise field. Note that the unit price has been set to the same value as on the Wee Jet record. Select New Line Item and enter the following values.Tutorial #4: Using Workflow and Approvals 17. Click the invoice record you created earlier. click the lookup icon and select the Wee Jet merchandise record. click Activate. See Also: Tutorial #4: Using Workflow and Approvals Step 1: Populate the Line Item Price Using a Workflow Rule Step 3: Test the Workflow Rules Step 3: Test the Workflow Rules You can check to make sure your workflows are functioning as expected by creating a new line item. Click line item 2.

select Text and click Next. enter the following code and text. In the Email Template Name field.Tutorial #4: Using Workflow and Approvals 6. enter Large Invoice Template. In the Subject field. See Also: Tutorial #4: Using Workflow and Approvals Step 2: Update Total Inventory When an Order is Placed Step 4: Create an Email Template Step 4: Create an Email Template One of the business rules that you want to enforce in your workflow is that all invoices totaling over $2000 must be approved by a manager. just assume we're talking about whatever currency you're using. 6. Click New Template. Note: If your default currency is not set to US dollars. To implement this rule you need to create two additional elements: an email to be sent to the manager when an invoice exceeds $2000. Click Your Name ➤ Setup ➤ Communication Templates ➤ Email Templates. In the Email Body field. 1. 7. and an approval process for the manager to follow. Notice that the Total Inventory is down to 1000 from 2000 (or whatever you entered). and then click Save.Invoice_Value__c} on {!Invoice_Statement__c.OwnerFullName} submitted for approval an Invoice Statement that totalled {!Invoice_Statement__c. Verify that your screen looks like the following. Select Available For Use. enter A large invoice has been submitted.LastModifiedDate} 8. {!Invoice_Statement__c. In Step 1 of the Email Template wizard. 33 . 4. 3. In this step you create the email template that will be used by the workflow rule to generate and send the email. 2. 5. You create the approval process in the next steps. Now open the Wee Jet merchandise record by clicking on the Wee Jet link.

Click Your Name ➤ Setup ➤ Create ➤ Workflow & Approvals ➤ Approval Processes. See Also: Tutorial #4: Using Workflow and Approvals Step 3: Test the Workflow Rules Step 5: Create an Approval Process Step 5: Create an Approval Process In this step you create an approval process that requires explicit approval from the manager if an invoice is over 2000. 7. In the Name field. click the lookup icon and select the Large Invoice Template you just created. 4. In the Value field enter 2000. choose Invoice Statement. In the Operator drop-down list. a.Tutorial #4: Using Workflow and Approvals Tell Me More. 1.Invoice_Value__c}. 3. the user's manager is assigned as the approver. 6. this value will be dynamically substituted with the actual invoice value that generated the approval process. enter Large Invoice Value. Click Create New Approval Process and choose Use Jump Start Wizard from the drop-down list. Creating and using an approval process is just as easy as creating a workflow rule. choose Invoice Value. for example {!Invoice_Statement__c. 34 . This ensures that if a particular user starts the approval process. c. 5. b.. In the Manage Approval Processes For drop-down list. 2. Enter the following values in the Specify Entry Criteria area. In the Field drop-down list. choose greater than. The email body text that you just entered supports merge fields. Next to the Approval Assignment Email Template field. Select Automatically assign an approver using a standard or custom hierarchy field and choose Manager for the hierarchy field. You'll create a user named Bob Smith in the next step. At the time the email is generated...

9. You'll see a warning that you must activate the approval process. but before it can run. Click OK. 35 . Click Approval Processes to return to the approval list. Click Save. 10. You've finished creating the approval process. and when they're rejected. 14. Choose A specific value and select Closed. Create new field update actions by clicking Add New and selecting Field Update for each related list in the following table. Configure each field update action as shown.Tutorial #4: Using Workflow and Approvals 8. Click Activate to activate the approval process. you have to define what happens to records when they're first submitted. Set Initial Approval Status Status Set Final Approval Status Set Final Rejection Status Status Status 12. Related List Initial Submission Actions Final Approval Actions Final Rejection Actions Name Field to Update Picklist Options Choose A specific value and select Pending. when they're approved. Choose A specific value and select Open. Click View Approval Process Detail Page. 13. 11. Click Save.

See Also: Tutorial #4: Using Workflow and Approvals Step 4: Create an Email Template Step 6: Create a Custom Profile Step 6: Create a Custom Profile A profile is a collection of permissions and other settings associated with a user or a group of users. if the record is rejected. Verify that your screen looks like the following. This makes sense: if someone submits a record for approval. 7. 5. You can change these permissions in custom profiles.. Click New.com . 1. Line Items. 6.. In the Profile Name field. and then click Save. In the Clone Profile field. Default actions are associated with a few of the approval steps.” and “Delete”) are disabled for most profiles. 2. 3. Click Your Name ➤ Setup ➤ Manage Users ➤ Profiles. Scroll to the bottom of the profile edit page. you'll enable object permissions so your users can access the objects. If you're using Free Edition. 36 . enter Basic User. Your organization has a number of standard profiles already defined. The Initial Submission actions and Final Approval actions both lock the record. you'll create a custom profile that you can assign to users who need to access the custom objects in the Warehouse app. it should be unlocked so changes can be made. select Standard User. but not standard profiles. and under Custom Object Permissions.” “Create. while the Final Rejection action unlocks it. and Merchandise objects.Tutorial #4: Using Workflow and Approvals Tell Me More. Create. 8. In this step. and Delete boxes for the Invoice Statements. it shouldn't be changed in the meantime. This security setting ensures that access to custom objects and their data is only explicitly granted to users. Then in your new custom profile.Free User.” “Edit. 4. Likewise. Click Save. If you create a custom object. You'll create the new user in the next step. Edit. the permissions to access that object (“Read. select Force. select the Read.. On the detail page for your new profile. click Edit.

. See Also: Tutorial #4: Using Workflow and Approvals Step 5: Create an Approval Process Step 7: Create a User Step 7: Create a User When you create a Force. The Username field defaults to your email address. it's automatically enabled to allow multiple users to log in. In the User License field. 3. If you need to edit many profiles. so that a user sees only his or her records or those of his or her manager. You can also strictly enforce data sharing. You've just seen how easy it is to create and edit a custom profile. In the Last Name field. You use this configuration to make sure that if the new user creates an invoice that meets certain conditions. select Salesforce. On the All Users page. select Basic User. or make them completely invisible. In this step. Enter the following information: • • • • • In the First Name field. enter Bob. Note: Write down Bob's username (his imaginary email address).. 1.. 37 . 2.com application. you create a new user and link that user to your current user's account via the Manager field. select the user you created when you signed up for your organization. you can grant read-only access to fields to a certain group of users. in the form of an imaginary email address. enter Smith. Now you can customize the application by configuring it to function differently depending on the profile of the user logging in. In the Email field. For example. so that you will receive the approval requests routed to Bob Smith. the invoice is routed to his or her manager. click New User.com online help. In the Alias field. but you'll need to create a unique username for Bob. In the Profile field. For more information. • • • In the Manager field. enter your own email address. see “Editing Profiles Using Profile Lists” in the Salesforce.Tutorial #4: Using Workflow and Approvals Tell Me More. because you'll be logging in as him shortly. Click Your Name ➤ Setup ➤ Manage Users ➤ Users. enter bsmith. you can use enhanced profile list views to create a custom list view of your profiles and then edit the profiles from the list.

1. You should now receive an email confirming the creation of the new user. you want its status updated to Closed. See Also: Tutorial #4: Using Workflow and Approvals Step 6: Create a Custom Profile Step 8: Test the Approval Process Step 8: Test the Approval Process We can now put the approval process together and see it in action. you have to modify the Basic User profile to use the Warehouse app. Select the Items to Approve option. skip this step. if it is not already selected. When the manager logs in. select Default. he or she can approve (or reject) the invoice. 4.) 1. Next to the Basic User profile. 2. he will be able to click the new Submit for Approval button on the invoice statement. and so on. And if not. your business process might require you to email the invoice owner and ask for confirmation. you want it to remain in the original Open status. (If you're using Free Edition. click Edit next to VolunteerForce Home Page. so it must be the default. Before testing the approval process. 3. (If you're using Developer Edition. and then click Save. 38 . 2. The app will send an email to his manager (using the email template you created earlier) and lock the record. Next to Warehouse. Free Edition users only get access to one app.) 3. click Edit. make sure that your Home page can display items that require approval. If the manager approves the invoice. Click Your Name ➤ Setup ➤ Manage Users ➤ Profiles. In a real-world scenario. Click Edit next to your home page layout. There's one more setup step to complete the approval process. Click Save. Click Your Name ➤ Setup ➤ Customize ➤ Home ➤ Home Page Layouts. Click Next. and the total value of the invoice is greater than $2000. If Bob Smith creates an invoice. preventing Bob from making any more changes.Tutorial #4: Using Workflow and Approvals 4. so don't log in as Bob Smith yet or you'll have to immediately log back in as the administrator. In Free Edition. before Bob can login and use the Warehouse app.

you need to log out of your administrator account and log back in as a standard user. Since you're the manager.Tutorial #4: Using Workflow and Approvals While developing the application. From your Approval Process detail page.. you see the pending approval request on the Home tab. 2. Tell Me More. Click the Invoice Statements tab. If this is your first time logging in as Bob. Click New and create an invoice statement. you may have to change your password. An Approval field allows the manager to approve or reject the invoice and continue the workflow. the user you created earlier. 4. 1.) The record is locked until the manager approves the invoice. 8. for purposes of this tutorial. (You may have to scroll down to see it. Click View Diagram. Click Submit for Approval.. click Approval Process and select the process you created. Go ahead and Approve it. To create a new record and test the approval process. 3. 39 . Log out of the application. you can check your email to verify this result. When you log in to the application as administrator. An email is sent to Bob Smith's designated manager who. 7. 1. Click Save. In the familiar Your Name ➤ Setup area. 2. is you the administrator. you've been logged in as an administrator.. 5. Log in as Bob Smith. Select the Warehouse app. Add a New Line Item and enough units sold to make the invoice value greater than $2000. 6. The approval process diagram appears in a separate browser window. you can see a nice diagram of the approval process and the actions that will fire at each step.

follow the instructions in Creating and Logging into a Sandbox on page 94. See Also: Tutorial #4: Using Workflow and Approvals Step 8: Test the Approval Process 40 . Your sandbox copy won't duplicate your existing records for you. so after you log in. and the invoice statement described in Step 5: Create an Invoice Record on page 18. The workflow rule automatically updates price and inventory across different objects. you need to recreate the Wee Jet record described in Step 5: Create a Merchandise Record on page 11.Tutorial #4: Using Workflow and Approvals See Also: Tutorial #4: Using Workflow and Approvals Step 7: Create a User Summary Summary Workflow rules and approval processes help you automate your business processes and enforce your standards. and then sends an email alert to the designated recipient. Important: If you're using Free Edition. If you're not developing in a sandbox now. the remaining tutorials require that you develop in a sandbox. The approval process runs whenever a condition is met.

Prerequisites Basic Knowledge For this tutorial. However. see Creating a Project in the Force. which is ideal for juggling multiple records and complex logic. or use the Force. as you've been doing up to this point.com IDE plugin: wiki. If you have not created a sandbox yet.com/index.com IDE. it helps to have basic knowledge of an object-oriented programming language like Java or C#. and many other features that make development—especially team development—highly productive. you will pass the savings along to your customers. Web services. so familiarity with Eclipse is useful but not necessary. In that case you'll need Eclipse 3.3 or 3. If you don't have the IDE installed.com IDE on page 94. To do this. all development must be done in your sandbox. For example you can use it to write triggers. but it is not required.com. If you need help creating a project.com IDE. code insight. 41 . Duration: 20-30 minutes Apex is a strongly-typed. This tutorial can also be completed in the Force.com_IDE.com: you can either use the online environment. you'll create an Apex trigger that updates all open invoices whenever the merchandise price decreases. Note: If you're using Free Edition. you know that it has syntax highlighting. and program controllers in your app's user interface layer. In this tutorial you'll create additional logic using Apex. A trigger is a set of code that fires at a particular time in the lifecycle of a record. Apex is used to add programmatic business logic to applications. The business case you'll be working on requires that when a price for a piece of merchandise goes down. You've already added business logic using the declarative workflow environment.php/Force. Software Requirements You can use the Force.developerforce. if you are already familiar with the IDE. see Creating and Logging into a Sandbox on page 94. Java™-like programming language that runs on Force.Tutorial #5: Adding Business Logic with Apex Tutorial #5: Adding Business Logic with Apex Level: Advanced.4 and the Force. object-oriented.com IDE for this tutorial if you want to. In this case. it will take a moment to set up. There are two ways to develop applications on Force. you will create a trigger that fires after a merchandise record is updated.

com IDE: 1. 4. Instructions are provided for both tools. the affected object. In the Package Explorer. click Refresh Objects. and an action that fires the trigger. See Also: Step 1: Create an Apex Trigger Definition Step 2: Define a List Variable Step 3: Iterate Through the List and Modify Price Step 4: Test the Trigger Summary Step 1: Create an Apex Trigger Definition The first thing you need to do is create the trigger definition. You can create triggers in the Web interface or in the Force. To create a trigger in the Web interface: 1. right-click your project and click New ➤ Apex Trigger. enter HandleProductPriceChange for the name. because if you've made syntax errors. which will save your work and let you continue editing.) 4. 3.” “Modify All Data. On the Merchandise detail page. make sure that you have the proper permissions to create Apex classes. 42 . which contains the trigger name. scroll down to Triggers and click New. Replace <name> and <events> so that the code matches the following: trigger HandleProductPriceChange on Merchandise__c (after update) { } 5. To create the trigger in the Force. If you're using the Web interface.” and “Author Apex” permissions Since this tutorial involves working with Apex. choose Merchandise__c. Click Your Name ➤ Setup ➤ Create ➤ Objects in the sidebar menu. In the Object drop-down list. Saving your work at this point also verifies that you've entered the code correctly. Select after update. 3. (Ignore the warning that pops up about how you must select an operation. Note: If this object doesn't appear in the list of object. In the dialog box. 2. click Quick Save. the system won't let you save.Tutorial #5: Adding Business Logic with Apex “Developer Mode. 2.com IDE. Click your Merchandise custom object.

Click Finish and the file opens in the Editor. Apex triggers are fired in response to data actions. let's break up the trigger definition and examine each part. so if you like to use lowercase. Note: We try to make our code samples fit on the page. Apex isn't case sensitive. Apex ignores white spaces. so if the format of your code doesn't look exactly the same. j. Note: For the sake of brevity. so you'll select only those that are in the set of records that triggered this code to run and have their status set to Negotiating.new FOR UPDATE]. { }—The code that goes between the curly brackets is called the body and determines what the trigger does.Price__c FROM Line_Item__c j WHERE j. The trigger you defined fires after a record is updated. 2.. Between the curly braces of your trigger definition. 43 . your Merchandise__c custom object. that's OK. but it's now ready to accept any logic that you want to execute when a Merchandise record is updated.. // update invoice line items associated with open invoices List<Line_Item__c> openLineItems = [ ]. Also.Unit_Price__c.id IN :Trigger. such as inserts. for example. you can enter select instead of SELECT. Before we get to the trigger logic. enter the following comment and then declare a list variable. updates and deletes—either before or after one of these events.. so there are often line breaks where they aren't strictly needed. Between the square brackets. (after update)—The action that fires the trigger. See Also: Tutorial #5: Adding Business Logic with Apex Step 2: Define a List Variable Step 2: Define a List Variable The first thing you need to do is define a list variable that will hold a list of line items. on Merchandise__c—The object the trigger acts on— in this case. • • • • HandleProductPriceChange—The name of the trigger.Invoice_Statement__r.Tutorial #5: Adding Business Logic with Apex 5.Status__c = 'Negotiating' AND j. You'll code the trigger body next.Merchandise__r. enter a query that pulls information from your Line Item custom object.Merchandise__r. Tell Me More. You don't need all the line items. but its good practice to comment your code. we won't comment everything here. Your trigger doesn't do anything yet. List<Line_Item__c> openLineItems = [SELECT j. 1.

Tutorial #5: Adding Business Logic with Apex

Tell Me More....
The openLineItems list holds a list of records from your Line_Item__c custom object. What's contained in that list is determined by the query inside the square brackets, which is written in the Salesforce Object Query Language (SOQL). Let's take a look at that query in detail. • • • • •
SELECT—Determines which fields are retrieved on the object. FROM—Determines which object or objects you want to access. The “j” in Line_Item__c j is an alias: it is a convenient shorthand that allows you to refer to Line_Item__c as “j”. WHERE—This is the start of the condition statement. In this case you want to return only those records where the status

is Negotiating. AND—This is the second condition of your statement. It pulls only the unique IDs of the records that are new. The code uses a special variable, Trigger.new, which is automatically initialized with the identifiers of the records being updated. FOR UPDATE—This tells the platform to lock the records, preventing other program or users from making updates to them. The lock remains until the trigger is complete.

See Also:
Tutorial #5: Adding Business Logic with Apex Step 1: Create an Apex Trigger Definition Step 3: Iterate Through the List and Modify Price

Step 3: Iterate Through the List and Modify Price
In the previous step, you created a list of line items and stored it in a variable called openLineItems. Now you can iterate through the list using a for loop and modify an item's original price if its new price is lower. 1. Declare a for loop.
for (Line_Item__c li: openLineItems) { }

2. Between the curly brackets, enter a conditional if statement.
for (Line_Item__c li: openLineItems) { if ( li.Merchandise__r.Price__c < li.Unit_Price__c ){ } }

3. Between the for loop's curly braces, enter code that updates the price.
for (Line_Item__c li: openLineItems) { if ( li.Merchandise__r.Price__c < li.Unit_Price__c ){ li.Unit_Price__c = li.Merchandise__r.Price__c; } }

4. The for loop is complete. Now you want to update the line items. Before the trigger's final curly brace, add the following.
update openLineItems;

44

Tutorial #5: Adding Business Logic with Apex

5. During development you typically leave a trigger inactive. To try out the trigger, you'll need to activate it. • • If you're using the Web interface, select the Is Active checkbox, which becomes available after saving the trigger. If you're using the IDE, click the Metadata tab and change the status value to Active.

6. Verify that your code looks like the following and then Save.
trigger HandleProductPriceChange on Merchandise__c (after update) { List<Line_Item__c> openLineItems = [SELECT j.Unit_Price__c, j.Merchandise__r.Price__c FROM Line_Item__c j WHERE j.Invoice_Statement__r.Status__c = 'Negotiating' AND j.Merchandise__r.id IN :Trigger.new FOR UPDATE]; for (Line_Item__c li: openLineItems) { if ( li.Merchandise__r.Price__c < li.Unit_Price__c ){ li.Unit_Price__c = li.Merchandise__r.Price__c; } } update openLineItems; }

Tell Me More....
The final statement, update openLineItems, updates the records in the database. That's simple enough, but what about that for loop? • • •
for (Line_Item__c li: openLineItems) { }—Iterates over the list of open line item. As you iterate, the current line item is assigned to the variable li. if (li.Merchandise__r.Price__c < li.Unit_Price__c ) { }—Check to see if the price on the merchandise

record is lower than the current price. You only want to take an action if this is true. li.Unit_Price__c = li.Merchandise__r.Price__c;—Finally, update the unit price on the current line item (assigned to variable li) with the new merchandise price.

See Also:
Tutorial #5: Adding Business Logic with Apex Step 2: Define a List Variable Step 4: Test the Trigger

Step 4: Test the Trigger
Now let's test the trigger in the app. First you need to create a new invoice statement and order at least one product, or modify an existing one. The only requirement is that you change the status field of the invoice statement to Negotiating. Then you'll

45

Tutorial #5: Adding Business Logic with Apex

lower the unit price of a merchandise item used in one of the line items of that invoice, and verify that your line item and invoice values are updated. 1. 2. 3. 4. 5. 6. 7. 8. Click the Invoice Statements tab. Click the name of an existing invoice statement. Change its Status to Negotiating and click Save. Take note of the Total Value of the invoice. Now click on a Line Item, and note its Unit Price. Click the Merchandise tab, and select the Wee Jet record (or any other item used in the line items). Edit the record, lowering the unit price. If you want an extreme reduction, change it to .01. Navigate back to the Invoice and the Line Item. Note how the values of the line item and the invoice have automatically changed.

Tell Me More....
You may have noticed that this trigger is a little wasteful: it initializes and operates on a list of all line item records that belong to invoice statements under negotiation. However, just because a merchandise record was updated, that doesn't mean your trigger should update the record. For example, you may have updated the merchandise record's description, or increased its price, and neither of these cases requires the trigger to fire. Ideally this trigger should iterate over the Trigger.new set (the list of Merchandise records that have been updated), creating a new set of these records that pass the price criterion, and only then retrieve the related line item records.

See Also:
Tutorial #5: Adding Business Logic with Apex Step 3: Iterate Through the List and Modify Price Summary

Summary
In this tutorial, you built on the application by adding business logic that updates all open invoices when the unit price of a merchandise item goes down. To do this, you defined a trigger that executes whenever a merchandise record is saved with a lower unit price. Triggers are very useful in scenarios such as these—when you need to update multiple records on a particular condition. You can have more than one trigger associated with an object that can be triggered under different events and conditions. An important part of creating Apex triggers is making sure you have automated tests that verify that your trigger works as it should. You'll learn about testing in Tutorial #6: Adding Tests to Your Application on page 47.

See Also:
Tutorial #5: Adding Business Logic with Apex Step 4: Test the Trigger

46

com/index. Duration: 20-30 minutes Testing is one of the most important steps in developing any application.com IDE plugin: wiki. Software Requirements You can use the Force. see Creating a Project in the Force.com IDE for this tutorial if you want to. the platform requires that you test any Apex you write before that code can be deployed to a production environment. but it also benefits the platform. In this tutorial you'll write and execute a unit test. To create a new Apex class in the Web interface: 47 . To that end. To facilitate testing. All Apex code has a set of limits that determine how many resources may be consumed. In that case you'll need Eclipse 3.com_IDE. but also that it doesn't exceed these limits.com IDE on page 94. In this step you create the class to contain the unit tests.Tutorial #6: Adding Tests to Your Application Tutorial #6: Adding Tests to Your Application Level: Advanced. For example.php/Force. there is a set limit on the number of queries that can be performed in a trigger.developerforce. If you need help creating a project. See Also: Step 1: Create an Apex Test Class Step 2: Add Test Methods to the Class Step 3: Write Code to Execute the Trigger Step 4: Execute the Test Step 5: View Code Coverage and Improve Tests Summary Step 1: Create an Apex Test Class All unit tests are contained in Apex classes. Prerequisites Apex Tutorial You first need to create an Apex trigger as described in Tutorial #5: Adding Business Logic with Apex on page 41. which exercises the Apex trigger you just created.4 and the Force. Testing ensures that your code behaves as it should and doesn't consume resources unnecessarily. Apex supports unit tests. Not only does testing benefit you (you will have more confidence in the applications you write). to ensure that no backward compatibility problems are introduced.3 or 3. Good tests ensure that your code not only behaves as it should. which programmatically validate the code behavior and expected results. Tests are also run before a new release of the platform is made available.

To create a new Apex class in the Force. which creates an invoice statement and inserts it into the database. 3. 2. enter the following code. Click Finish to create the class. 1. Between the curly braces. @isTest private class TestHandleProductPriceChange { } 4. Tell Me More. static testMethod void testPriceChange() } { Note: If you're using the IDE. 2.Tutorial #6: Adding Tests to Your Application 1. The @isTest annotation tells Force.com IDE: 1. 3. right-click your project folder. only works when records are updated. The trigger that you created.com that all code within the Apex class is code that tests the rest of your code. In the IDE. replace the generated comment and code. enter TestHandleProductPriceChange for the name. and add these to the database. Click New. See Also: Tutorial #6: Adding Tests to Your Application Step 2: Add Test Methods to the Class Step 2: Add Test Methods to the Class Now you can add a method to the class that will do the actual testing. In the Template field. 2. Click Quick Save to save your work and continue editing. Then click New ➤ Apex Class.. You will now create test methods within this class that perform the actual tests. add the following code. In the editor pane. You want the method to create an Invoice Statement as well as Merchandise and Line Item records.. So the first thing you need to do is create test records in the database.. Invoice_Statement__c invoice = new Invoice_Statement__c(Status__c = 'Negotiating'). Between the curly braces. choose Test Class. Click Your Name ➤ Setup ➤ Develop ➤ Apex Classes. Start by creating the test method that will contain your three test procedures. insert invoice. 48 . On the Create Apex Class page. 4. which you want to test. enter the following code.

the system won't count your setup code towards the governor limits. Units_Sold__c = 6) }. Total_Inventory__c = 10). 4. raising its price. Line_Item__c[] lineItems = new Line_Item__c[] { new Line_Item__c(Invoice_Statement__c = invoice.id. 1. which is the condition you need for the trigger to fire.price__c = 20. add the following lines. Merchandise__c[] products = new Merchandise__c[]{ new Merchandise__c(Name = 'item 1'. Unit_Price__c = 10. update products. See Also: Tutorial #6: Adding Tests to Your Application Step 1: Create an Apex Test Class Step 3: Write Code to Execute the Trigger Step 3: Write Code to Execute the Trigger The code in your test method doesn't really do much yet: it won't cause your trigger to execute. as that only happens when you update the price of a Merchandise record. directly below insert products. Testing also ensures that your code doesn't exceed certain governor limits—which limits the resources your Apex code may use. Price__c = 10.id. Merchandise__c = products[0]. Units_Sold__c = 3). insert lineItems.id. ensuring that your test is a more accurate reflection of how it would behave in a production environment. Merchandise__c = products[1]. The system will not consider the setup code and database operations that precede it to be part of the test. Description__c = 'test product 1'. Directly below insert invoice. Note: This code modifies the price of one of the Merchandise records. which is part of the testing framework that marks the point in your test code when your test actually begins. products[0]. You now need to write the code that will fulfill the other conditions for the trigger to fire: you need to lower the price of a piece of merchandise. enter the code to add line items. After insert lineItems. Price__c = 11. Then. Unit_Price__c = 11. 49 .startTest().. Note how the invoice statement that you created has a status set to Negotiating. add the code to create new merchandise records. By marking where your actual test begins and ends. Test.id.Tutorial #6: Adding Tests to Your Application 3. Total_Inventory__c = 10) }.stopTest(). Test. new Merchandise__c(Name = 'item 2'. It then calls startTest(). insert products. You'll do that in the next step. new Line_Item__c(Invoice_Statement__c = invoice. You have now set up the data. Description__c = 'test product 2'.

new Line_Item__c(Invoice_Statement__c = invoice.com IDE by right-clicking the class name in the Package Explorer and choosing Force.id. and also check code coverage.price__c = 20. Ideally.id.assert(lineItems[0]. but you can also execute tests in the Force. because the price was raised in the setup code. you need to check whether the price in the line items has changed. unit_price__c FROM Line_Item__c WHERE id IN :lineItems].com has a testing framework that lets you execute tests. lineItems = [SELECT id. system. Line_Item__c[] lineItems = new Line_Item__c[] { new Line_Item__c(Invoice_Statement__c = invoice. insert invoice. Add the following code after Test. The remainder of this tutorial uses the Web interface. but you should be able to follow along easily in the IDE. Note: These steps show how to execute steps in the Web interface. Merchandise__c = products[1].id. Description__c = 'test product 2'.id. new Merchandise__c(Name = 'item 2'. Description__c = 'test product 1'. system. it shouldn't have.assert(lineItems[0]. and look at the resulting code coverage. Test. Units_Sold__c = 6) }. Unit_Price__c = 10. Now that you have updated the products. Verify that your code looks like the following and then Save. You are now going to execute the tests.stopTest(). lineItems = [SELECT id. Units_Sold__c = 3). unit_price__c FROM Line_Item__c WHERE id IN :lineItems]. products[0].Tutorial #6: Adding Tests to Your Application 2.com ➤ Run Tests. update products. Total_Inventory__c = 10) }. Unit_Price__c = 11. Price__c = 10. 3. 50 .startTest(). Price__c = 11. @isTest private class TestHandleProductPriceChange { static testMethod void testPriceChange() { Invoice_Statement__c invoice = new Invoice_Statement__c (Status__c = 'Negotiating').unit_price__c == 10). } } See Also: Tutorial #6: Adding Tests to Your Application Step 2: Add Test Methods to the Class Step 4: Execute the Test Step 4: Execute the Test Force. Merchandise__c[] products = new Merchandise__c[]{ new Merchandise__c(Name = 'item 1'. insert lineItems. insert products. Merchandise__c = products[0].stopTest(). Total_Inventory__c = 10). Test.unit_price__c == 10).

for example. Navigate to your test class by clicking Your Name ➤ Setup ➤ Develop ➤ Apex Classes. • It indicates whether your tests were successful or not. Click Run Test and you'll see output similar to the following.Tutorial #6: Adding Tests to Your Application 1. or only some portion of. does it execute all. that result would be flagged here. It provides detail about the execution of the test. The term code coverage refers to how much of your production code is covered by testing code.assert statement that you added to the test had failed. • • Note also how the result page shows that you provided 80% coverage of the HandleProductPriceChange trigger. the production code? If it only executes a portion of the code. Adding lots of asserts is a great way for you to test the expected behavior of your code. If the boolean condition in the system. which we'll call production code. In the next step. which we'll call test code. See Also: Tutorial #6: Adding Tests to Your Application Step 3: Write Code to Execute the Trigger Step 5: View Code Coverage and Improve Tests Step 5: View Code Coverage and Improve Tests You have written two sets of code. This result tells you a number of important things. It indicates code coverage: how many lines of code you executed in some other class or trigger. That's enough code coverage to deploy. By looking through the Debug Log. 51 . you can see that your Order_in_Stock validation rule has fired. and then click your test class. how many queries you executed. and you have your code in the test class. In other words: when someone runs your testing code. 2. you'll view the code coverage to see where you need to add more test cases to bring it up to 100%. that could mean your production code contain bugs in the untested code. You have your trigger. and more. And you can see which records you created. You can make these concepts a little more concrete by looking at a graphical code coverage chart. but we strive for perfection. TestHandleProductsPriceChange.

3.price__c = 20. That red line is good indicator that your test isn't complete. Now click Run Test again. 2. // raise price products[1]. keep using it. click 80. Synchronizing is easy (right-click your class and choose Force. System.assert(lineItems[1]. but it's even easier to avoid! 1. The Code Coverage page opens.unit_price__c == 5). 4. Click Edit. In the Code Coverage section. // unchanged System. Starting with products[0]. update products.unit_price__c == 10).com ➤ Synchronize with Server).startTest(). Close the Code Coverage window and then click Your Name ➤ Setup ➤ Develop ➤ Apex Classes and select your test class TestHandleProductPriceChange. In this case. Test.price__c = 5. lineItems = [SELECT id. The red highlight marks lines that have not been executed. unit_price__c FROM Line_Item__c WHERE id IN :lineItems].stopTest(). // changed!! 6.Tutorial #6: Adding Tests to Your Application Note: If you have been using the Force.com IDE for this tutorial. Click Save. // lower price Test.assert(lineItems[0]. products[0]. Developing in both the IDE and the Web interface at the same time requires that you synchronize with the server every time you switch back and forth. replace the code up to the next curly brace with the following. The blue highlight marks lines of code that have been covered (executed) as a result of our test method. 5. 7. 52 . we only raise it. line 12 wasn't executed because we don't lower the price of a merchandise item. and you'll see that you have 100% code coverage. So let's modify your test method to improve your code coverage.

Creating unit tests as you develop is necessary for deployment and it's also the key to successful long-term development. See Also: Tutorial #6: Adding Tests to Your Application Step 5: View Code Coverage and Improve Tests 53 . It should also check other status values. But it's important to note that code coverage isn't the only goal for testing. then raising or lowering the price shouldn't have any effect. Right now it only checks invoice statements that have a status of Negotiating. and the test case you have just written misses one.Tutorial #6: Adding Tests to Your Application See Also: Tutorial #6: Adding Tests to Your Application Step 4: Execute the Test Summary Summary In this tutorial you created tests for the Apex trigger and saw how the integrated testing tools can help you attain 100% code coverage. For example. if an invoice statement does not have a status of Negotiating. ideally you should also check all possible scenarios.

Prerequisites Basic Knowledge For this tutorial. as well as update the counts on each. Select the Development Mode checkbox and click Save. The purpose of the count sheet is to update the computer system with a physical count of the merchandise. and an Apex-based controller model. you will use Visualforce to create a new interface for the Warehouse application that displays an inventory count sheet that lets you list all Merchandise inventory. Duration: 30–45 minutes Visualforce is a component-based user interface framework for the Force. Click Edit. Development Mode also adds an Apex editor for editing controllers and extensions.Tutorial #7: Building a Custom User Interface Using Visualforce Tutorial #7: Building a Custom User Interface Using Visualforce Level: Intermediate. It allows you to see code and preview the page at the same time. Visualforce supports the Model-View-Controller (MVC) style of user interface design. in case they are different. Click Your Name ➤ Setup ➤ My Personal Information ➤ Personal Information. See Also: Step 1: Enable Visualforce Development Mode Step 2: Create a Visualforce Page Step 3: Add a Stylesheet Static Resource Step 4: Add a Controller to the Page Step 5: Display the Inventory Count Sheet as a Visualforce Page Summary Step 1: Enable Visualforce Development Mode Development Mode embeds a Visualforce page editor in your browser. 3. In this tutorial. 2. and is highly flexible.com platform. 54 . it helps to have basic knowledge of markup languages like HTML and XML. Visualforce gives you a lot more control over the user interface by providing a view framework that includes a tag-based markup language similar to HTML. a library of reusable components that can be extended. In previous tutorials you built and extended your application by using a user interface that is automatically generated. 1. but it is not required.

com/apex/CountSheet. 3. It should look like this. if your Salesforce. The Page Editor tab displays the code and a preview of the new page (which has some default text). the new URL would be https://na1. Click the Create Page CountSheet link to create the new page. You will get an error message: Page CountSheet does not exist. 55 . In your browser. Click the Page Editor link in the bottom left corner of the page.salesforce. add the text /apex/CountSheet to the URL for your Salesforce.com instance is https://na1.Tutorial #7: Building a Custom User Interface Using Visualforce See Also: Tutorial #7: Building a Custom User Interface Using Visualforce Step 2: Create a Visualforce Page Step 2: Create a Visualforce Page In this step you create a Visualforce page that will serve as an inventory count sheet.com instance. 1. 2. For example.salesforce.com.

Most Web pages and Web designers use CSS. 3. 56 . it can be referenced by any of your Visualforce pages. a standard Web technology. To add a style sheet as a static resource: 1. Click Browse and find the styles. Back in the app. so we've created one for you. such as <h1>. 5. for this purpose. you have to upload it as a static resource. 4. font. The page reloads to reflect your changes. and go ahead and remove the comments. Download the file and save it to your desktop. In your browser. <apex:page> <h1>Inventory Count Sheet</h1> </apex:page> 5. so you're going to use a custom stylesheet (CSS file) to specify the color. In order for your pages to reference a stylesheet.. Click the Save icon at the top of the Page Editor.com. so change the contents of the <h1> tag to Inventory Count Sheet. A static resource is a file or collection of files that is stored on Force.zip file you downloaded. That's because a Visualforce page combines HTML tags.. Notice that the code for the page looks a lot like standard HTML. Once your stylesheet is added as a static resource. The code for the page should now look like this. Tell Me More. go to developer. with Visualforce-specific tags.. and arrangement of text on your page.com/workbook/styles. click Your Name ➤ Setup ➤ Develop ➤ Static Resources and click New.force. In the Cache Control picklist choose Public.Tutorial #7: Building a Custom User Interface Using Visualforce 4. enter styles. 2. You don't really want the heading of the page to say “Congratulations”. In the Name field. which start with <apex:> See Also: Tutorial #7: Building a Custom User Interface Using Visualforce Step 1: Enable Visualforce Development Mode Step 3: Add a Stylesheet Static Resource Step 3: Add a Stylesheet Static Resource You want your Warehouse application to look slick.

Note: If your Visualforce pages are exposed on a public website. the title is in a different font and location. 5. Just as you did when you created the page.styles. Verify that your code looks like the following: <apex:page standardStylesheets="false" showHeader="false" sidebar="false"> <apex:stylesheet value="{!URLFOR($Resource. 57 . Click the Save icon at the top of the Page Editor. the header. Note how the page now looks very different. Now specify the location of the stylesheet as shown.css')}" /> <h1>Inventory Count Sheet</h1> </apex:page> 7. 2. which gives you a drop-down list of the elements that are available in this context. so add a new line below the first <apex:page> tag and type <apex: 4. then Force. and the standard header and sidebar are no longer present. Now you need to modify your Visualforce page to reference the stylesheet. The editor has code insight. <apex:page standardStylesheets="false" showHeader="false" sidebar="false"> 3. Now you need to tell the page where to find the stylesheet.com uses a global content delivery network of cache servers to hold copies of your static files. add the text /apex/CountSheet to the URL for your Salesforce.Tutorial #7: Building a Custom User Interface Using Visualforce 6. Click Save. select it. and the sidebar.css')}" /> 6.com instance. Modify the attributes of the <apex:page> tag and enter the following code to remove the standard stylesheet.styles. 'styles. 1. 'styles. Start typing stylesheet and when you see apex:stylesheet. <apex:stylesheet value="{!URLFOR($Resource.

. If the syntax looks familiar. For example. Click the Save icon at the top of the Page Editor. In our case. the controller is usually an Apex class. or create custom controllers from scratch. so in many cases you don't need to write the code for the controller yourself. the variable will be available to you in the body of the page and it will represent a list of Merchandise records. 1. <apex:page standardStylesheets="false" showHeader="false" sidebar="false" standardController="Merchandise__c" recordSetVar="products"> 4. which exposes some functionality to the page. 2. Modify your code to enable the Merchandise__c standard controller by editing the first <apex:page> tag.com objects have default standard controllers that can be used to interact with the data associated with the object. With $Resource. and a file within that resource.. the view (the Visualforce page) interacts with a controller. In this tutorial you'll use the default controller.. You can extend the standard controllers to add new functionality. add the standard list controller definition.styles. • • $Resources is a global variable which Visualforce has access to. click Page Editor to edit the page. Next. and calculates the URL that should be generated in your final page. <apex:page standardStylesheets="false" showHeader="false" sidebar="false" standardController="Merchandise__c"> 3. Let's take a look at that stylesheet code in a little more detail.Tutorial #7: Building a Custom User Interface Using Visualforce Tell Me More. it's because you've already encountered it to dynamically evaluate values when the Visualforce page is rendered. However. The editor ignores whitespace. so you can enter the text on a new line. the controller may contain the logic that should be executed when a button is clicked. 58 . and defined the variable products. In MVC. The URLFOR() function locates the static resource. See Also: Tutorial #7: Building a Custom User Interface Using Visualforce Step 2: Create a Visualforce Page Step 4: Add a Controller to the Page Step 4: Add a Controller to the Page Visualforce's Model-View-Controller design pattern makes it easy to separate the view and its styling from the underlying database and logic. All Force. You won't notice any change on the page. If the Page Editor isn't open on your Visualforce page. because you've indicated that the page should use a controller. you refer to the resource called "styles" which you created earlier. A controller also typically interacts with the model (the database)—exposing data that the view might want to display.

will contain the set of records to be displayed on the Visualforce page. Now you need to add some attributes to the dataTable tag.even"> 5. Place your cursor between the tags and create a data table. <apex:dataTable value="{!products}" var="pitem" rowClasses="odd. 4. and below it you'll see a list of rows: one for each merchandise record. It will display a table of all the merchandise records. 1. together with an input field on each so that you can update the inventory count. The var attribute assigns each item of that list. and highlight <apex:form> when it appears in the drop-down list. to the pitem variable. The form will allow you to make updates to the page.Tutorial #7: Building a Custom User Interface Using Visualforce Tell Me More. In the line below the </h1> tag.even"> <apex:column headerValue="Product"> <apex:outputText value="{!pitem. See Also: Tutorial #7: Building a Custom User Interface Using Visualforce Step 3: Add a Stylesheet Static Resource Step 5: Display the Inventory Count Sheet as a Visualforce Page Step 5: Display the Inventory Count Sheet as a Visualforce Page You now have all the functionality in place to flesh out the Visualforce page.name} indicates that we want to display the name field of the current row. Press Enter and notice that the system generates the opening and closing tags for you. Start by typing <apex:d and press Enter to select dataTable from the drop-down list. Add the following code between the opening and closing dataTable tags..The value attribute indicates which list of items the dataTable component should iterate over.. <apex:dataTable value="{!products}" var="pitem" rowClasses="odd. The headerValue attribute has simply provided a header title for the column.. and you will see your table appear. which provides additional controller support for listing a number of records with pagination. Its value. Click Save. and determine where it gets its data by looking up the appropriate field in the pitem variable. The expression {!pitem. enter the following. for one single iteration. will ensure that a new variable. 3. The recordSetVar attribute enables a standard list controller. which you've set to products. Now you are going to define each column. 59 . start typing <apex:f on a new line. On one or more lines within the tag. products.name}"/> </apex:column> </apex:dataTable> 6. 2. The rowClasses attribute assigns CSS styling names to alternate rows.

Tutorial #7: Building a Custom User Interface Using Visualforce 7. which updates the product with the new count. enter the following code directly above the </apex:form> line. and invokes a method called quicksave on the standard controller. Here. add two more columns.com objects. 9.Total_Inventory__c}"/> </apex:column> Note: The second column is an inputField.Total_Inventory__c}"/> </apex:column> <apex:column headerValue="Physical Count"> <apex:inputField value="{!pitem. The standard controller you used for this page was set to Merchandise__c. Now. To do this. and provides an input field for the physical count. which updates the values on the records. Click Save and you have an inventory count sheet! It lists all the merchandise records. displays the current inventory. You need a way to reference the current row as you iterate over the list. It's this list that the dataTable component uses. but it will also allow you to change it. • • • 60 . and the recordSetVar to products. • The dataTable component produces a table with rows. 8. That statement var="pitem" assigns a variable called pitem that holds the current row. the controller automatically populated the products list variable with merchandise records retrieved from the database. <apex:column headerValue="Inventory"> <apex:outputField value="{!pitem. and each row is found by iterating over a list. The rowClasses and styleClass attributes simply use some of the styles from the CSS style sheet that you loaded in the static resource.. The inputField will display a value. after the closing tag for the first column. You can safely remove this–it will just make things look less pretty! Every standard controller has various methods that exist for all Force. not an outputField. <br/> <apex:commandButton action="{!quicksave}" value="Update Counts" /> Tell Me More. As a result... you're updating the physical count of the product and performing a quick save. add a button that will modify the physical count on any row and refresh the values on the page. The commandButton component displays the button. As a final embellishment.

you can expose this functionality on a public website. Your page is highly configurable. See Also: Tutorial #7: Building a Custom User Interface Using Visualforce Step 5: Display the Inventory Count Sheet as a Visualforce Page 61 . <apex:commandLink action="{!next}" value="Next" rendered="{!hasNext}" /> See Also: Tutorial #7: Building a Custom User Interface Using Visualforce Step 4: Add a Controller to the Page Summary Summary Congratulations! You have created a new interface for your Warehouse application by creating a Visualforce page that uses a standard controller. add the following code below the commandButton for page-flipping action. For example. If you have enough records to page through them. It also provides a way of saving records. You'll find out about that in the Tutorial #8: Creating a Public Web Page Using Sites tutorial.Tutorial #7: Building a Custom User Interface Using Visualforce • Although pagination isn't shown in this example. through its quicksave method. The page also makes use of a lot of functionality provided by the standard controller behind the scenes. Now that you have created some Visualforce components. the functionality is there. For example. you can easily modify which data is displayed in each row by modifying the column components. the controller automatically queries the database and finds all merchandise records and assigns them to the products variable.

enable Sites for your organization. 1. Because sites are hosted on Force. data validation on collected information is performed automatically. You can also make the site's pages match the look and feel of your company's brand. You can publicly expose any information stored in your organization through a branded URL of your choice. Sites enables you to create public websites and applications that are directly integrated with your organization—without requiring users to log in with a username and password.Tutorial #8: Creating a Public Web Page Using Sites Tutorial #8: Creating a Public Web Page Using Sites Level: Intermediate.com supports your application in a multi-user environment. as described in Tutorial #7: Building a Custom User Interface Using Visualforce on page 54. And because sites are built on native pages. The new Product Catalog page will show description and price instead of inventory and count. register your Force. Click Clone. there are no data integration issues. 3. an associated portal seamlessly from your public site.com domain name. While Force. Duration: 20-30 minutes The application you just created requires that you log in use it.com Domain Name Step 3: Create a Force. You can also enable users to register for. If you're still in the Visualforce editor. 2. Select the CountSheet page you created earlier. you will create a Visualforce page.com servers. In this tutorial. sometimes you need to eliminate the login—for example on a public website. Prerequisites Visualforce Tutorial You first need to create the Visualforce page. 62 .com Site Step 4: Configure and Test the Site Summary Step 1: Create a Product Catalog Page In this step. See Also: Step 1: Create a Product Catalog Page Step 2: Register a Force. Click Your Name ➤ Setup ➤ Develop ➤ Pages. you clone the inventory count page you created earlier. or log into. you click Back in your browser until you see the Setup area. and expose the Visualforce page you created as a public product catalog on the Web.

. In the editor. The code should look like the following. 63 .Description__c}"/> </apex:column> <apex:column headerValue="Price"> <apex:outputField value="{!pitem. find the following lines. By simply changing a couple of values in a table..styles. it's easy to clone a Visualforce page. as shown. Change Inventory to Description and change Total_Inventory__c to Description__c. In the Page Editor. Then change Total_Inventory__c to Price __c.name}"/> </apex:column> <apex:column headerValue="Description"> <apex:outputField value="{!pitem. <apex:column headerValue="Description"> <apex:outputField value="{!pitem. you can display data from different fields.Total_Inventory__c}"/> </apex:column> 7. Change Physical Count to Price.Description__c}"/> </apex:column> 8. The standard controllers for the Visualforce page make all your data readily accessible. <apex:column headerValue="Inventory"> <apex:outputField value="{!pitem. 5. Finally. There are a few important things to note here.css')}"/> <h1>Merchandise Catalog</h1> <apex:dataTable value="{!products}" var="pitem" rowClasses="odd. change the Label and Name fields to Catalog. because you don't want to accept input on this page.Price__c}"/> </apex:column> </apex:dataTable> </apex:page> Tell Me More.Tutorial #8: Creating a Public Web Page Using Sites 4. 10. • • Lots of components on the Force. change the contents of the <h1> tag to Merchandise Catalog. Verify that your code looks like the following and then click Save. remove the opening and closing <apex:form> and <apex:commandButton> tags.com platform can be cloned.. and as you just saw. <apex:page standardStylesheets="false" showHeader="false" sidebar="false" standardController="Merchandise__c" recordSetVar="products" > <apex:stylesheet value="{!URLFOR($Resource. Then change inputfield to outputfield. Now you'll make a similar change on the next column to display the price. 6. but changing the table heading and the data within. You're keeping the same table.even"> <apex:column headerValue="Product"> <apex:outputText value="{!pitem. On the Page Editor tab. <apex:column headerValue="Price"> <apex:outputField value="{!pitem.Price__c}"/> </apex:column> 9. 'styles.

Salesforce.com Domain Name Your unique Force. It must begin with a letter.com domain. and not contain two consecutive underscores. After you accept the Terms of Use and register your Force.com Domain Name Step 2: Register a Force. but you can also extend the controller to create custom functionality.force. This name can contain only underscores and alphanumeric characters. Click Your Name ➤ Setup ➤ Develop ➤ Sites. Caution: You cannot modify your Force. 4.com Domain. you are prompted to change it.com. Enter a unique name for your Force. your domain name would be http://www. Read and accept the Sites Terms of Use by selecting the checkbox.com domain. not include spaces. If it is not unique. To get started. and even create your own controller from scratch. Create a custom Web address if you want to use a custom domain name. and must be unique in your organization.com Site 64 . the changes related to site creation are tracked in your organization's Setup Audit Trail and the Site History related list. if you choose “mycompany” as your domain prefix. See Also: Tutorial #8: Creating a Public Web Page Using Sites Step 2: Register a Force. See Also: Tutorial #8: Creating a Public Web Page Using Sites Step 1: Create a Product Catalog Page Step 3: Create a Force. not end with an underscore. It may take up to 48 hours for your registration to take effect.com recommends using your company's name or a variation. which hosts your site.com domain by doing the following. Click Check Availability to confirm that the domain name you entered is unique. 5.com domain name after you have registered it. Free Edition domain names are assigned automatically and can't be updated. plus force. register your company's Force. Click Register My Force. For example.com domain. such as mycompany.mycompany. is constructed from the unique domain prefix that you register. 3. 1. 2.com site.com. Congratulations! You are now ready to create your first Force.Tutorial #8: Creating a Public Web Page Using Sites • Did you notice how easy it was to change an input field to an output field? The Visualforce standard controller is powerful indeed.

1. 2. In this step you will toggle this security setting for the Merchandise object. 2. On the Site Edit page. The platform has a number of conservative controls in place for data security. c. unless you explicitly enable it. you can make the Merchandise Catalog Visualforce page you created the home page for your new site. Click the Site URL link for the Product Catalog site.Tutorial #8: Creating a Public Web Page Using Sites Step 3: Create a Force. b. Click Save. See Also: Tutorial #8: Creating a Public Web Page Using Sites Step 2: Register a Force. Select the Active checkbox. However.com Site Now that you have registered your domain. The Site Edit page appears. 3. Click New. you're almost ready to try it out. Go to the Sites page by clicking Your Name ➤ Setup ➤ Develop ➤ Sites. 1. Go to the Sites list by clicking Your Name ➤ Setup ➤ Develop ➤ Sites. instead of seeing your Merchandise Catalog page. fill in the site details: a. 4. This action opens either a new tab or a new window (depending on your browser). One of the controls ensures that data isn't displayed. In the Active Site Home Page field enter Catalog. In the Site Label and Site Name fields enter Catalog. you'll see a large Authorization Required 65 . and then visit your new site. even on public pages.com Domain Name Step 4: Configure and Test the Site Step 4: Configure and Test the Site Now that you've created your site. and established a default page.

. Note: If you still have an authorization required message. you will be able to access it with a URL something like http://workbook-developer-edition. 4.com/Meme (depending on your domain name of course). Scroll down to the Custom Object Permissions section and select the Read permission for the Merchandise object. 7.. Let's fix this. 6. if you add a page Meme to the site.. you probably didn't set your Active Site Home Page to Catalog in the previous step. For example. and made it the home page for that site. Force. You can go ahead and create additional Visualforce pages and assign them to the site as well. Click Save. click Edit.force.na1. it should be called Catalog.Tutorial #8: Creating a Public Web Page Using Sites page.com keeps track of the number of page views a Developer Edition site and imposes a daily bandwidth limit on the site. 3. Click Public Access Settings and then in the Profile Detail section. Go back to the setup page. Click the Site Label link. Now go back to your website and refresh your browser and you should see your page. • You've assigned a single Visualforce page to the site. 5. This is because the anonymous website viewer hasn't yet been granted permission to view the data that the page is displaying. • 66 . Tell Me More.

the next logical step is to provide a way for people to order merchandise.Tutorial #8: Creating a Public Web Page Using Sites • Sites sites lets you make use of a global content delivery network for fast access and caching of your site pages on production environments. registered the page as your home page. See Also: Tutorial #8: Creating a Public Web Page Using Sites Step 4: Configure and Test the Site 67 . and tested the site to see that it works.com domain name. To create the site. You'll do that next in the tutorial Tutorial #9: Creating a Store Front on page 68. <apex:page cache="true" expires="600"> See Also: Tutorial #8: Creating a Public Web Page Using Sites Step 3: Create a Force. You simply need to modify the page component to include a cache instruction. Then you registered a unique Force.com Site Summary Summary Congratulations. you have created a public website! Anyone in the world can access the site you just created and look at your home page. you cloned a Visualforce page and then enabled your Developer Edition organization for Sites functionality. all without having to log in. tweaked the security. Now that you have a site with a product catalog.

” “Modify All Data. and much more. Duration: 30 minutes Apex is an object-oriented programming language.com IDE on page 94. which will use a controller you write in Apex. which returns the products your store front will display. you can create classes and methods. make calls to the database.” and “Author Apex” permissions Since this tutorial involves working with Apex. discover more Apex syntax. create Web services. In that case you'll need Eclipse 3. Prerequisites Warehouse App You first need to create the basic Warehouse application and add relationships. send email.developerforce. as described in Tutorial #2: Adding Relationships on page 13. which executes when products have been selected.Tutorial #9: Creating a Store Front Tutorial #9: Creating a Store Front Level: Intermediate.com/index. see Creating a Project in the Force. “Developer Mode. and contain code that will be executed in response to page actions. Software Requirements You can use the Force.php/Force. In this tutorial you are going to create a simple Visualforce store front page.3 or 3.com IDE for this tutorial if you want to. Your rudimentary store front will have two methods: getProducts(). If you need help creating a project. and learn how to pass values between a Visualforce page and its controller. you'll create an Apex class. as you did in the previous tutorial. See Also: Step 1: Create a Controller Step 2: Add Methods to the Controller Step 3: Create the Store Front Step 4: Bonus Step—Updating the Page with AJAX Summary Step 1: Create a Controller Instead of using the default controller.4 and the Force.com_IDE.com IDE plugin: wiki. make sure that you have the proper permissions to create Apex classes. and shop(). Along the way. Controllers typically retrieve the data to be displayed in a Visualforce page. such as a command button being clicked. Using Apex. 68 . you're now going to write the controller code yourself.

but you'll need it as a placeholder for the action that occurs when someone clicks the Shop button. On the Create Apex Class page.Tutorial #9: Creating a Store Front To create the class in the Web interface: 1. In the IDE. define the method getProducts(). Now you'll add methods to it. so that the end user can select how many of each item they wish to purchase. 3. 2. Click Finish. Add the following code to the class (just after the public class StoreFront { line).com IDE: 1. specify StoreFront for the name. public PageReference shop() { return null. define a field to hold a list of DisplayMerchandise. which is going to initialize the products. right-click your project folder and select New ➤ Apex Class. It has no methods or fields. Add the following code as the definition of the class and then click Quick Save. } public DisplayMerchandise(Merchandise__c item) { this. 3. See Also: Tutorial #9: Creating a Store Front Step 2: Add Methods to the Controller Step 2: Add Methods to the Controller In the last step you created a custom controller. } public Decimal count { get. set. On the next line. DisplayMerchandise[] products. public DisplayMerchandise[] getProducts() { if (products == null) { 69 . together with a count. Click New. You'll start by adding the shop() method. You now have a rudimentary class for your controller. } } 3. set. It's not going to do anything yet. Click Your Name ➤ Setup ➤ Develop ➤ Apex Classes. 2. public class StoreFront { } To create the class in the Force. Within the current class (on the next line). and a new inner class called DisplayMerchandise to hold the data. so you'll add those in the next step. 1.merchandise = item. You also want the shop to display merchandise items. } 2. public class DisplayMerchandise { public Merchandise__c merchandise { get.

It then iterates over the records returned by the query. also called a SOQL query) returning all Merchandise records that have a positive total inventory.. price__c FROM Merchandise__c WHERE Total_Inventory__c > 0]) { products. description__c. } } You have now finished defining a simple controller. public class StoreFront { public PageReference shop() { return null.add(new DisplayMerchandise(item)). Verify that your code looks like the following and then click Save.Tutorial #9: Creating a Store Front products = new DisplayMerchandise[]{}. The DisplayMerchandise class “wraps” the Merchandise type that you already have in the database. set. } } return products. The getProducts() method executes a query (the text within square brackets. } } public DisplayMerchandise[] getProducts() { if (products == null) { products = new DisplayMerchandise[]{}. name.. adding a new decimal field. adding them to a list of DisplayMerchandise products. description__c. public class DisplayMerchandise { public Merchandise__c merchandise { get. } } return products. See Also: Tutorial #9: Creating a Store Front Step 1: Create a Controller Step 3: Create the Store Front 70 . which is then returned. } DisplayMerchandise[] products. set. for (Merchandise__c item : [SELECT id. Tell Me More. } public DisplayMerchandise(Merchandise__c item) { this.add(new DisplayMerchandise(item)). } public Decimal count { get. name.merchandise = item. It uses standard Apex classes and methods to access the database. The constructor lets you create a new DisplayMerchandise instance by passing in an existing Merchandise record.. for (Merchandise__c item : [SELECT id. price__c FROM Merchandise__c WHERE Total_Inventory__c > 0]) { products. The instance variable products is defined as a list of DisplayMerchandise instances. } 4.

merchandise.merchandise.name}"/> </apex:column> <apex:column headerValue="Price"> <apex:outputText value="{!pitem. 4. You'll see the familiar error message. between the open and close form tags.css')}"/> <h1>Store Front</h1> <apex:form> </apex:form> </apex:page> Note: The controller="StoreFront" attribute ensures that the Visualforce page you are creating will use the StoreFront Apex class as its controller. Click Save. Click the Create Page StoreFront link. In the address bar of your browser. 'styles. 71 . 2. 1.styles. and a button to call the shop method.count}"/> </apex:column> </apex:dataTable> <br /> <apex:commandButton action="{!shop}" value="Buy" /> 6. add /apex/StoreFront to the end of your instance.price__c}"/> </apex:column> <apex:column headerValue="#Items"> <apex:inputText value="{!pitem. 3. Your Store Front page should look like this.salesforcecom/apex/StoreFront. Enter this code on the next line. 5. You are now ready to insert the contents of the form between the opening and closing form tags. For example: https://na1. so let's create that now.even"> <apex:column headerValue="Product"> <apex:outputText value="{!pitem. <apex:page standardStylesheets="false" showHeader="false" sidebar="false" controller="StoreFront" > <apex:stylesheet value="{!URLFOR($Resource. Replace the text in the editor with the following. Click the Page Editor tab at the bottom. You will create a table that iterates over the products.Tutorial #9: Creating a Store Front Step 3: Create the Store Front Your store front uses another Visualforce page for the store front. <apex:dataTable value="{!products}" var="pitem" rowClasses="odd.

. It shows you how Visualforce transparently passes data back to your controller. In a real-world scenario you could imagine emailing the order. Each of these will form a new row. • • See Also: Tutorial #9: Creating a Store Front Step 2: Add Methods to the Controller Step 4: Bonus Step—Updating the Page with AJAX Step 4: Bonus Step—Updating the Page with AJAX This step is optional. Because you are using a custom controller. Because this is an action.. invoking a Web service. The Visualforce page has an action.salesforce. For example. adding the items to a shopping basket. 72 . for example https://na1. • The value attribute of the dataTable is set to "products". a method with the exact same name is used in the Apex controller. {!shop}. and is assigned to the pitem variable in the Visualforce page as the dataTable iterates. The getProducts() method in your controller returns an array of DisplayMerchandise objects. you will simply display that data in the page again (using a nifty AJAX page update). 2. Visualforce automatically looks for a method called getProducts() in your Apex controller.com/apex/StoreFront.. indicating that the table should iterate over a list called products. the shop() method that you wrote in the controller has access to the merchandise counts that were entered by the end-user on the Visualforce page.Tutorial #9: Creating a Store Front Tell Me More. Click the Page Editor tab. In this step. Navigate to your Visualforce page by using its URL. and so on. Let's take a look. There's a lot of new stuff here. where it can be processed. 1. This step shows you how to access that data in the controller.

Now modify the shop() method to update the message property displayed in the panel with a list of items that were selected. It updates the panel identified as "msg" after it calls the shop() method on the controller. Click Create Apex property StoreFront. 6. Add a number to one of the merchandise items. 2. 73 .Tutorial #9: Creating a Store Front 3. Now test the shopping cart. <apex:outputPanel id="msg">{!message}</apex:outputPanel> You just created an output panel identified as msg. <apex:commandButton action="{!shop}" reRender="msg" value="Buy" /> You have now modified the Visualforce page to use an in-place AJAX update. and click Buy. Note: Notice how this code simply utilizes the products variable.. Tell Me More. This simple addition exposes a lot of powerful functionality. 4. indicating how many products you purchased. 1. Click the Save icon. } '. Locate the shop() method (lines 4 through 6) and replace it with the following code. change the commandButton tag to include a reRender attribute. Visualforce will automatically ensure that the data you change in the user interface is reflected by the data in the products variable. Click Save. for (DisplayMerchandise p: products) { if (p. public PageReference shop() { message = 'You bought: '.name + ' (' + p.merchandise. which displays an item from the controller called "message". Now.count > 0) { message += p.count + ') } } return null. The Page Editor will figure out that you don't have any method or property called “message” and offer to create it for you. Click the Controller tab next to the Page Editor tab.message. 5. Modify your page by adding the following code after the </apex:form> line.. 4. You'll notice that a text field appears beneath the merchandise list. 3. which hasn't been created yet..

See Also: Tutorial #9: Creating a Store Front Step 3: Create the Store Front Summary Summary Apex is a powerful object-oriented language. Visit developer. you'd need to create a portal.force. was accomplished with a simple reRender attribute. we have included detailed steps on how to create a portal that works with the app you just built. without refreshing the entire page. If you did the bonus step. In order to do that. by either packaging for distribution or deploying it to a production organization.Tutorial #9: Creating a Store Front • • As you saw in this step. create a username and password. with many of the features typically found in similar languages such as Java. and purchase merchandise. For more information. see Delivering Your Application on page 95. See Also: Tutorial #9: Creating a Store Front Step 4: Bonus Step—Updating the Page with AJAX 74 . However. the panel updates without updating the entire screen. The next thing you might do is create an authenticated portal. which is outside the scope of this workbook. you modified the Visualforce page to use the data passed back to the controller to display a message using an AJAX update. and lets you quickly build forms and other complex input pages. The AJAX effect that does this.com/workbook for the portal tutorial and other new additions to the workbook. so that people can log into your site. and querying the database. Visualforce automatically mirrored the data changes on the form back to the products variable. which typically requires complex JavaScript manipulation. When you click the Buy button. In this tutorial you created an Apex class and used a few of the features of the language. Another thing you might want to do next is to deliver your app. such as arrays. This functionality is extremely powerful. iteration.

com Flex Level: Advanced.com includes classes that facilitate the development of Flex-based applications for Salesforce.com logic. These applications create.com Flex to build a basic desktop app called Inventory Tracker. Duration: 30 minutes Force.com when online A list of merchandise.com Flex framework installs as a standalone instance of Adobe® Flash® Builder for Force. and security.com API.com enterprise WSDL and provide access to Salesforce. The framework provides: • • • • • • Seamless handling of connected and disconnected states for desktop apps.com and desktop applications Generated ActionScript classes that mirror your Salesforce. including the detection of Internet connectivity Adobe’s Data Management Services (DMS). Adobe Flash Builder for Force. Force. including descriptions. update.com objects MXML components to simplify the implementation of user interfaces that render Salesforce. and indicates the number of unresolved data conflicts and errors 75 . enabling managers to track inventory on tablet PCs while on foot in a warehouse with inconsistent Wi-Fi.com. Inventory Tracker will include: • • • • • A login screen that prompts users for their credentials and establishes connectivity with Force. and delete Salesforce.com data. prices.com Flex status bars.com Flex is a framework for creating Flex-based desktop and Web applications that leverage Salesforce. This tutorial demonstrates how to use Force.com Flex Tutorial #10: Creating a Desktop App with Force. and inventory counts for each item Editable details for each item a user selects A conflict resolution interface that lets users easily resolve data conflicts that occur when values in the app violate validation rules or conflict with changes made by other users A status bar that notifies users whether the app is connected to the Internet. data. and popup notifications called toasts An engine and user interface for resolving data conflicts and errors in desktop applications The Force.com data via asynchronous requests to the Force.Tutorial #10: Creating a Desktop App with Force. The app will provide offline access to merchandise data.com—an enhanced version of Adobe's Eclipse-based integrated development environment (IDE) for developing Flex applications. which creates and manages local databases for desktop applications that operate online and offline Data synchronization between Salesforce.

we'll use standard Adobe MXML components and ActionScript classes alongside Force. 76 .com Personal Information Force. click Your Name ➤ Setup ➤ Manage Users ➤ Users.com Flex desktop application.com.com Flex desktop applications leverage the Connect Offline technology in Force.com.com Flex desktop app up and running.com Flex To create the app. To develop or use a Force. you must have the Offline User option selected in your Salesforce.com Flex Project Step 6: Import Your Enterprise WSDL Step 7: Set the Force. See Also: Step 1: Configure Your Salesforce.com Flex components and classes The tutorial provides all the code you need to get your first Force.com Personal Information Step 2: Create an Offline Briefcase Configuration Step 3: Generate Your Enterprise WSDL Step 4: Install and Launch Force.com Flex Step 5: Create a Force.com Flex Application Component Attributes Step 8: Create the Inventory Tracker Window Component Step 9: Testing the Inventory Tracker application Summary Step 1: Configure Your Salesforce. 1. In Salesforce.com personal information.Tutorial #10: Creating a Desktop App with Force.

Tutorial #10: Creating a Desktop App with Force.com Flex 2. 77 . The Inventory Tracker application needs to access merchandise data. Click Edit next to your name. 5. 1. Select the Active checkbox.com. See Also: Tutorial #10: Creating a Desktop App with Force.com data specified in the offline briefcase configuration assigned to you in Salesforce. Click Save. such as Inventory Tracker App Data. 4. Enter a name for your offline briefcase configuration. 4. Select your name in the Available Members list and click Add to move it to the Assigned Members list. 2.com Flex desktop application accesses only Force. so create an offline briefcase configuration that includes the Merchandise object.com Flex Step 2: Create an Offline Briefcase Configuration Step 2: Create an Offline Briefcase Configuration Your Force. click Your Name ➤ Setup ➤ Desktop Administration ➤ Offline Briefcase Configuration.com. In Salesforce. Click New Offline Briefcase Configuration. 3. Select the Offline User checkbox. 3.

The Offline Briefcase Configuration detail page appears. 10. Click Add. 9. Click Edit in the Data Sets related list.. Click Done. Select Merchandise and click OK. Select Merchandise Name in the Order By picklist. 78 . 11..Tutorial #10: Creating a Desktop App with Force.com Flex 6.. Click Save. 7. 8.

Click Generate Enterprise WSDL. automatically. 1. In your browser. See Also: Tutorial #10: Creating a Desktop App with Force.Tutorial #10: Creating a Desktop App with Force.com Flex Step 2: Create an Offline Briefcase Configuration Step 4: Install and Launch Force. click File ➤ Save Page As. and delete accounts.com data using the same browser-based interface as the online system but without an Internet connection. For example. 2. Connect Offline is a client application that lets you access a subset of Force.com Connect Offline. This is typically all that's needed when integrating with another system as it fully describes all the objects and the Web service.com provides a robust set of functionality to support both incoming and outgoing Web services calls.. activities. and custom object records (including relationship groups). 3.com. 79 . opportunities. See Also: Tutorial #10: Creating a Desktop App with Force.com Flex Tell Me More. which describes your Force. contacts.com Flex development projects. We will import our enterprise WSDL into our development project later to create an ActionScript class for the Merchandise object.com Flex zip file from developer. and Force. and install it as follows: 1. Offline briefcase configurations are sets of parameters that determine the records available in Force.wsdl and click Save.. click Your Name ➤ Setup ➤ Develop ➤ API. You can also add and update products and schedules on opportunities. Name the file enterprise.com objects.com also. You can create multiple briefcase configurations and associate each with different users and profiles to simultaneously suit the needs of various types of offline users. Extract the contents of the zip file. Use Connect Offline to view. and automatically generate ActionScript classes for every object your enterprise WSDL contains.com Personal Information Step 3: Generate Your Enterprise WSDL Step 3: Generate Your Enterprise WSDL Web services are a common form of integration. Use the classes to access Force. Force.com Flex Step 1: Configure Your Salesforce. while another configuration includes accounts and related opportunities for account executives. edit. save a local copy of your current enterprise WSDL. one configuration might include leads and opportunities for sales representatives.. You can import your enterprise WSDL into your Force.force.com/flashbuilder. leads.com Flex Download the Force. 4. For now.com Flex desktop applications and Force.com Flex Step 4: Install and Launch Force. Enterprise WSDL refers to the Web Services Definition Language. generates a Web service end point that allows access to the data in your application..com objects in your ActionScript code. In Salesforce.. create..

When the installation is complete. Force. 3. To open a Force. double-click the Adobe Flash Builder shortcut on your desktop.com Flex 2.com Flex creates a Force. Use this type of project to create Force. Double-click the installer. See Also: Tutorial #10: Creating a Desktop App with Force.com Flex applications. Force.com Flex Project in the Flash Builder folder and click Next. In Flash Builder.com Flex projects are Flex projects with additional ActionScript classes that add the following functionality to Force. 80 .com Flex Project Step 5: Create a Force.Tutorial #10: Creating a Desktop App with Force. Adobe's integrated development environment (IDE) based on the Eclipse platform.com Flex desktop applications: • • • • • Data storage and synchronization Online and offline detection Data conflict and error resolution Status bars Toaster alerts Force. The New Project wizard opens. 2. select File ➤ New Project. It does not affect other installations of Eclipse that you might have on your machine.com Flex desktop applications projects also have ActionScript classes and MXML components that let you add user interface components with the Salesforce.com look and feel to your both desktop and Web applications. Select the Force.com Flex project: 1.com Flex Project Installing Force.com Flex Step 3: Generate Your Enterprise WSDL Step 5: Create a Force.com Flex installs as a standalone version of Adobe Flash Builder.com Flex project type in Adobe Flash Builder.

Enter Inventory Tracker as the project name. and click Finish. Select Salesforce.com Flex creates a Fiber model of your enterprise WSDL. then click Next. Force. Select your enterprise WSDL. Select the Data/Services tab and click the Connect to Data/Service link.com Flex 3. 4. Figure 1: Connect to Data/Service Link 5. 81 . 6. then click Next.Tutorial #10: Creating a Desktop App with Force. select Desktop (runs in Adobe AIR).

com Flex Figure 2: Fiber Model of Your Enterprise WSDL You are ready to begin coding your application. Force.com Flex creates a Fiber model of your enterprise WSDL.com Flex projects let you import your Salesforce. See Also: Tutorial #10: Creating a Desktop App with Force.com Flex: • • • Generates ActionScript classes for every standard and custom object in your Salesforce. Select Salesforce. Force.com Flex Step 4: Install and Launch Force.com WSDL Renders a model of your WSDL that you can visually introspect Provides code hinting and compiler warnings in Adobe Flash Builder based on your WSDL To import your WSDL: 1.Tutorial #10: Creating a Desktop App with Force. 82 . When you import your WSDL. 3. Select your enterprise WSDL. Force. Figure 3: Connect to Data/Service Link 2. then click Next. Select the Data/Services tab and click the Connect to Data/Service link.com Flex Step 6: Import Your Enterprise WSDL Step 6: Import Your Enterprise WSDL As with other Flex projects.com enterprise WSDL as a data service. then click Next.

This sets the name that appears in the title bar of the application.mxml file located in src ➤ (default package) if it is not already open. 2.com Flex Step 5: Create a Force.com. 4. In the WindowedApplication component.com/flex/spark" xmlns:mx="library://ns. 3.com Flex desktop application is contained within an F3DesktopApplication component. Your final code should look like this.salesforce.com Flex Figure 4: Fiber Model of Your Enterprise WSDL See Also: Tutorial #10: Creating a Desktop App with Force.0" encoding="utf-8"?> <s:WindowedApplication xmlns:fx="http://ns.The application component connects the Force. Modify the attributes of the flexforforce:F3DesktopApplication element in this template as follows: 1. This attribute specifies the Force. and handles the initial synchronization of data between Force.com Flex application template you can modify for your Inventory Tracker application. In the F3DesktopApplication component.com objects your Force.com Flex Project Step 7: Set the Force.Tutorial #10: Creating a Desktop App with Force.salesforce.adobe.com Flex application.adobe.INFO}" filters="{['com.com Flex application references.com Flex projects have a default MXML file that contains a Force. Open the Main.com and the Force.com Flex desktop application to Force.com Flex Application Component Attributes Every Force.com/flex/mx" xmlns:flexforforce="http://flexforforce. <?xml version="1. Force. set the requiredTypes attribute to Merchandise__c.*']}"/> <flexforforce:F3DesktopApplication id="app" statusChanged="statusChangedHandler(event)" loginComplete="loginCompleteHandler(event)" loginFailed="loginFailedHandler(event)" sessionExpired="sessionExpiredHandler(event)" 83 .adobe.com/mxml/2009" xmlns:s="library://ns.com Flex Application Component Attributes Step 7: Set the Force. set the title attribute to Inventory Tracker.com" title="Inventory Tracker" showStatusBar="false"> <fx:Declarations> <s:TraceTarget includeCategory="true" includeLevel="true" includeTime="true" level="{LogEventLevel.

<flexforforce:FieldContainer id="_editFieldContainer" width="100%"> </flexforforce:FieldContainer> 84 .com Flex components simplify the process of accessing Force. When you select a record in that list. A Save button below the record details lets you commit those changes to Force. <s:Label text="Put your components here"/> 2. add a Force.com Flex application opens. This component contains default ActionScript that initializes the data when the Force. You'll enter the application logic in the default WindowedApplication component generated when you create a Force. The lower part contains a list of merchandise records.Tutorial #10: Creating a Desktop App with Force. Force. You can click on the record details to edit them.com. a VGroup component that creates a vertical grouping of the UI elements. The FieldContainer you're creating here will also render the details of the selected record at the top of the screen. FieldContainer components group data and simplify the process of manipulating several fields in a single operation. An XML Script component in which you can enter ActionScript. enter _editFieldContainer. The main UI of the Inventory Tracker consists of two parts. You don't need to modify the login UI. Remove the Label component. and a Force. • • • Modify the default code to implement the Inventory Tracker application logic as follows.com logic and data in your code.com Flex component that renders a status bar at the bottom of the application. 1.com Flex project. the text displayed in the title bar.com Flex Step 6: Import Your Enterprise WSDL Step 8: Create the Inventory Tracker Window Component Step 8: Create the Inventory Tracker Window Component The Inventory Tracker has two users interfaces: a login dialog and a main window containing the primary functionality. The default MXML code includes: • A Spark WindowedApplication component that specifies the namespaces. and the showStatusBar attribute. Set the FieldContainer component width to 100% and for the ID. The main UI for your application. Save the file. Inside the VGroup component.com Flex requiredTypes="Merchandise__c"/> </fx:Declarations> 5. the details of the record appears in the top part. The showStatusBar attribute determines whether the application renders the standard Flash Builder status bar and is set to false to allow the application to show the Force. A Spark states component used to determine which of the UIs is presented. as well as Force. Spark and Halo.com Flex components. The component contains a layout component used to arrange your UI elements. See Also: Tutorial #10: Creating a Desktop App with Force.com Flex status bar instead. The logic for the main functionality of the Inventory Tracker application consists of ActionScript and MXML that utilize two Adobe component sets.com Flex FieldContainer component. You'll reference the FieldContainer ID later in the code. which is in a Spark Group component.

DynamicEntity.LogEventLevel.events. Begin the ActionScript by importing the classes you need for the ActionScript in the <![CDATA[ section inside the <fx:Script> element.controls. com. error notification.salesforce. You'll use a standard ActionScript DataGrid component to render the list. <s:Button label="Save" click="onEditSaveClick()"/> 5.events. which is part of the default code. hover details. com.Total_Inventory__c" /> 4.flexforforce.IManaged. mx.com field value with its label. which you'll write later. mx. The code will look like this: import import import import import import import import import import import com.collections.SessionExpiredEvent.managers.salesforce.com Flex StatusBar component. <mx:DataGrid id="_dataGrid" width="100%" height="100%" dataProvider="{_gridDataProvider}" itemClick="onDataGridItemClick()"> <mx:columns> <mx:DataGridColumn dataField="Name" /> <mx:DataGridColumn dataField="Description__c" headerText="Description" /> <mx:DataGridColumn dataField="Price__c" headerText="Price" /> <mx:DataGridColumn dataField="Total_Inventory__c" headerText="Total Inventory" /> </mx:columns> </mx:DataGrid> The dataProvider attribute references a variable that you'll create later. and Info icon help text. 85 .com user interface. The fields also respect field dependencies. date fields display a calendar when clicked.ArrayCollection.LoginFaultEvent. com.Description__c" /> field="Merchandise__c. com. mx.Alert. mx. 6. Below the Save button in the Inventory Tracker user interface.data. com.salesforce.Price__c" /> field="Merchandise__c.com Flex LabelAndField component for each field of the Merchandise object you want to display.notifications. Now add a standard Spark button. and reference each field by its internal Force. and the itemClick attribute references a function that you'll create later. and automatically provide inline editing. Leave this component as is.com data and saves the data in the Force. 7. <flexforforce:LabelAndField <flexforforce:LabelAndField <flexforforce:LabelAndField <flexforforce:LabelAndField field="Merchandise__c.logging. add one Force. A LabelAndField component renders a Salesforce.salesforce. and configure it to execute a function called onEditSaveClick. Within the FieldContainer component. For example.salesforce.salesforce. mx.com Flex applications the same way they do on the Salesforce.LoginResultEvent. but you need to add the ActionScript that retrieves Salesforce.com Flex application.StatusChangedEvent.Tutorial #10: Creating a Desktop App with Force.F3Message. label it Save.com API name.events.Name" /> field="Merchandise__c. Enter the code as shown below. The final component in the VGroup element is the Force.events. The Inventory Tracker application user interface is now in place.CursorManager.com Flex 3. The fields you create with the FieldAndLabel component automatically function in Force. you will display a list of merchandise records.

rpc.query( "select * from Merchandise__c". [Bindable] private var _gridDataProvider:ArrayCollection = null.rpc. Create a function named onEditSaveClick that copies the changes a user makes to the data back into memory from the user interface. ArrayCollection—An ActionScript wrapper that exposes an array as a collection that can be accessed and manipulated. F3Message—A Force. Responder—An ActionScript component that ensures that NULL responder functions do not cause problems internally. 8.Merchandise__c.Responder. Create a variable to hold the merchandise data. The classes are as follows. Modify this function to query the database so the merchandise data is displayed in the lower part. such as data conflicts.com Flex component that binds dynamically to any item the user selects. This will be used to store the records to be displayed in the UI. new mx. Merchandise__c—The ActionScript service class representing the Merchandise object.Responder(commitToDB.com Flex component that provides standard contextual error and information messages. } 86 . 10. This class is automatically generated by Force. It is used to display the selected item in the top part of the UI. // when the login is complete the main state should be shown currentState = "main".flexforforce.removeBusyCursor().wrapper. IManaged—An ActionScript interface that provides the contract for a managed object.Responder( function(rows:ArrayCollection):void {_gridDataProvider = rows. app. } You referenced this function when you assigned the loginComplete attribute in the F3DesktopApplication element at the beginning of this step in the tutorial.com Flex import mx. The code will use this variable to display the data in the list. The complete function looks like this: protected function loginCompleteHandler( event : LoginResultEvent ) : void { CursorManager. 9. null) ). • • • • • • DynamicEntity—A Force. The loginCompleteHandler() function in the default code sets the current state to main so that the main UI is displayed.updateObject( new mx.fieldCollection. null ) ). import services.com Flex.rpc. private function onEditSaveClick():void { _editFieldContainer.Tutorial #10: Creating a Desktop App with Force.}.

mx. 87 .fieldCollection. mx. com. <?xml version="1.events. private function onDataGridItemClick():void { var de:DynamicEntity = _dataGrid.com" title="Inventory Tracker" showStatusBar="false"> <fx:Declarations> <s:TraceTarget includeCategory="true" includeLevel="true" includeTime="true" level="{LogEventLevel. } 12.salesforce. } 13.salesforce. which commits the data in memory to the database.adobe.LoginFaultEvent. Save the file.Tutorial #10: Creating a Desktop App with Force.DynamicEntity.com/flex/mx" xmlns:flexforforce="http://flexforforce.LoginResultEvent. com.data.adobe.salesforce.save( managedObject ).notifications.events. Create the commitToDB function. com. _editFieldContainer.ArrayCollection.controls.events.flexforforce.F3Message. Refer to the FieldContainer by the ID you set for it earlier (_editFieldContainer). mx. This function also performs a simple validation of the data the user enters.collections.salesforce.Alert. 11.CursorManager.com Flex This action is triggered when the user clicks the Save button. private function commitToDB(managedObject:IManaged):void { app. Create a function that renders the FieldContainer data in the Force. and clears the data from the FieldContainer.salesforce.*']}"/> <flexforforce:F3DesktopApplication id="app" statusChanged="statusChangedHandler(event)" loginComplete="loginCompleteHandler(event)" loginFailed="loginFailedHandler(event)" sessionExpired="sessionExpiredHandler(event)" requiredTypes="Merchandise__c"/> </fx:Declarations> <fx:Script> <![CDATA[ import import import import import import import import import import import com. Your final code should look like this.com Flex application. com.StatusChangedEvent.0" encoding="utf-8"?> <s:WindowedApplication xmlns:fx="http://ns. mx. com.IManaged. If the data is valid. the function calls the commitToDB function.managers.render(de).SessionExpiredEvent. mx.salesforce.LogEventLevel.salesforce.events.selectedItem as DynamicEntity.logging.salesforce.wrapper.com/flex/spark" xmlns:mx="library://ns.com/mxml/2009" xmlns:s="library://ns.adobe.INFO}" filters="{['com.

new mx.render(de). var alertString : String. } protected function loginFailedHandler( event : LoginFaultEvent ) : void { CursorManager. // By default an alert shows that login failed. app.setBusyCursor().Responder.Tutorial #10: Creating a Desktop App with Force. _password = password.flexforforce.updateObject( new mx. To implement an own logic // you can prevent default by uncommenting the following line: //event. null) ). CursorManager.preventDefault().loginByCredentials( _username. event.Responder( function(rows:ArrayCollection):void {_gridDataProvider = rows.".text.show( alertString.removeBusyCursor(). Alert.selectedItem as DynamicEntity. } private function onDataGridItemClick():void { var de:DynamicEntity = _dataGrid. } protected function statusChangedHandler( event : StatusChangedEvent ) : void { status = event.com Flex import mx. } protected function loginCompleteHandler( event : LoginResultEvent ) : void { CursorManager.removeBusyCursor(). "Session Expired" ).Merchandise__c.setBusyCursor(). currentState = "login".fieldCollection. // when the login is complete the main state should be shown currentState = "main".save( managedObject ).rpc. _editFieldContainer. _password ). CursorManager. } private function commitToDB(managedObject:IManaged):void { app. app. import services. private var _username : String. alertString = "Your session expired and was automatically re-newed. private function onEditSaveClick():void { _editFieldContainer. null ) ).message.}.description. private var _password : String.rpc.wrapper.query( "select * from Merchandise__c".wrapper. [Bindable] private var _gridDataProvider:ArrayCollection = null. 88 .preventDefault(). } protected function loginClickHandler( event : MouseEvent ) : void { _username = username.Responder(commitToDB.fieldCollection. } protected function sessionExpiredHandler( event : SessionExpiredEvent ) : void { // Alert will be shown if default is not prevented. " + "Please repeat your last operation.text.rpc.

loginPending}" width="100%" height="100%"> <s:layout> <s:BasicLayout/> </s:layout> <s:VGroup paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10"> <flexforforce:FieldContainer id="_editFieldContainer" width="100%"> <flexforforce:LabelAndField field="Merchandise__c. _password ).Name" /> <flexforforce:LabelAndField field="Merchandise__c.Price__c" /> <flexforforce:LabelAndField field="Merchandise__c.com Flex // when the login session expired the user could be re-logged in automatically pp.loginPending}" click="loginClickHandler(event)"/> </mx:FormItem> <mx:ProgressBar indeterminate="true" visible="{app.com Login" fontWeight="bold"/> <mx:Form> <mx:FormItem label="Username"> <s:TextInput id="username" text=""/> </mx:FormItem> <mx:FormItem label="Password" direction="horizontal"> <s:TextInput id="password" text="" displayAsPassword="true"/> <s:Button label="Login" enabled="{!app.Tutorial #10: Creating a Desktop App with Force.loginByCredentials( _username. } ]]> </fx:Script> <s:states> <s:State name="login"/> <s:State name="main"/> </s:states> <s:VGroup includeIn="login" horizontalCenter="0" verticalCenter="0"> <s:Label text="Salesforce.Total_Inventory__c" /> </flexforforce:FieldContainer> <s:Button label="Save" click="onEditSaveClick()" /> <mx:DataGrid id="_dataGrid" width="100%" height="100%" 89 .Description__c" /> <flexforforce:LabelAndField field="Merchandise__c.loginPending}" label="{status}"/> </mx:Form> </s:VGroup> <s:Group includeIn="main" enabled="{!app.

90 .com Flex Step 7: Set the Force. In Flash Builder..com Flex Application Component Attributes Step 9: Testing the Inventory Tracker application Step 9: Testing the Inventory Tracker application The Inventory Tracker application is now ready to be tested. 2.com Flex dataProvider="{_gridDataProvider}" itemClick="onDataGridItemClick()"> <mx:columns> <mx:DataGridColumn dataField="Name" /> <mx:DataGridColumn dataField="Description__c" headerText="Description" /> <mx:DataGridColumn dataField="Price__c" headerText="Price" /> <mx:DataGridColumn dataField="Total_Inventory__c" headerText="Total Inventory" /> </mx:columns> </mx:DataGrid> </s:VGroup> <flexforforce:StatusBar left="0" bottom="0"/> </s:Group> </s:WindowedApplication> See Also: Tutorial #10: Creating a Desktop App with Force.. ➤ Desktop Application. right-click on the Inventory Tracker project and select Run as.Tutorial #10: Creating a Desktop App with Force. The Inventory Tracker application login screen appears. 1. Verify that your machine has an active Internet connection.

enter the username and password you use to log into your Force. The Inventory Tracker user interface appears. In the login screen.Tutorial #10: Creating a Desktop App with Force.com Flex application. 91 .com Flex 3. and click Login.

Tutorial #10: Creating a Desktop App with Force.com Flex

4. Select a record in the list and change its data, then click Save. 5. Log into your Force.com application and verify that your change appears. 6. To test the data conflict resolution capability: a. Change a field in your Force.com application and click Save. b. Change the same field in the Inventory Tracker application to a different value and click Save. c. Select the icon in the status bar and select Sync Now. When you select Sync Now in the Inventory Tracker application, the status bar icon changes to indicate a conflict exists.

7. Click Resolve in the status bar to launch the conflict resolution interface.

92

Tutorial #10: Creating a Desktop App with Force.com Flex

The conflict resolution interface lets you see the values in both Salesforce.com and the Inventory Tracker application. Select the value you want to keep, then click Continue To Summary.

See Also:
Tutorial #10: Creating a Desktop App with Force.com Flex Step 8: Create the Inventory Tracker Window Component Summary

Summary
In this tutorial, you created a simple Force.com Flex app that gives users the ability to view and edit Force.com data both with and without an Internet connection. It demonstrates the fundamentals of Force.com Flex without much coding. As you can probably imagine, you can use Force.com Flex to create far more powerful Force.com Flex apps to enhance the ways in which users interact with your Force.com apps.

See Also:
Tutorial #10: Creating a Desktop App with Force.com Flex Step 9: Testing the Inventory Tracker application

93

Creating and Logging into a Sandbox

APPENDIX
Creating and Logging into a Sandbox
If you're using Free Edition, you should do all your development in a sandbox. To create one: 1. 2. 3. 4. 5. Log into your Free Edition organization. Click Your Name ➤ Setup ➤ Data Management ➤ Sandbox. Click New Sandbox. Enter a Name, such as Dev. Click Start Copy.

Creating a copy of the production organization takes a moment. To track the progress, refresh your browser and look at the Status field. If you're not the type to watch water boil, step away and we'll email you when the copy completes. When the sandbox is available, log in: 1. If you navigated to a different page during the sandbox copy, click Your Name ➤ Setup ➤ Data Management ➤ Sandbox. 2. Next to your sandbox, click Login. 3. Your browser opens a login page, enter your password and click Login.

Tell Me More....
When you logged in, you may have noticed that the User Name field is different than your regular user name. Force.com automatically appends your sandbox name to your user name so that you can log into multiple sandboxes. You may have also noticed that the URL in your browser is different. That's because each sandbox has its own instance that's different from the one used by your regular organization.

Creating a Project in the Force.com IDE
To create a project in the Force.com IDE: 1. Select File ➤ New ➤ Force.com Project. 2. Specify your organization credentials. a. Enter a project name. You can have multiple project names on the same organization, so it helps to identify each project with a descriptive name. Call this one Workbook. b. Enter the username you use to log in as an administrator. The username is in the form of an email address. c. Enter your password. d. If you are using a sandbox for development, in the Environment field, select Sandbox from the drop-down list. e. Click Next.

94

you'll want to know about the various ways you can deliver it. • For more information on packaging. If you're developing this application to be installed in multiple organizations. then you'll deploy it.php/Migration_Tool_Guide. including all of the source code.developerforce. or applications. it means your current IP is not recognized from a trusted network range.com online help. the publisher. With managed packages. with control over the intellectual property and licensing.com Migration Tool for deployment. you. Managed packages are the preferred way to release applications on Force. 95 . have no way of controlling what happens to the components that were in it. You can use them to distribute an application to multiple organizations. use the Force. Delivering Your Application Now that your application is complete. you can also easily distribute upgrades to customers who installed older versions of the application. see wiki. there are a couple options available: • If you're comfortable with a command-line interface.Delivering Your Application Note: If you get a LOGIN_MUST_USE_SECURITY_TOKEN error.com platform provides two types of packages: unmanaged and managed: • Unmanaged packages are used to distribute copies of the bundled components. then you'll want to package it. About Deploying If you want to deploy your code to a production organization that you have login credentials for. code.com/index.com user interface.com AppExchange. About Packaging Packages are like suitcases that can contain your components. the publisher. From the Salesforce. click Your Name ➤ Setup ➤ My Personal Information ➤ Reset My Security Token and follow the instructions there. The Force. Once an unmanaged package is installed in another organization. On the Project Content page click Finish to retrieve Apex and Visualforce and components. These are typically free packages without the option to upgrade. see “Overview of Packages” in the Force. You must reset your security token. If you're developing this application for just one organization. Managed packages are used to distribute copies of the bundled components in a way that leaves you. For more information. 3.

com_IDE.com IDE. 96 .php/Force.com/index. see wiki.Delivering Your Application • If you prefer a graphical interface.developerforce. For more information. use the Force.

Sign up to vote on this title
UsefulNot useful