Creating a Flex Mashup on Force.com

来源:互联网 发布:linux vi 翻页到最后 编辑:程序博客网 时间:2024/06/11 16:46

Abstract

In the Getting Started with the Force.com Toolkit for Adobe AIR and Flex article we described how to build Flex applications that integrated with Force.com from a data access perspective. In this article, we'll describe how to integrate the two technologies from a visual perspective - mashing up Flex applications inside of Force.com Visualforce pages. This tutorial shows you how to accomplish this task.

Review of Force.com Toolkit for Adobe AIR and Flex

The Force.com Toolkit for Adobe AIR and Flex is an ActionScript library that provides access to the Force.com Web Services API. This API allows a developer to initiate Force.com operations such as login, query, and create. With this functionality developers can use Adobe's Flex Builder development environment to build applications that use the rich visualization and user experience capabilities of Flex while taking advantage of the powerful database services of Force.com. If you haven't already done so, you should read theGetting Started article to become acquainted with the technology.

The Anatomy of the Mashup

By default when you create an application in Flex Builder, it assumes you want to create a Flash movie (a .SWF file) that takes up the full extents of its surrounding web page. However, Flash movies can also be embedded as smaller widgets or components inside of web pages and web applications containing surrounding HTML content - a common example of this that you've probably seen is Flash advertising banners. When we're talking about mashing up Flex and Force.com, we're referring to just this - building small to medium-sized Flash movies that are incorporated into HTML-based Force.com user interfaces. These Flash-based components could present an interesting visualization or perhaps a non-standard user interface construct that would otherwise be difficult in HTML.

Embedding Flash Movies in Visualforce

Visualforce is Force.com's web user interface framework. It allows the developer to define pages that are a mix of static and dynamic content. Visualforce is a technology built into the underlying Force.com platform. This means that it can be used in your own custom applications, built from scratch on the platform, or as part of extensions or customizations to existing Salesforce CRM Sales and CRM Service applications. These pages can also be part of an internal application or exposed as part of a public web site using Force.com Sites. The sky is really the limit.

A common way to generate dynamic content within a Visualforce page is to use a Visualforce component, which is a special tag that gets evaluated before being sent to the client. It happens that there's a Visualforce component for embedding a Flash object, which is exactly what we want to do with this mashup.

An Example Flex Application

The following is a simple Flex application that after logging into Force.com, performs a query on the Opportunity table for a particular company and shows a bar chart of the size of the corresponding opportunities.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:salesforce="http://www.salesforce.com/"
        layout="absolute" width="500" height="300"
        backgroundGradientAlphas="[1.0, 1.0]"
        backgroundGradientColors="[#FFFFFF, #FFFFFF]" applicationComplete="init()">
        
        <mx:Script>
               <![CDATA[
                       import mx.collections.ArrayCollection;
                       import com.salesforce.results.QueryResult;
                       import com.salesforce.results.LoginResult;
                       import com.salesforce.AsyncResponder;
                       import com.salesforce.objects.LoginRequest;
                       
                       [Bindable]
                       private var opps:ArrayCollection;
                       
                       private function init():void
                       {
                               var lr:LoginRequest = new LoginRequest();
                               lr.username = "username";
                               lr.password = "password"; // You may need the security token if so please append the security token eg: passwordsecurityToken
                               lr.callback = new AsyncResponder(loginHandler,faultHandler);
                               force.login(lr);
                       }              
                       
                       private function loginHandler(result:LoginResult):void
                       {
                               force.query("SELECT Name, Amount FROM Opportunity " +
                                      "WHERE Account.Name = 'GenePoint'",
                                      new AsyncResponder(queryHandler, faultHandler));
                       }
                       
                       private function queryHandler(result:QueryResult):void
                       {
                               opps = result.records;
                       }
                       
                       private function faultHandler(result:Object):void
                       {
                               Alert.show(“Error: ” + result.toString());
                       }

               ]]>
        </mx:Script>
        
        <salesforce:Connection id="force"/>
        
        <mx:BarChart id="chart" dataProvider="{opps}" top="10" bottom="10" left="10" right="10">
        <mx:verticalAxis>
           <mx:CategoryAxis dataProvider="{opps}" categoryField="Name"/>
        </mx:verticalAxis>
        <mx:series>
           <mx:BarSeries xField="Amount"/>
        </mx:series>
        </mx:BarChart>
        
</mx:Application>

 

Running this application standalone produces the following output:


Integrating into Visualforce

