Flex – controlling parent page by Javascript using ExternalInterface

When developing a Flex application you are generally involved with the nitty gritty coding, getting your text boxes looking right; hooking up that button and making sure your webservices are behaving. Something you probably haven’t started to consider is that the SWF you end up with is going to have to live on a page somewhere. When you get closer to release time, suddenly your thoughts turn to integrating your application with an actual webpage.

A very useful trick to be aware of is that your Flex application can control its parent page to a certain extent by executing Javascript on it. So for example, at graffed.com you’ll notice that instead of showing the Flex application straight away, we show a basic loading image in HTML and then once the entire app has loaded, we switch the loading image to a button to launch the app.

Loading the app

Loading the app

Loading completed

Loading completed


This way, visitors are shown a landing page which loads very quickly that they can read through, and the application is loaded in the background. Once the application is loaded, the parent page displays a nice button for them to launch. It’s also good for SEO since the parent page is what the search engines will see, rather than a blank page with a Flex application.

To achieve this magic, we use ExternalInterface to interact with the parent page. First off, create an appropriate Javascript function within your parent page for the Flex app to call, let’s say it’s called flexLoaded(). To call this Javascript method in your Flex application, you simply put:

ExternalInterface.call("flexLoaded");

Exceptionally easy and a very powerful way to influence the page your SWF resides in. Don’t forget to import the appropriate library at the top of the Actionscript, i.e

import flash.external.*;

Announcing graffed.com, the new way to track your body shape, not just your weight

I’ve hinted a few times about a Flex application I’ve been working on. Well now is the time to reveal the app, graffed.com.

Graffed is a site that lets you track your body shape instead of just your weight. You can see in real time your silhouette overlaid with your target body, showing you where you’ve lost weight and shaped up. It was a long hard slog to write but I’ve been very impressed with the Flex technology (Flash for programmers if you will) and it’s taught me a lot. For a limited time, premium accounts are totally free so sign up and give it a go:

The new site in all its glory

The new site in all its glory

Flex – extra unbound custom parameters in a webservice

One of the greatest parts of Flex is the ease of integration to other servers. As a client side technology, Flex is clearly designed to embrace communication between itself and external servers and not make the programmer jump through hoops to get there. To that end it has the component mx:HTTPService, they can literally be defined in the XML components of your MXML document. That is seriously trivial, close to as easy as writing a tag in an HTML document. Forget worrying about establishing connections, sending data and processing the data returned. Typically, the values sent by the web service are tied to components in the document, e.g. say we have a webservice which sends the value of a textbox called myTextBox to the url http://myserver.com/myurl:

<mx:Script>
    <![CDATA[

        import mx.controls.Alert;
        import mx.rpc.events.ResultEvent;

        private function handleReturn(event:ResultEvent):void
        {
            Alert.show("returned from the webservice");
        }

        private function send():void
        {
            myWebServiceName.send();
        }

    ]]>
</mx:Script>

<mx:HTTPService
    id="myWebServiceName"
    url="http://myserver.com/myurl"
    contentType="application/xml"
    resultFormat="e4x"
    method="POST"
    result="handleReturn(event)">
    <mx:request>
        <sentdata>
            <text>{myTextBox.text}</text>
        </sentdata>
    </mx:request>
</mx:HTTPService>

<mx:TextInput id="myTextBox" />

Here the method send() will invoke the webservice with the up to date textbox data, parse the returned data as XML and call the callback method handleReturn. Great. But what if we want to attach data which is not so easily bindable, say the property of an object defined in your actionscript. Then we just need to set it on the webservice before calling .send(). For example say you had an global ActionScript object user with a public property called id which you needed to send with the request as user_id:

private function send():void
{
    myWebService.sentdata.user_id = user.id;
    myWebServiceName.send();
}

Note that sentdata is just the name of the top level XML node I include all the sent data under, it could be anything of your choosing. Because of the slight slackness of object structure in Flex and Actionscript, you can define the dynamic XML structure on the fly with myWebService.MYTOPNODE.MYNODE = DATA where MYTOPNODE, MYNODE and DATA are all what you need. Good stuff.

Flex application initialisation code using creationComplete

This is only a very small post, but something I initially struggled to find so I have deemed it worthy.

Compared to traditional UI coding, Flex hides the application flow entirely away from the programmer. You don’t need to worry about initialising the window objects, you don’t need to know about the event processing thread and you should not be concerned with how your components get drawn. All in all that is a fantastic thing. But I initially struggled to determine how to run some code once a Flex application has been loaded. For example in my latest (and soon to be posted about) project graffed, on initialisation I wanted to load the user details if they were cookied. It’s actually extremely easy, in your top level MXML mx:Application tag, simply add the attribute creationComplete=”init()”. Here init() refers to a function within the script data of the MXML file, e.g.

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()">
    <mx:Script>
        <![CDATA[
        import mx.controls.Alert;

        private function init():void
        {
            Alert.show("Starting the program"):
        }
        ]]>
    </mx:Script>
</mx:Application>

Here, the program will run init() on launch and give you a nice informative message. Simple.

Adobe Flex – Controlling focus with ActionScript

For my up and coming project, very soon to be released, I’ve been using the client side Flash based technology Adobe Flex. The best way to describe Flex is probably Flash for programmers. It gives the programmer complete control over the application, using XML to define components and embedded ActionScript to specify the more complex interactions between them. It’s a fantastic technology, produces very slick interfaces very fast and best of all, is totally free. Well, free if you’re happy using the command line SDK to compile, otherwise their IDE is only about £150.

Having said all that, there are a couple of things that you think should be easy, and turn out not to be so obvious. This is particularly true when you want to tweak the built in UI functionality to do something different. The Flex developers have generally done a great job, but some of the form and error handling is not quite ideal and needs some tweaks to really work well.

The application I’m writing has lots of text boxes in a vertical column to fill in, one after the other. Straight out of the box the tab order works sensibly which is great, but I had a lot of feedback requesting that pressing enter should advance the form to the next field. Fortunately text fields have an “enter” event defined so I thought I could be clever and put something like:

    &lt;mx:TextInput enter=&quot;focusOut&quot; /&gt;

since focusOut is another event associated with TextInputs. I suppose practically speaking I shouldn’t expect that to work, but I thought there must be a built in function I could call on pressing enter to advance the form focus. Anyway, either there isn’t one or I couldn’t find it, so instead I defined a method called nextElement which will programmatically find the next component and set the focus on it, as so:

&lt;mx:Script&gt;
    &lt;![CDATA[
        import mx.managers.IFocusManagerComponent;

        public function nextElement():void
        {
            var nextComponent:IFocusManagerComponent = focusManager.getNextFocusManagerComponent(true);
            nextComponent.setFocus();
        }
    ]]&gt;

&lt;/mx:Script&gt;

&lt;mx:TextInput enter=&quot;nextElement()&quot; /&gt;

The code should be pretty straight forward, the method simply finds the next component using the focusManager and sets the focus on that. Easy when you know how.