0

I need to know why JavaScript can't talk back to Flex. I have a project that is going to use JavaScript to play a given video file. Its running on a custom MVC framework where asset files are loaded via the /static prefix.

Example: http://helloworld/static/swf/movie.swf`

I compile my Flex application using the mxmlc binary with options -static-link-runtime-shared-libraries=true, -use-network=true and --debug=true.

Flex

<?xml version="1.0" encoding="utf-8"?>
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    creationComplete="init()">
    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import flash.external.ExternalInterface;
            private function init():void {
                log("Logging...");
                if (ExternalInterface.available) {
                    ExternalInterface.call("HelloWorld.initFlash");
                    ExternalInterface.addCallback("playVideo", playVideo);
                }
            }
            public function playVideo():void {
                log("Playing video...");
            }
            public function log(message:String):void {
                if (ExternalInterface.available) {
                    ExternalInterface.call(
                        "function log(msg){ if (window.console) { console.log(msg); } }", 
                        message);
                }
            }
        ]]>
    </fx:Script>
    <s:Panel id="myPanel" title="Hello World" x="20" y="20">
        <s:layout>
            <s:HorizontalLayout 
                paddingLeft="10"
                paddingRight="10"
                paddingTop="10"
                paddingBottom="10"
                gap="5" />
        </s:layout>       
    </s:Panel>
</s:Application>

HTML

<!DOCTYPE HTML>
<html lang="en-US">
    <head>
        <meta charset="UTF-8">
        <title>Hello World</title>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
        <script type="text/javascript">
            $(function(){
                var swfVersionStr        = "10.1.0";
                var xiSwfUrlStr          = "playerProductInstall.swf";
                var flashvars            = {};
                var params               = {};
                var attributes           = {};
                params.allowscriptaccess = "sameDomain";
                params.quality           = "high";
                params.bgcolor           = "#FFFFFF";
                params.allowfullscreen   = "true";
                attributes.id            = "HelloWorld";
                attributes.name          = "HelloWorld";
                attributes.align         = "left";
                swfobject.embedSWF( 
                    "HelloWorld.swf", 
                    "flash-content", 
                    "100%", "100%", 
                    swfVersionStr, xiSwfUrlStr, flashvars, params, attributes ); 
                HelloWorld = function(){
                    return {
                        initFlash : function() {
                            console.log("Called from Flex...");
                            console.log($("#HelloWorld").get(0).playVideo("be6336f9-280a-4b1f-a6bc-78246128259d"));
                        }
                    }
                }();
            });
        </script>
        <style type="text/css">
            #flash-content-container {
                width  : 400px;
                height : 300px;
            }
        </style>
    </head>
    <body>
        <div id="layout">
            <div id="header"><h1>Hello World</h1></div>
            <div id="flash-content-container">
                <div id="flash-content"></div>
            </div>
        </div>
    </body>
</html>

Output

Logging...
Called from Flex...
2
  • Have you look at this article? livedocs.adobe.com/flex/3/html/… Commented Sep 22, 2011 at 17:46
  • I think I have looked over every reference page on ExternalInterface and tried the examples and didn't work. Any suggestions on other resources that might help. In my code Flex can talk to JavaScript but not the reverse Commented Sep 22, 2011 at 18:15

2 Answers 2

1

I had the same issue, in the link provided by Chris Cashwell it shows the base for the solution.

Flex MXML

    <?xml version="1.0" encoding="utf-8"?>
    <s:Application 
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx"
        creationComplete="init()">
        <fx:Script>
            <![CDATA[
                import mx.controls.Alert;
                import flash.external.ExternalInterface;
                private function init():void {
                    consoleLog("Hello World");
                    try 
                    {  
                        Security.allowDomain("*"); //I need to add this.
                        ExternalInterface.marshallExceptions = true;
                        ExternalInterface.addCallback("sendAlert",sendAlert);
                        ExternalInterface.call("initCallBack");
                    }  catch (error:Error) {
                        consoleLog("Error in ExternalInterface");                           
                        consoleLog("Error" + error.message);
                    }
                }
                public function sendAlert(s:String):void
                {
                    Alert.show(s);
                }
                public function consoleLog(message:String):void {
                    if (ExternalInterface.available) {
                        ExternalInterface.call(
                            "function log(msg){ if (window.console) { console.log(msg); } }", 
message);
                    }
                }
            ]]>
        </fx:Script>
        <s:Panel id="panel1" title="Hello World" x="20" y="20">
            <s:layout>
                <s:HorizontalLayout 
                    paddingLeft="10"
                    paddingRight="10"
                    paddingTop="10"
                    paddingBottom="10"
                    gap="5" />
            </s:layout>
            <s:TextArea id="textarea1" 
                width="300" height="100" 
                text="Hello World" />       
        </s:Panel>
    </s:Application>

HTML