To integrate the above Flex application into a Visualforce page, we first must upload our application's SWF file as a static resource within Force.com. ReadDelivering Static Resources with Visualforce for more information about static resources if you haven't used them before. Once uploaded, we can simply use the<apex:flash> Visualforce component.

The following is a simple Visualforce page that will show the details for an account, and below it a segment of Visualforce that includes the Flash movie (the application):

<apex:page standardController="Account">
      
    <apex:pageBlock title="Account Details">
        <apex:pageBlockSection>
            <apex:outputField value="{!account.name}"/>
            <apex:outputField value="{!account.accountNumber}"/>
        </apex:pageBlockSection>
    </apex:pageBlock>
    
    <apex:pageBlock title="Active Opportunities">
        <apex:flash src="{!$Resource.MyChart_SWF}" width="500" height="300"/>
    </apex:pageBlock>
      
</apex:page>



The resulting mashup should look like this:


Passing Variables Between Visualforce and Flex

So far, our mashup is working but there are a few things that are quite limiting. First, we're having to perform a login the Flex application even though the user is already logged onto Force.com. It would be great if we could pass the existing session identifier and URL from Visualforce to Flex. Second, we're hardcoding the name of the account that we're referencing within the query. It would be much more usable if we could grab the current account being shown and pass its identifier to Flex. To fix both of these situations we must pass some variables from Visualforce to Flex. This is done via Flashvars.

Flashvars is a special attribute exposed by the <apex:flash> component that we'll use to pass in the session id, session URL and the current account id. From within the Flex application, we can access these values via the Application object's parameters property.

See the modified Visualforce page below, the flashvars attribute has been used to pass in a string containing the three required variables. To obtain these variables we're usingVisualforce expressions.

<apex:page standardController="Account">
      
    <apex:pageBlock title="Account Details">
        <apex:pageBlockSection >
            <apex:outputField value="{!account.name}"/>
            <apex:outputField value="{!account.accountNumber}"/>
        </apex:pageBlockSection>
    </apex:pageBlock>
    
    <apex:pageBlock title="Active Opportunities">
        <apex:flash src="{!$Resource.MyChart_SWF}" width="500" height="300"
            flashvars="sid={!$Api.Session_ID}&surl={!$Api.Partner_Server_URL_90}&aid={!account.id}"/>
    </apex:pageBlock>
      
</apex:page>


Next, we've modified the Flex application to remove the hardcoding of the username/password and the account name. Instead we've made referece to the Application object's parameters property which gives access to any values passed in via flashvars.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:salesforce="http://www.salesforce.com/"
    layout="absolute" width="500" height="300" backgroundGradientAlphas="[1.0, 1.0]"
    backgroundGradientColors="[#FFFFFF, #FFFFFF]" applicationComplete="init()">
    
    <mx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import com.salesforce.results.QueryResult;
            import com.salesforce.results.LoginResult;
            import com.salesforce.AsyncResponder;
            import com.salesforce.objects.LoginRequest;
            
            [Bindable]
            private var opps:ArrayCollection;
            
            private function init():void
            {
                var lr:LoginRequest = new LoginRequest();
                lr.session_id = parameters.sid;
                lr.server_url = parameters.surl;
                lr.callback = new AsyncResponder(loginHandler);
                force.login(lr);
            }        
            
            private function loginHandler(result:LoginResult):void
            {
                force.query("SELECT Name, Amount FROM Opportunity WHERE Account.Id = '" +
                    parameters.aid + "'", new AsyncResponder(queryHandler));
            }
            
            private function queryHandler(result:QueryResult):void
            {
                opps = result.records;
            }
        ]]>
    </mx:Script>
    
    <salesforce:Connection id="force"/>
    
    <mx:BarChart id="chart" dataProvider="{opps}" top="10" bottom="10" left="10" right="10">
        <mx:verticalAxis>
           <mx:CategoryAxis dataProvider="{opps}" categoryField="Name"/>
        </mx:verticalAxis>
        <mx:series>
           <mx:BarSeries xField="Amount"/>
        </mx:series>
    </mx:BarChart>
    
</mx:Application>



Now no extra login is being performed and the URL can change to include a different account id and the Flash movie will update accordingly. We've made our Flash movie smart and tightly integrated.

Summary

Using this example you should be able to get started building great mashups between Flex and Force.com. You will be able to build your smaller Flash movies and embed these into Visualforce via the<apex:flash> Visualforce component. Then, you'll be able to pass session information and any other kind of data context down to the Flex application for use in the programming logic.

We're looking forward to seeing what kind of mashups you build!


原创粉丝点击