Although currently in beta state, the Adobe Flex-Ajax Bridge (FABridge) has proven to be a simple, easy to use library which exposes Flex applications to traditional DHTML applications. However, current documentation, code samples, and general misinformation are preventing the exercising of this important technology. This article will present 10 simple steps to becoming a master of the FABridge.
The FABridge library is a complete solution which exposes the ActionScript objects residing in a Flex application to the JavaScript environment in your DHTML applications. Without this library, you would need to write your own custom, inherently limited library to enable this functionality. In short, the FABridge opens the door to an incredible number of creative and interesting opportunities. While this library allows you to introduce complex UI elements to your traditional DHTML applications, the process is quite simple.
The following 10 steps will walk through the generation of an example application which utilizes all the key features of the FABridge. The example is meant to focus on the core uses the developer would incorporate in their own applications.
Before we can start coding, we'll need to run through our checklist of materials required to use the FABridge. The following materials are required to complete the development of the example application:
Specific suggestions on where to get these materials can be found in the links section or in the cheatsheets download included in this article. Optionally, you may want to download the Flash Player Content Debugger for IE or Netscape-compliant browsers. This will enable robust exception handling data to come across the bridge from ActionScript to JavaScript.
Now that we have the necessary tools, we can begin shelling out the framework for the example application. Let's start by creating the directory structure and creating/saving the files listed in Listing 1 under your web root. The fabridge_example01.mxml, index.html, and fabridge_example01.js files can be empty at this point.
fabridge_example01 +--- assets | +--- js | | +--- bridge | | | +--- FABridge.js | | +--- fabridge_example01.js | | | +--- swf | +--- bridge | | +--- FABridge.as | +--- fabridge_example01.mxml | +--- index.html
Listing 1 - Directory structure
We can start by entering the code in Listing 2 in the /fabridge_example01/index.html file which is the minimum amount of code used to embed the SWF in Netscape compatible browsers. The buttons defined in the HTML form will help us invoke the different functions as we step through all the functionality of the FABridge.
<html>
<head>
<title>fabridge example 01</title>
<!-- link the JavaScript side of the FABridge library -->
<script language="JavaScript" src="assets/js/bridge/FABridge.js"></script>
<script language="JavaScript" src="assets/js/fabridge_example01.js"></script>
</head>
<body>
<h3>FABridge Example 01</h3>
<!-- embed the flex application swf -->
<embed src="assets/swf/fabridge_example01.swf" />
<!-- define a simple HTML form. -->
<form name="frm_mainMenu">
<input type="text" name="frm_mainDish" value="" /><br/>
<input type="button" value="Step 5 - Get ActionScript Objects by ID" onclick="getId();" /><br/>
<input type="button" value="Step 6 - Get ActionScript Property Values" onclick="getProperty();" /><br/>
<input type="button" value="Step 7 - Set ActionScript Property Values" onclick="setProperty();" /><br/>
<input type="button" value="Step 8 - Calling ActionScript Object Methods" onclick="callObjectMethod();" /><br/>
<input type="button" value="Step 9 - Attach Event Handler" onclick="attachEvent();" />
</form>
</body>
</html>
Listing 2 - /fabridge_example01/index.html
Next, enter the code in Listing 3 in the /fabridge_example01/assets/swf/fabridge_example01.mxml file.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:bridge="bridge.*">
<bridge:FABridge bridgeName="flex" />
<mx:TextInput id="txt_mainDish" text="Chicken Yaya" />
</mx:Application>
Listing 3 - /fabridge_example01/assets/swf/fabridge_example01.mxml
The key to linking the ActionScript side of the FABridge library to your MXML source is to properly define the namespace it will operate in. Line 2 of Listing 3 shows the added definition of the bridge namespace which imports all components found under the bridge directory. Since the FABridge.as script contains the FABridge class definition of the bridge package, it becomes even more important to maintain the directory structure described in Listing 1. Without the directory integrity in check, compilation of the MXML source file will fail. Line 3 of Listing 3 defines the name of the bridge which you will refer to in your JavaScript code when referencing the Flex application instance.
Let's continue the exercise by compiling the /fabridge_example01/assets/swf/fabridge_example01.mxml source file using the following command.
<path_to_flex_sdk>/bin/mxmlc <web_root>/fabridge_example01/assets/swf/fabridge_example01.mxml
This command will generate a .swf file at /fabridge_example01/assets/swf/fabridge_example01.swf. Note that at this point, you will not need the bridge folder nor the MXML source file located under the /fabridge_example01/assets/swf/ folder for the application to operate. The FABridge ActionScript component is already compiled into the resulting SWF file. Since we are still developing our exercise we'll leave everything intact. Browsing to the example application should yield a screen similar to Figure 1.
Figure 1 - Example Application
Now that the FABridge is linked in both the JavaScript and ActionScript environments, we can start to shell out the JavaScript library we'll develop to invoke the functionality of the FABridge. Enter the code in Listing 4 in /fabridge_example01/assets/js/fabridge_example01.js.
// global variable var flexApp; var initCallback = function() { flexApp = FABridge.flex.root(); return; } // register the callback to our Flex application with the 'bridgeName' of 'flex' FABridge.addInitializationCallback( "flex", initCallback );
Listing 4 - /fabridge_example01/assets/js/fabridge_example01.js
What we've done in Listing 4 is enable the FABridge to load the instance of the Flex application with the bridge name of flex automatically. The object holding the instance of the Flex application is stored globally in the variable named flexApp. As we begin to define and use the remaining functions in this library, we will be able to continually reference the Flex application using this global variable.
Perhaps the most important idea to understand when using the FABridge library is gaining access to an ActionScript object through it's ID property. This is accomplished by calling the object not by traditional object.property notation, but rather by calling it as a function. Let's start by modifying our fabridge_example01.js file by including the code in Listing 5.
// step 5 - get objects by ID
function getId() {
var swfObj_mainDish = flexApp.getTxt_mainDish();
alert( "Got the object, it's ID is '" + swfObj_mainDish.getId() + "'" );
return;
}
Listing 5 - Get ActionScript Objects By ID
As you'll recall in Listing3, we have defined a TextInput control in our Flex application with an ID of txt_mainDish. Normally, in the ActionScript world, we would reference this object purely by the ID property. Using JavaScript and the FABridge, we reference it as a method of the Flex application instance object flexApp. Whenever we get properties from ActionScript objects in this way, we use the format <actionscript_object>.get<property_name>() where <property_name> is formatted using alternate capitalization. Let's move on to step 6 to seal this idea.
Although this is functionally the same as step 5, the gaining of access to properties of ActionScript objects obviously can't occur without the reference to the object itself which is what we did in step 5. To drive this idea home, modify your fabridge_example01.js script to include the function in Listing 6.
// step 6 - get object properties function getProperty() { // get the 'mainDish' object var swfObj_mainDish = flexApp.getTxt_mainDish(); // show what's for dinner alert( "Delicious, we're having " + swfObj_mainDish.getText() + " for dinner!" ); return; }
Listing 6 - Getting ActionScript Object Properties
Listing 6 demonstrates getting the text property of the TextInput ActionScript class. All you need to know is the format to follow to gain access to any and all properties of ActionScript objects residing in your Flex applications. Let's move on to modifying properties.
If you got the idea surrounding steps 5 and 6, you'll find step 7 even easier. Much in the same way that we get properties, we set them in virtually the same way. To set properties of ActionScript objects, simple use the format <actionscript_object>.set<property_name>( <property_value> ). Let's try an example to demonstrate. Modify your fabridge_example01.js script to include the function found in Listing 7.
// step 7 - set object properties function setProperty() { // there's a special tonight var str_special = "cheeseburgers"; // get the 'main dish' object var swfObj_mainDish = flexApp.getTxt_mainDish(); // what's the main dish? alert( "We currently offer " + swfObj_mainDish.getText() + "." ); // switch it up, we'll have the special. swfObj_mainDish.setText( str_special ); alert( "I changed my mind, I'm having the special which is " + swfObj_mainDish.getText() + "." ); return; }
Listing 7 - Setting ActionScript Object Properties
You'll notice that when we run this example by clicking the corresponding button in index.html, that the actual TextInput control in the Flex application updates to reflect the new special. Now we're really learning some very powerful ideas by applying simple concepts. Let's move on to calling ActionScript object methods.
Just as all properties of ActionScript objects are available to us, so are their methods. There is no special notation involved here, we just need access to the ActionScript object as we have been doing all along. Modify your fabridge_example01.js script to include the function in Listing 8.
// step 8 - call object methods function callObjectMethod() { // get the 'main dish' object var swfObj_mainDish = flexApp.getTxt_mainDish(); // set focus to the 'main dish' TextInput swfObj_mainDish.setFocus(); // select some text in the 'main dish' TextInput swfObj_mainDish.setSelection( 1, 2 ); return; }
Listing 8 - Calling ActionScript Object Methods
At this point, you're probably picking up steam and becoming more and more familiar with how the FABridge exposes ActionScript objects to your JavaScript. Once you start to understand that there are really only a couple of core techniques, the rest is very intuitive. The example in Listing 8 brings focus to the TextInput in the Flex application and selects a couple of characters in the control.
The FABridge also allows us to pass functions to ActionScript. One very useful technique is to attach event handlers to ActionScript objects. Modify your fabridge_example01.js script to include the function in Listing 9.
// step 9 - attach event handler function attachEvent() { // get the 'main dish' object var swfObj_mainDish = flexApp.getTxt_mainDish(); // define a function used as a callback to JavaScript var mainDishCallback = function( event ) { // get the object which fired the event var swfObj_source = event.getTarget(); // as the value in the swf 'main dish' changes, so does the html 'main dish' document.frm_mainMenu.frm_mainDish.value = swfObj_source.getText(); return; } swfObj_mainDish.addEventListener( "change", mainDishCallback ); return; }
Listing 9 - Attaching Events to ActionScript Objects
Listing 9 is a little more complicated so let's walk through it. We begin on line 4 by accessing the TextInput ActionScript object just as we have been. Our callback function defined on lines 7-14 is used to hook the ActionScript object we chose to attach to into the JavaScript environment. Line 9 demonstrates gaining access to the object the event was attached to by evaluating the target property of the ActionScript Event class. Line 11 accesses the HTML text input control to update its value with the value currently stored in the TextInput in the Flex application. Run this example by clicking the corresponding button in the index.html page. As you change the value of the main dish in the SWF, you should see the HTML text input update.
The final piece of this puzzle involves handling for exceptions that may come across the bridge from ActionScript to JavaScript. This is accomplished by simply using try/catch blocks in your JavaScript code where the potential exists for error in your ActionScript. By default, when catching exceptions thrown by ActionScript to JavaScript, you will always have the value of the error code at the very least. However, if you install the Flash Player Content Debugger, you will enable more robust information to come across the bridge such as description, line number, file name, and stack trace. For more information on how to get this feature, please see either the Links section of this article, or the cheatsheets included as part of this download. The download included in this article contains a demonstration of catching exceptions in JavaScript thrown by ActionScript.
A great deal of potential exists for creating interesting and innovative applications which utilize this compact library. Please visit the download section of this article for some useful examples and cheatsheets. They should serve as handy references when developing your own applications using the FABridge.