Flex: IFrame Map Demo

As requested here is an IFrame map demo. It took me a bit of time as it’s not that easy to put together. The application looks like this:

IFrame Map App

You will need the full project to examine as it isn’t just encapsulated by the Flex code. There is a load of javascript and the magic of FABridge to get your head around.

This is currently only a FlexBuilder2 project. I haven’t got around to converting it to FB3. The reason for this is that there are hooks into the required javascript from all sorts of places including the ‘index.template.html’ file. Recreating the project from scratch means these are blasted by the new project option in FB3 and it’s a bit of chore to generate all the required includes that the project needs.

Here is a (rough) diagram of how the javscript is arranged.

IFrame Map App

The ‘MapClient.js’ component presents a generalised API to the FABridge layer, this abstracts the implementation details of the map down into the controller component ‘MapOSController.js’. The controller implements the real details of whichever map is plugged in to the client. In this case it is OpenLayers whereas in flexTraffic I have a similar component which implements the map interface for a Google map.

Flex

Map communication from the Flex side takes the form of generating events which the ‘MapClient’ has registered listeners for (through FABridge). The advantage of this over using ‘ExternalInterface’ calls is that FABridge marshalls the objects across the Flex/Javascript layer and turns the Plain Old Flex Objects (POFO’s) into javascript objects complete with getters and setters for member variables. This is an extremely powerful mechanism.


flexApp.addEventListener("ResizeFrameEvent", function(event) {self.controller.resizeFrame(event.getWidth()-self.offset, event.getHeight()-self.offset)});
flexApp.addEventListener("CentreFrameEvent", function(event) {self.controller.centerOn(event.getLatitude(), event.getLongitude())});

See the ‘getWidth’ and ‘getHeight’ functions? These are generated automatically by Fabridge from the Flex event which the listener registered.


public class ResizeFrameEvent extends Event
{
public static const EVENT_RESIZE_FRAME:String = "ResizeFrameEvent"

public var width:Number;
public var height:Number;

public function ResizeFrameEvent(width:Number, height:Number):void
{
super (EVENT_RESIZE_FRAME, true);

this.width = width;
this.height = height;
}
}

Javascript

The javscript side communicates with the Flex app by calling Flex methods directly. The method function must be declared in the application mxml at the same level as the FABridge controller definition. Note that the functions which perform this direct communication are abstracted further by making them plugin functions to the controller at the client level.

self.controller.addMapViewChangedHandler(function(a,b,c,d)
{
var flexApp = self.frame.FABridge.flash.root();
flexApp.onMapViewChanged(a,b,c,d);
});

This application exhibits all of the tricks I have invented to embed an html page into a Flex application. If you are interested in using the Flex IFrame then I suggest if you understand this you will have mastered all of the techniques required to make something like flexTraffic. The demo doesn’t have that much of a wow factor but all of the magic is in the code. There is no quick dropin code to acheive this kind of thing, it takes a bit of inventiveness and graft.

Comments

5 Responses to “Flex: IFrame Map Demo”

  1. harley on April 9th, 2008 12:04 pm

    aagh..
    I don’t understand, but now I will try it. the documetation didn’t seem to say anything about how to code the bridge if it’s in an Iframe..but here you have done it. good job.
    this is very cool.
    thanks.
    i will let you know how it goes.

  2. harley on April 11th, 2008 8:59 pm

    hi.
    could break out a little more detail how the communication works between flash/flex and then into the Iframe?
    I have my activex component in the iframe, I have flex sending out to java script, testing is just poping up an alert dialog box. so that works…

    I have javascript that needs to be called outside of the javascript I am calling to using the bridge.

    so, maybe just an include is all i need, but i need to be able to get the activex name space; it’s in the this.frame = parent right? or is it a child? you’re example is using self. so, maybe i am at the wrong level…

  3. Administrator on April 12th, 2008 1:53 pm

    Harley, I am assuming that there is some sort of javascript interface to the ActiveX control.

    According to this page

    http://www.devarticles.com/c/a/JavaScript/JavaScript-and-Embedded-Objects/13/

    You would interace with the ActiveX control using ‘document’ e.g.

    document.myActiveXObject.play();

    Al

  4. harley on April 14th, 2008 9:02 pm

    yes you are right. thank you, this is a good reference.
    that confirms my understanding and also provides the example with the activex component.

    in your modification of the iframe.js there is an ‘id’ but does there need to be an iframe ‘name’ assigned as well?

    I am using this to get the iframe in the java script:
    var myframe= this.document.getElementById(“IframeViewer”);

    Along with your site and then this site:
    http://www.dyn-web.com/tutorials/iframes/refs.php
    provides a good basic example of communication between iframes and the activex component.

    I still haven’t made the communication between them, but might be closer today, so hope I can figure it out.

    but, I am trying this..
    var myframe= this.document.getElementById(“IframeView”);
    but, according to these references I should be able to then use:
    {
    var myplugin = myframe.contentDocument.getElementById(“PlugIn”);
    }
    then send commands to it like:
    myplugin.play();

    thanks!

    Now, How can i do the samething.. only use the div or iframe content =””???

    which is what your modification accomplishes right?

  5. harley on April 14th, 2008 10:39 pm

    aah… i see. i went sideways on the div, which gets named the same as the iframe, which then gets the iframe_

    var myframe = this.document.getElementById(‘iframe_IframeView’);
    var myplugin = myframe.contentWindow.document.getElementById(‘Player’);

    this then gets me the object id of the activex.
    thanks again.

Leave a Reply