Flex Hello World

Contents

Simple Grid Sample

The following sample is about the simplest introduction to using Flex and the Flex Toolkit for Force.com around. In a very few lines of ActionScript Code and MXML you can create simple data-bound grid control that has useful default behaviors such as sorting, column resizing and column reordering. For a webinar showing how this code is used, see Build On-Demand Apps with Adobe Flex.

If you just want to cut and paste the code you can find it at the end of this article.

Create the Project

The first step is to create a new Flex Project or open an existing Flex Project. Next, create a new MXML Application in the project. For the sample the MXML application is named SimpleGrid. If the application file is opened in the source editor, click the button to switch to Design.

Add a Grid Component

Drag a Grid component onto the design surface. For the layout properties select to constrain the four edges of the grid and enter 10 into each of the constraint boxes. This will cause the grid to fill the entire surface with a 10 pixel margin around it.

Switch back over to the source view and remove the columnHeading attributes for each of the three columns that were automatically generated for the grid.

Add the Flex Toolkit for Force.com

Downlad the Flex Toolkit for Force.com. In the toolkit you will find a file named as3Salesforce.swc in the bin folder. You can unzip or move the toolkit folder anywhere you want on your hard drive. I prefer to put the toolkit in the Flex Builder X folder. For example on my Mac the path to the toolkit is /Applications/Adobe Flex Builder 3/FlexSalesforce_Rx_x.

Once you have obtained the toolkit you will need to add it to the build path for your project. Right-click the project created above and select "Properties" from the pop-up menu. In the properties dialog select "Flex Build Path" from the list of items and then click the "Library Path" button in the right hand pane. Click the "Add SWC" button and navigate to where you saved the toolkit.

Click the "OK" button and you are now ready to use the toolkit in your Flex application.

Writing the Code

While still in source view place your cursor directly before the <mx:Grid> tag and enter a new line. Beging typing <Connection and when the salesforce:Connection tag is displayed, selected and hit enter.

The Connection tag needs, at minimum, two attributes to be set. The first is the id attribute. This is the variable name by which you can reference the connection object. For the sample enter "apex". The second attribute is the server url which indicates the endpoint of the Force.com Web Services API. For the current version of the API enter "https://www.salesforce.com/services/Soap/u/9.0". Do not try to use the Enterprise endpoint. The toolkit is based on the Partner wsdl and therefore needs to use /u/x.x. Be sure to close the connection with "/>".

Create a <mx:Script> block below the connection tag. Cut and paste the code shown below into the script block.

	import mx.collections.ArrayCollection;
	import com.salesforce.results.QueryResult;
	import mx.utils.ObjectUtil;
	import mx.controls.Alert;
	import com.salesforce.AsyncResponder;
	import com.salesforce.objects.LoginRequest;
	
	private function login(event:Event):void {
		var lr:LoginRequest = new LoginRequest();
		lr.server_url = parameters.server_url;
		lr.session_id = parameters.session_id;
		lr.callback = new AsyncResponder(loadData, handleFault);
		apex.login(lr);
	}
	[Bindable]
	private var accountList:ArrayCollection = new ArrayCollection();
	
	private function handleFault(fault:Object):void {
		Alert.show(ObjectUtil.toString(fault));
	}
	
	private function loadData(lr:Object):void {
		apex.query("Select Name, Phone, Type From Account", new AsyncResponder(
			function(qr:QueryResult):void {
				if (qr.size > 0) {
					accountList = qr.records;
				}
			}, 
			handleFault)
		);
	}

Binding the DataGrid

To bind the grid you need to add the dataProvider attribute to the grid control and set the dataField attributes for the columns. In this case the dataProvider is accountList. This must be specified in curly braces. For information about curly braces, search the help docs in Flex Builder.

The dataFields do not need curly braces and must match exactly the field names that are returned from your query. In this case the field names are Name, Phone and Type.

Your data grid is now bound to the accountList variable and when the contents of that variable change, so will the data that is displayed in the grid.

Hooking the Creation Complete Event

You want to have the login function run only after the entire application has been generated on the client. To ensure this is the case, you will handle the creationComplete event on the Application object. In the Application tag enter 'creationComplete="login(event)"'.

You have now completely wired up the grid to recieve data from salesforce.com.

