Accessing Flex from JavaScript

You can call Flex methods from your enclosing wrapper by using the ExternalInterface API. You do this by adding a public method in your application to a list of callable methods. In your application, you add a local Flex function to the list by using the addCallback() method of the ExternalInterface API. This method registers an ActionScript method as callable from the JavaScript or VBScript in the wrapper.

Note: This feature requires that the client is running certain browsers. For more information, see About the ExternalInterface API.

The signature for the addCallback() method is as follows:

addCallback(function_name:String, closure:Function):void

The function_name parameter is the name by which you call the Flex function from your HTML page’s scripts. The closure parameter is the local name of the function that you want to call. This parameter can be a method on the application or an object instance.

The following example declares the myFunc() function to be callable by the wrapper:

<?xml version="1.0"?>
<!-- wrapper/AddCallbackExample.mxml -->
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="initApp()">
    <fx:Script>
        import flash.external.*;

         public function initApp():void {
            ExternalInterface.addCallback("myFlexFunction",myFunc);
         }  

         public function myFunc(s:String):void {
            l1.text = s;
         }
    </fx:Script>

    <s:Label id="l1"/>
  
</s:Application>
To call the Flex method from the HTML wrapper, you get a reference to the movie object. The name of the movie is the same value as the attributes.id and attributes.name properties. In this case, it is AddCallbackExample, as the following example wrapper shows:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- saved from url=(0014)about:internet -->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
    <head>
        <title>addCallback() Wrapper</title>
        <script type="text/javascript" src="swfobject.js"></script>
        <script type="text/javascript">
            var swfVersionStr = "0";
            var xiSwfUrlStr = "";
            var flashvars = {};
            var params = {};
            params.quality = "high";
            params.bgcolor = "#ffffff";
            params.allowscriptaccess = "sameDomain";
            var attributes = {};
            attributes.id = "AddCallbackExample";
            attributes.name = "AddCallbackExample";
            attributes.align = "middle";
            swfobject.embedSWF(
                "AddCallbackExample.swf", "flashContent",
                "100%", "100%",
                swfVersionStr, xiSwfUrlStr,
                flashvars, params, attributes);
        </script>
    </head>
    <SCRIPT LANGUAGE="JavaScript">
        function callApp() {
            window.document.title = document.getElementById("newTitle").value;
            var AddCallbackExample = document.getElementById("AddCallbackExample");
            AddCallbackExample.myFlexFunction(window.document.title);
        }
    </SCRIPT>

    <body>
        <form id="f1">
            Enter a new title: <input type="text" size="30" id="newTitle" onchange="callApp()">
        </form>
        <div id="flashContent"/>
   </body>
</html>

If your wrapper uses <object> and <embed> tags, the movie object is the same value as the id and name properties of the <object> and <embed> tags. You then call the method on that object, passing whatever parameters you want, as the following example shows:

<html>
<head>
<title>wrapper/AddCallbackWrapper.html</title>
</head>
<body scroll='no'>

<SCRIPT LANGUAGE="JavaScript">
    function callApp() {
        window.document.title = document.getElementById("newTitle").value;
        mySwf.myFlexFunction(window.document.title);
    }
</SCRIPT>

<h1>AddCallback Wrapper</h1>

<form id="f1">
    Enter a new title: <input type="text" size="30" id="newTitle" onchange="callApp()">
</form>

<table width='100%' height='100%' cellspacing='0' cellpadding='0'>
    <tr>
        <td valign='top'>
            <object id='mySwf' classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' height='200' width='400'>
                <param name='src' value='AddCallbackExample.swf'/>
                <param name='flashVars' value=''/>
                <embed name='mySwf' src='AddCallbackExample.swf' height='100%' width='100%' flashVars=''/>
            </object>
        </td>
    </tr>
</table>

</body></html>

If there is no method with the appropriate name in the application or that method hasn’t been made callable, the browser throws a JavaScript error.

Getting a reference to the application object and other DOM objects is not the same in Internet Explorer as it is in Chrome or FireFox. If you do not know which browser your users will be using when they request your application, you should make your wrapper’s script browser independent. For some ideas on detecting the browser type, you can look at the code in the swfobject.js file. To cover most cases, you typically use the getElementById() method.

Flash Player has strict security in place to prevent cross-site scripting. By default, Flex methods are not callable by HTML scripts. You must explicitly identify them as callable. You also cannot call a Flex method from an HTML page if the HTML page is not in the same domain as the application. However, it is possible to expand the sources from which Flex methods are called. For more information, see About the addCallback() method.

Handling browsers that disable JavaScript

In some cases, the client’s browser either does not support JavaScript or the user has purposely disabled it. You can use the <noscript> tag in the wrapper to define what happens when this user tries to run your applications. Most commonly, you use the <object> and <embed> tags inside the wrapper’s <noscript> block to embed the application. However, without scripting, deep linking and Express Install functionality is not available.

The following is an example of a <noscript> block that embeds an application built with Flex:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- saved from url=(0014)about:internet -->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
    <head>
        <title>wrapper/NoScriptWrapper.html</title>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    </head>
    <body>
           <noscript>
            <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%" id="AddCallbackExample">
                <param name="movie" value="TestProject.swf" />
                <param name="quality" value="high" />
                <param name="bgcolor" value="#ffffff" />
                <param name="allowScriptAccess" value="sameDomain" />
                <!--[if !IE]>
                <object type="application/x-shockwave-flash" data="TestProject.swf" width="100%" height="100%">
                    <param name="quality" value="high" />
                    <param name="bgcolor" value="#ffffff" />
                    <param name="allowScriptAccess" value="sameDomain" />
                <![endif]-->
                <!--[if gte IE 6]>
                    <p>
                        Either scripts and active content are not permitted to run or Adobe Flash Player version
                        10.0.0 or greater is not installed.
                    </p>
                <![endif]-->
                    <a href="http://www.adobe.com/go/getflashplayer">
                        <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash Player" />
                    </a>
                <!--[if !IE]>
                </object>
                <![endif]-->
            </object>
        </noscript>
   </body>
</html>

If your application requires functionality that is available only to scripting-enabled browsers (such as deep linking or access to the ExternalInterface API), then you can insert a message in the <noscript> block that warns the user against accessing your application while JavaScript is disabled. The following example warns users when someone with JavaScript disabled tries to run your application:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- saved from url=(0014)about:internet -->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
    <head>
        <title>wrapper/NoScriptWarning.html</title>
        <script type="text/javascript" src="swfobject.js"></script>
        <script type="text/javascript">
            var swfVersionStr = "0";
            var xiSwfUrlStr = "";
            var flashvars = {};
            var params = {};
            params.quality = "high";
            params.bgcolor = "#ffffff";
            params.allowscriptaccess = "sameDomain";
            var attributes = {};
            attributes.id = "TestProject";
            attributes.name = "TestProject";
            attributes.align = "middle";
            swfobject.embedSWF(
                "TestProject.swf",
                "flashContent", "100%", "100%",
                swfVersionStr, xiSwfUrlStr,
                flashvars, params, attributes);
        </script>
    </head>
    <body>
        <div id="flashContent"/>
           <noscript>
             <EM>Your browser either does not support JavaScript or has disabled it.
             Some features of this application require JavaScript.
            Please enable JavaScript and reload this page.</EM>
           </noscript>
   </body>
</html>