Communicating with the Host Application

Flex applications require the Flash Player runtime environment to work. For this reason, it is common to think of Flex applications as being confined to Flash Player. However, it is entirely possible for a Flex application to communicate with the host application. For example, if a Flex application is running within a web browser, the application can interact with the browser. If a Flex application is running within a desktop executable, it can interact with that executable. This lets you create integrated applications that span beyond the Flash Player context.

Flex application/host application communication takes place via a Flash Player class called flash.external.ExternalInterface. ExternalInterface allows you to make synchronous calls to host application methods from the Flex application, and from the host application to Flex application methods. ExternalInterface is quite simple to work with, and in most cases it is quite appropriate.

Working with ExternalInterface

The flash.external.ExternalInterface class defines two static methods, named call() and addCallback(), enabling Flex-to-host-application communication and host-application-to-Flex communication, respectively.

The call() method allows you to call a method of the host application by passing it the name of the method. If the host application method expects parameters, you can pass those parameters to the call() method following the name of the host application method. For example, the following will call the alert() JavaScript method when the Flex application is run in a web browser:

ExternalInterface.call("alert", "Test message from Flex");

The call() method works synchronously. For example, the JavaScript confirm() function creates a new dialog with OK and Cancel buttons. The confirm dialog pauses the application until the user clicks on a button, at which time it returns either True (OK) or False (Cancel).

var option:Boolean = ExternalInterface.call("confirm",
                     "Do you really want to close the application?");

Of course, the host application functions can be custom functions as well.

If you want to call a Flex method from the host application, you must register the method within the Flex application using ExternalInterface.addCallback(). The addCallback() method lets you register a particular function or method with an alias by which the method or function may be called from the host application. For example, the following registers Alert.show as showAlert:

ExternalInterface.addCallback("showAlert", Alert.show);

You can then call the Alert.show method by way of the showAlert alias from the host application.

Within the host application you must retrieve a reference to the Flash Player instance that is running the .swf. You can then call the method by its alias directly from the reference. For example, if getFlexApplicationReference() is a function within the host application that returns a reference to the Flash Player instance, the following would launch an alert:

getFlexApplicationReference().showAlert("Alert message from host application");

In JavaScript, the Flash Player reference is different depending on the type of browser (IE or non-IE). In IE you can retrieve a reference to the Flash Player instance by window.id, where id is the value of the id parameter of the <object> tag, and in non-IE browsers the reference is document.name, where name is the value of the name attribute of the <embed> tag. The following JavaScript function determines the browser type and returns the correct reference where both the id parameter and the name attribute are Example:

function getFlexApplicationReference() {
  if (navigator.appName.indexOf("Microsoft") != −1) {
    return window.Example;
  } else {
    return document.Example;
  }
}

Setting the Web Browser Status

ExternalInterface might seem a little confusing until you see an example or two. In this section and the next, we’ll look at a few simple examples that should clarify how ExternalInterface works. This first application simply allows a Flex application to call to JavaScript in a hosting web browser so that it sets the status bar message as the user moves the mouse over Flex buttons.

Note

Firefox disables JavaScript access to window.status by default, and therefore this example might not work with the default Firefox configuration.

This application uses one simple MXML document and one HTML page. The MXML document should contain the code shown in Example 16-12.

Example 16-12. ExternalInterfaceExample.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

    <mx:Script>
        <![CDATA[

            private function rollOverHandler(event:MouseEvent):void {
                ExternalInterface.call("setStatus", event.currentTarget.label);
            }

        ]]>
    </mx:Script>
    <mx:VBox>
        <mx:Button label="A" rollOver="rollOverHandler(event)" />
        <mx:Button label="B" rollOver="rollOverHandler(event)" />
        <mx:Button label="C" rollOver="rollOverHandler(event)" />
        <mx:Button label="D" rollOver="rollOverHandler(event)" />
    </mx:VBox>

</mx:Application>

This MXML document creates four buttons. Each button has a different label. Using event handlers for the rollOver event each button notifies the rollOverHandler() method when the user has moved the mouse over the button. The rollOverHandler() method uses ExternalInterface.call() to call the setStatus method that is defined using JavaScript in the HTML page within which the application is to be embedded. The label for the corresponding button gets passed to the setStatus function.

