Welcome!

AJAX & REA Authors: John Funnell, Bob Little, Kevin Hoffman, Maureen O'Gara, Onkar Singh

Related Topics: Adobe Flex, ColdFusion

Adobe Flex: Article

Using the Adobe Flex Toolkit for Salesforce.com

New integration opportunities

Graphing Example
The real benefit of using Flex is access to the charting engine. You can easily build interactive graphs with drilldown capability based on Salesforce.com data. Pop open the sfChart project and the sfChart.mxml file included to follow along with this example. Like the previous example, we're creating a LoginRequest object and authenticating ourselves against Salesforce.com. Once logged in, we're again using the apex.query() call to retrieve all contacts for each account. Notice that the SOQL statement is leveraging the "relationships" syntax to get the contacts as a nested array of objects in the result set. Feel free to try the SOQL statement used here in the previous example as well.

private function loadAccounts():void
{
apex.query("SELECT Id, Name, (select Id, FirstName, LastName from Contacts) from Account order by Name",
    new AsyncResponder(function (qr:QueryResult):void{
    // add each account to an array collection for binding to the chart
    for (var j:int=0;j<qr.records.length;j++)
    {
accountArray.addItem( {accountID:qr.records[j].Id, accountName:qr.records[j].Name,
numContacts:qr.records[j].Contacts.records.length});
    }
}));
}

Once we've gotten data, our callback function adds each account to a new array object. I did this to simplify the results in a format we can actually bind to the charts. Note that we're storing the number of contacts (Contacts.records.length) per account in the "numContacts" property of each index of the account array. With one line of code, we can bind the data in the array to the accounts chart:

contactChart.dataProvider = accountArray;

Now take a look at the mx:PieChart item with the id "contactChart." You'll see that the itemClick event triggers the changeAccount function, passing the event information to that function.

<mx:PieChart id="contactChart" showDataTips="true" itemClick="changeAccount(event)">

The changeAccount function causes another function to fire and retrieve the opportunities for the selected account. In the following code, we call the apex.query(...) function again and bind the results to the second pie chart on the screen.

private function changeAccount(ev:ChartItemEvent):void
{
// send account ID to generate the opportunity listing
emptyRecordset.visible = false;
oppLabel.text = "Loading...";
// extract the accountID from the item that was clicked
loadOpportunities(ev.hitData.item.accountID);
oppLabel.text = ev.hitData.item.accountName;
}
private function loadOpportunities(accountID:String):void
{
    apex.query("select Name, Amount, StageName from Opportunity where AccountId = '" + accountID + "'",
    new AsyncResponder(function (qr:QueryResult):void
    {
       // if there are any opportunities, render them in the second pie chart
       if(qr.records)
       {
          opportunityChart.dataProvider = qr.records;
       }
       else
       {
emptyRecordset.visible = true; opportunityChart.dataProvider = null;
       }
    }));
}

In a real application, you could surely find something more relevant to link together (number of contacts and opportunities don't really relate). Try it out by compiling the app and running it yourself. It's easy to run from here and create your own drilldown charts, graphs, and data grids based on your users' needs.

Deployment
Once you've developed an application, you've got to figure out how to deploy it. You have three choices: deploy to your own server, deploy in the Salesforce environment as an S-Control, or compile your application as an Adobe AIR application and use the new runtime to use the application on the desktop without an application or Web server.

To embed the Flex application as an S-Control, first compile your application for use in Salesforce by modifying the LoginRequest object in your code to use the server_url and session_id arguments instead of username and password. Recompile the application and note the location of the generated swf.

Now log in to your developer account and click on Setup. Under App Setup, expand the Build menu and select Custom S-Controls. Create a new one and give it a memorable label and name. The type will be HTML. In the zip file you downloaded from Salesforce.com containing the toolkit, you'll find a file called flexScontrolContent.htm. Copy the contents of that file to the Content area in the S-Control setup screen. In the filename field, browse and select the swf you just compiled (see Figure 2).

Let's take a look at the code you pasted in:

<embed src="{!Scontrol.JavaArchive}" play="true" bgcolor="#f3f3ec" width="100%" height="700"
    name="FlexSalesforce" align="middle"
    flashvars="session_id={!API.Session_ID}&server_url={!API.Partner_Server_URL_90}"
    loop="false" allowScriptAccess="always"
    type="application/x-shockwave-flash"
    pluginspage="http://www.adobe.com/go/getflashplayer">
</embed>

There are three Salesforce.com variables in here: Scontrol.JavaArchive, API.Session_ID, and API.Partner_Server_URL_90. The last two are passed into the swf when it loads in the browser, maintaining your session state so no secondary login is required. Save the S-Control. This should upload the swf to the Salesforce.com servers and create the S-Control for use in your environment.

Now you need to create a new Custom Tab to house the S-Control you just created. Create a new "Web Tab." I prefer the full width (more room for charts), but the choice as to whether or not you want a sidebar is up to you. The tab type will be "Custom S-Control." In step three you'll select the S-Control you just created to be the content on that tab. Click next through steps four and five you'll see the new tab appear at the top of your screen (see Figure 3).

Conclusion
Creating Flex applications that interface with Salesforce.com is easy to do and provides new integration opportunities among your systems. The release of Adobe AIR gives you the ability to store Salesforce.com data offline and tighten desktop integration, both of which are shown in Christophe Coenraets blog post (see below). Outstanding functionality for a Web-connected application!

If your company is looking at CRM or is already a Salesforce.com customer, I encourage you to look closely at this API and consider the possibilities. The flexibility of the platform combined with the user experience of Flex is a practically unbeatable combination.

Further Reading
The original presentation materials and additional example applications are downloadable from my Web site at
www.countermarch.com/salesforce
James Ward has done some amazing work with the toolkit, Flex, and Apollo/AIR:
www.jamesward.org/wordpress/category/salesforce/
And as always Christophe Coenraets has taken it up another notch:
http://coenraets.org/blog/2007/06/salesbuilder-on-air- local-database-data-sync-and-native-drag-and-drop/
I think that URL says just about everything!

More Stories By Stephen Rittler

Stephen Rittler is the president of Countermarch Systems LLC, a company dedicated to improving alumni relations in higher education through the proper application of CRM tools, social networking and process improvement through technology. His company has developed effective solutions for clients in education, government, publishing and manufacturing. He is a Certified Advanced ColdFusion MX developer and has contributed to the CF community through his writing, leadership of the Philadelphia ColdFusion User Group and presentations on a variety of topics. Steve is a musician at heart but has yet to figure out how to play his saxophone and code at the same time. You can read his blog at http://www.countermarch.com/blog.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.