Create the S-Control

Creating the S-Control is a matter of creating a simple S-Control and using the HTML shown below as your template. This template can be used for any number of S-Controls since the merge fields that specify the actual swf file to load and the authentication token is included. To provide additional context to your Flex S-Control you can add more parameters to the flashvars attribute using additional merge fields.

<!-- saved from url=(0014)about:internet -->
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<style>
body { margin: 0px; overflow:hidden }
</style>
</head>

<body scroll="no">
  	<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="SimpleGrid" width="100%" height="100%"
			codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
			
			<param name="movie" value="{!Scontrol.JavaArchive}" />
			
			<param name="flashvars" value="session_id={!API.Session_ID}&server_url={!API.Partner_Server_URL_90}" />
			
			<param name="quality" value="high" />
			<param name="bgcolor" value="#869ca7" />
			<param name="allowScriptAccess" value="always" />
			
			<embed src="{!Scontrol.JavaArchive}" quality="high" bgcolor="#869ca7"
				width="100%" height="100%" name="SimpleGrid" align="middle"
				
				flashvars="session_id={!API.Session_ID}&server_url={!API.Partner_Server_URL_90}"
				
				play="true"
				loop="false"
				quality="high"
				allowScriptAccess="always"
				type="application/x-shockwave-flash"
				pluginspage="http://www.adobe.com/go/getflashplayer">
			</embed>
	</object>
</body>
</html>

Once you have created the S-Control you will need to upload the swf file that is generated by Flex Builder. In your Flex project you should see a "bin" folder. This folder will contain a <application name>.swf file. This is the file to upload. If you need to modify the Flex app, simply make your changes, save the changes (causing Flex Builder to regenerate the swf) and just re-upload the swf file from the salesforce.com ui.

Hooking into the salesforce.com UI

All the S-Control pieces are now ready to be hooked into the salesforce.com platform UI. In this case we are simply going to add a new Custom Tab to host the Flex/S-Control. Using the salesforce.com Setup area click "Build" and then "Custom Tabs". You have two types of custom tabs available. Click the "New" button for a new Web Tab.

Select the layout to be 2 Columns with Salesforce Sidebar and click the "Next" button. For the tab type select Custom S-Control and enter a label for the new tab. You can pick any style you want and leave the rest of the fields alone and then click the "Next" button.

In the next screen select the S-Control that you created previously and then click the "Next" button. Accept the defaults on the next two screens then click the "Save" button.

That's it you now have a new tab that runs your Flex\S-Control.

Full MXML File

<?xml version="1.0" encoding="utf-8"?>
<mx:Application creationComplete="login(event)" xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:salesforce="http://www.salesforce.com/">
	<salesforce:Connection id="apex" serverUrl="https://www.salesforce.com/services/Soap/u/9.0" />
	
<mx:Script>
	<![CDATA[
			import mx.collections.ArrayCollection;
			import com.salesforce.results.QueryResult;
			import mx.utils.ObjectUtil;
			import mx.controls.Alert;
			import com.salesforce.AsyncResponder;
			import com.salesforce.objects.LoginRequest;
			
			private function login(event:Event):void {
				var lr:LoginRequest = new LoginRequest();
				lr.server_url = parameters.server_url;
				lr.session_id = parameters.session_id;
				lr.callback = new AsyncResponder(loadData, handleFault);
				apex.login(lr);
			}

			[Bindable]
			private var accountList:ArrayCollection = new ArrayCollection();
			
			
			private function handleFault(fault:Object):void {
				Alert.show(ObjectUtil.toString(fault));
			}
			
			private function loadData(lr:Object):void {
				apex.query("Select Name, Phone, Type From Account", new AsyncResponder(
					function(qr:QueryResult):void {
						if (qr.size > 0) {
							accountList = qr.records;
						}
					}, 
					handleFault)
				);
			}
		
	]]>
</mx:Script>	
	<mx:DataGrid dataProvider="{accountList}" left="10" right="10" top="10" bottom="10">
		<mx:columns>
			<mx:DataGridColumn dataField="Name"/>
			<mx:DataGridColumn dataField="Phone"/>
			<mx:DataGridColumn dataField="Type"/>
		</mx:columns>
	</mx:DataGrid>
	
</mx:Application>

Resources