The HTML page should contain the standard HTML template for embedding Flex content. In addition, it must define the setStatus() JavaScript function as follows:

<script language="JavaScript" type="text/javascript">
<!--

  function setStatus(value) {
    window.status = value;
  }

// -->
</script>

When you test this application, the browser status bar message changes as you move the mouse over the Flex buttons.

Integrating HTML and Flex Forms

There are cases where you may want to display the majority of a form in HTML, but you want to utilize Flex components for one or more of the form elements. For example, you may want to use sliders, color pickers, or, as in this example, date choosers.

In this simple example, we’ll create a basic HTML form with a checkbox and a small embedded Flex application. The Flex application consists of one date chooser component. The checkbox simply enables and disables the date chooser. Additionally, to highlight the synchronous nature of ExternalInterface the Flex application makes a request to the HTML page for an array of disabled dates, which it uses to disable those dates in the date chooser.

For this application, we’ll first create the HTML page as shown in Example 16-13. Note that this example uses SWFObject, which is a JavaScript library described in Chapter 21.

Example 16-13. ExternalInterface example HTML page

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
    <head>
        <title>Flex Example</title>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
        <script type="text/javascript" src="swfobject.js"></script>
        <script type="text/javascript">
            swfobject.registerObject("flexApplication", "9.0.0");
function getDisallowedDates() {
                return [new Date()]
            }
        </script>
    </head>
    <body>
       <input name="checkbox" type="checkbox" onChange="swfobject.
getObjectById('flexApplication').setEnabled(this.checked)" />
        <div>
            <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
                    width="175" height="180" id="flexApplication">
                <param name="movie" value="Flex3.swf" />
                <!--[if !IE]>-->
                <object type="application/x-shockwave-flash" data="Flex3.swf"
                        width="175" height="180">
                <!--<![endif]-->
                    <p>This site is best viewed as a Flex application, which requires
                       Flash Player 9. For users who prefer not to use Flash Player
                       we have provided a <a href='textVersion.html'>text-only
                       version of the site</a/>.</p>
                <!--[if !IE]>-->
                </object>
                <!--<![endif]-->
            </object>
        </div>
    </body>
</html>

In the preceding HTML code, we’ve highlighted a few of the key things to notice. You’ll see that the checkbox uses an onChange handler to call the setEnabled() method of the Flex application, passing it the checked value of the checkbox. This means that the Flex application must map a method to the setEnabled() name as a valid ExternalInterface callback. You’ll also see that the code defines a JavaScript method called getDisallowedDates(). This is callable from the Flex application to retrieve an array of Date objects.

The Flex application consists of just one MXML document, as shown in Example 16-14.

Example 16-14. ExternalInterface example MXML Flex3.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
initialize="initializeHandler(event)" width="175" height="180">

    <mx:Script>
        <![CDATA[

            private function initializeHandler(event:Event):void {
                var disallowedDates:Array =
ExternalInterface.call("getDisallowedDates");
                calendar.disabledRanges = disallowedDates;
                ExternalInterface.addCallback("setEnabled", setEnabled);
            }

            public function setEnabled(value:Boolean):void {
                calendar.enabled = value;
            }

        ]]>
    </mx:Script>
    <mx:DateChooser id="calendar" enabled="false" />

</mx:Application>

In this code, you’ll notice that when the application initializes, it calls the getDisallowedDates() JavaScript function in a synchronous fashion, retrieving the returned value immediately. It then uses that value—an array of Date objects—to specify the disabled ranges for the date chooser instance. Because ExternalInterface automatically serializes and deserializes arrays and Date objects, this code works without having to further convert the returned values.

When the application initializes, it also registers setEnabled() as an ExternalInterface callback. That is what allows the JavaScript-to-Flex communication.

The setEnabled() method takes the parameter and assigns it to the enabled property of the date chooser. Again, because Boolean values are automatically serialized and deserialized, the code works as is.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset