Quick example of ExternalInterface, communicating between Flex and JavaScript

This post is more than 2 years old.

A few days ago I did some mentoring with a ColdFusion developer in Baton Rouge. He was also doing some Flex and I got to take a look at some of his work. He was making use of a feature I had not seen before, ExternalInterface. This is a rather interesting little feature. It lets you create a bridge between your Flex code and JavaScript code on the page. This is not the same as the Flex Ajax Bridge (which apparently was a Labs product and then moved into core Flex 3). I plan on looking at that more later, but here is some basic info about ExternalInterface.

At a simple level, ExternalInterface allows for two way communication between anything in the browser that uses JavaScript (remember that other plugins may have a JavaScript API, and other Flex/Flash embeds may have exposure as well). So I could write JavaScript code that runs some stuff in my Flex app. I could write Flex code that will fire off something in JavaScript.

Here is a quick example of listening for events in Flex.

<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="init()" width="220" height="200">

<mx:Script> <![CDATA[

public function init():void {

ExternalInterface.addCallback('sendMessage',getMessage)	

}

private function getMessage(m:String) { thebox.text+=m }

]]> </mx:Script>

<mx:TextArea id="thebox" />

</mx:Application>

The ExternalInterface.addCallback API allows you to specify a function name to listen for (sendMessage) and a corresponding function to run in your Flex code. In this case, I've built an API to let me pass strings to a TextArea. Very exciting, I know.

For testing, I modified the file, index.template.html. If you are new to Flex, you may not know this, but Flex uses a template HTML file to generate your view when you run your application. You don't have to use this HTML in production. You can just use the SWF. For my testing I modified this so it would be easier to work with. This template is a bit large (I'll include the source in a zip at the end) so I'll just paste in the modifications I made.

Normally your Flex application will take over the entire page. I wanted a mix of HTML and Flex. If you look at your template, you will notice the embed code uses tokens for height and width:

AC_FL_RunContent( "src", "${swf}", "width", "${width}", "height", "${height}", ... more ...

Now, if you are like me, you may wonder - where in the heck do those values come from? I had a hard time finding this in the docs. I did find an excellent blog post on it though: Macros that are available in html-template files . Long story short - if I add a width and height to my MXML Application tag (as you see in the first code listing), it will get respected in the HTML template. To be sure it was working, I also added this lovely design:

<style> body { background-color: pink; } </style>

Pink is the new black. You heard it here first folks. Ok, so I added a simple button:

<input type="button" onclick="tryit()" value="Try it">

Add added the following JavaScript:

function tryit() { document.TestJS.sendMessage('you rock') }

The basic idea for 'speaking' to the Flex application is to use the name of embed (also a token, it comes from the Flex project name) and call the method you exposed.

Here is a quick screen shot:

Ok, not so terribly exciting, but you get the idea. Note that document.X is Netscape only, it would be window.X in IE.

The flip side to this is calling JavaScript from Flex. This is done with the call API:

<mx:Button click="ExternalInterface.call('alert','Alerts are the new black')" label="Alert Me, Baby" />

As you can see, you just name the function and pass the arguments.

I'm not 100% sure where I'd use this just yet - and I want to dig more into the Flex-Ajax bridge, but for a deeper look, please see this excellent blog entry:

ExternalInterface: Flex + Javascript Get Downright Cozy

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by todd sharp posted on 7/9/2009 at 9:34 PM

I use ExternalInterface to call an anonymous JS function in my SlideSix viewer to get the domain name via JS so I know the remote site that is embedding the presentation. Very handy stuff when used properly.

It's also common to use EI with 'invisible' Flash/Flex SWF uploaders - the SWF handles the upload and exposes the internal functions to JS.

One more thing - the YouTube chromeless player uses ExternalInterface to let you play/pause etc via JavaScript.

So bottom line, cool stuff and tons of use cases...

Comment 2 by Dan Vega posted on 7/9/2009 at 9:40 PM

I am using this in my CFMU project and it really rocks. I wanted to allow people the ability to call a JavaScript method when the upload was completed and also to be able to a pass in the file name. I have a quick write up on it http://www.danvega.org/blog...

Comment 3 by Gareth Arch posted on 7/9/2009 at 9:47 PM

At my current job, we're using it to pass values in to the Flex application (rather than hard coding them into the flashVars). It allows us to embed the swf file within the current HTML structure, and still pass values between the HTML page and the Flex content, until we move all of the site to Flex.

Comment 4 by Gareth Arch posted on 7/9/2009 at 9:49 PM

Something else to check out with the ExternalInterface call.
http://dougmccune.com/blog/...
Allows you to inject a js file into the page and call methods in it. This way you don't have to hard code anything in the actual HTML wrapper, but rather just put it in your JS library.

Comment 5 by Raymond Camden posted on 7/9/2009 at 10:25 PM

I've got to admit. I'm shocked. I didn't think anyone was using it. Thanks for the examples guys!

Comment 6 by Campbell Anderson posted on 7/10/2009 at 12:25 AM

And heres a class that uses metadata to externalise methods in a class. Just a handy Util.

http://blog.xsive.co.nz/arc...

Comment 7 by TJ Downes posted on 7/10/2009 at 1:06 AM

I believe the Flex?AJAX Bridge is also based on ExternalInterface, if I recall correctly.

Comment 8 by jason olmsted posted on 7/10/2009 at 6:34 PM

I've used ExternalInterface for quite a few projects lately ... usually for Actionscript only gui elements where I forgo the Flex framework (it's too heavy when all you want to make is a navigational menu - you can create a swf that embeds a font, reads an external xml doc, renders the info and communicates with the browser for less than 12kb).

One of the niftier aspects of communicating with external javascript is that you can resize and move your flash content. In a simpler instance, with wmode=transparent, you can create drop down menus with flash.