<!DOCTYPE HTML>
<html lang="en-US">
    <head>
        <meta charset="UTF-8">
        <title>Hello World</title>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
        <script type="text/javascript">
            var flexApp;
            function initCallBack() {  
                flexApp = document.getElementById("HelloWorldFlex");
                if (flexApp != undefined) { 
                   try {
                      flexApp.sendAlert( "Hello World" );
                   } catch(err) {
                      console.log("There was an error on the flex callback.");
                      console.log(err);     
                   }
                } else {
                    console.log("The flex object does not exist yet");
                }
                return;
            } 
            $(function(){
                HelloWorld = function(){
                    return {
                        init : function() {
                            var swfVersionStr        = "10.1.0";
                            var xiSwfUrlStr          = "playerProductInstall.swf";
                            var flashvars            = {
                                bridgeName : "flex",
                            };
                            var params               = {};
                            var attributes           = {};
                            params.allowscriptaccess = "always";
                            params.quality           = "high";
                            params.bgcolor           = "#FFFFFF";
                            params.allowfullscreen   = "true";
                            attributes.id            = "HelloWorldFlex";
                            attributes.name          = "HelloWorldFlex";
                            attributes.align         = "left";
                            swfobject.embedSWF( 
                                "HelloWorld.swf", 
                                "flash-content", 
                                "100%", "100%", 
                                swfVersionStr, xiSwfUrlStr, flashvars, params, attributes ); 

                        }
                    }
                }();
                HelloWorld.init();
            });
        </script>
        <style type="text/css">
            #flash-content-container {
                width  : 400px;
                height : 300px;
            }
        </style>
    </head>
    <body>
        <div id="layout">
            <div id="header"><h1>Hello World</h1></div>
            <div id="flash-content-container">
                <div id="flash-content"></div>
            </div>
        </div>
    </body>

I tested it on Flex 4.1, please notice that i had to add the bin-debug folder (C:\flexworkspaces\project\bin-debug) to the flash security app ( http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.htmlconfiguration ) Please notice that this internet URL is in fact an app that modifies the Flex local configuration.

The logs can be displayed in the Firebug console.

Sign up to request clarification or add additional context in comments.

Comments

-1

Decided to go with FABridge. For others heres a working example.

MXML

<?xml version="1.0" encoding="utf-8"?>
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:bridge="bridge.*"
    creationComplete="init()">
    <fx:Declarations>
        <bridge:FABridge bridgeName="flex" />
    </fx:Declarations> 
    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import flash.external.ExternalInterface;
            private function init():void {
                consoleLog("Hello World");
            }
            public function sendAlert(s:String):void
            {
                Alert.show(s);
            }
            public function consoleLog(message:String):void {
                if (ExternalInterface.available) {
                    ExternalInterface.call(
                        "function log(msg){ if (window.console) { console.log(msg); } }", 
                        message);
                }
            }
        ]]>
    </fx:Script>
    <s:Panel id="panel1" title="Hello World" x="20" y="20">
        <s:layout>
            <s:HorizontalLayout 
                paddingLeft="10"
                paddingRight="10"
                paddingTop="10"
                paddingBottom="10"
                gap="5" />
        </s:layout>
        <s:TextArea id="textarea1" 
            width="300" height="100" 
            text="Hello World" />       
    </s:Panel>
</s:Application>

HTML

<!DOCTYPE HTML>
<html lang="en-US">
    <head>
        <meta charset="UTF-8">
        <title>Hello World</title>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
        <script type="text/javascript" src="bridge/FABridge.js"></script>
        <script type="text/javascript">
            var flexApp;
            var initCallback = function() {  
                flexApp = FABridge.flex.root();  
                var textarea1 = flexApp.getTextarea1();
                textarea1.setText( "Hello World (Updated)" );
                flexApp.sendAlert( "Hello World" );
                return;
            } 
            $(function(){
                HelloWorld = function(){
                    return {
                        init : function() {
                            var swfVersionStr        = "10.1.0";
                            var xiSwfUrlStr          = "playerProductInstall.swf";
                            var flashvars            = {
                                bridgeName : "flex",
                            };
                            var params               = {};
                            var attributes           = {};
                            params.allowscriptaccess = "sameDomain";
                            params.quality           = "high";
                            params.bgcolor           = "#FFFFFF";
                            params.allowfullscreen   = "true";
                            attributes.id            = "HelloWorld";
                            attributes.name          = "HelloWorld";
                            attributes.align         = "left";
                            swfobject.embedSWF( 
                                "HelloWorld.swf", 
                                "flash-content", 
                                "100%", "100%", 
                                swfVersionStr, xiSwfUrlStr, flashvars, params, attributes ); 
                            FABridge.addInitializationCallback( "flex", initCallback );
                        }
                    }
                }();
                HelloWorld.init();
            });
        </script>
        <style type="text/css">
            #flash-content-container {
                width  : 400px;
                height : 300px;
            }
        </style>
    </head>
    <body>
        <div id="layout">
            <div id="header"><h1>Hello World</h1></div>
            <div id="flash-content-container">
                <div id="flash-content"></div>
            </div>
        </div>
    </body>
</html>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.