Nothing is more annoying than loading up a full browser flex app that has a login screen… It looks like it’s ready so you start typing only to realize that doesn’t let you type anything in. Usually, this is because your SWF file doesn’t have the browser focus. Even if you’ve set the focus to a text input field in ActionScript, you can still fall victim to this issue.

I’d like to share a few techniques I’ve used to ensure that the Flex app is able to get the browser’s focus immediately after loading.

First, you need to ensure that your wmode is set to opaque inside your html script. This isn’t required for all browsers, but in my layman’s testing, Chrome seemed to need it. If you’re using swfobject (the default for a FlashBuilder 4 app), customizing your html template will look something like this.

        <script type="text/javascript" src="swfobject.js"></script>
        <script type="text/javascript">
            <!-- For version detection, set to min. required Flash Player version, or 0 (or 0.0.0), for no version detection. -->
            var swfVersionStr = "${version_major}.${version_minor}.${version_revision}";
            <!-- To use express install, set to playerProductInstall.swf, otherwise the empty string. -->
            var xiSwfUrlStr = "${expressInstallSwf}";
            var flashvars = {};
            var params = {};
            params.quality = "high";
            params.bgcolor = "${bgcolor}";
            params.allowscriptaccess = "sameDomain";
            params.allowfullscreen = "true";
            params.wmode = "opaque";
            var attributes = {};
            attributes.id = "${application}";
            attributes.name = "${application}";
            attributes.align = "middle";
            swfobject.embedSWF(
                "${swf}.swf", "flashContent",
                "${width}", "${height}",
                swfVersionStr, xiSwfUrlStr,
                flashvars, params, attributes);
            <!-- JavaScript enabled so display the flashContent div in case it is not replaced with a swf object. -->
            swfobject.createCSS("#flashContent", "display:block;text-align:left;");
        </script>

Next, you need to run a bit of javascript code to set the focus to your Flex app after it has loaded. There are a number of techniques floating around to do this from your html template, but I prefer the tried and true method of using ExternalInterface from inside your Flex app’s applicationComplete handler. That way, you’re absolutely sure everything has loaded and you’re ready to give yourself the focus.

protected function applicationCompleteHandler(event:FlexEvent):void
{
    //set focus to this app using javascript
    if(ExternalInterface.available)
    {
        ExternalInterface.call("eval", "document.getElementById('" + ExternalInterface.objectID + "').tabIndex=0");
        ExternalInterface.call("eval", "document.getElementById('" + ExternalInterface.objectID + "').focus()");
    }
}

Setting the tabIndex to a value is another one of those quirky Chrome requirements. I found it on a bug report for Google Chrome and it seems to work for me. http://code.google.com/p/chromium/issues/detail?id=27868#c15 I’ve tested this code in Firefox, IE, and Chrome. It should work in Safari as well, but I haven’t tested that one.

Post to Twitter

Posted by Andrew, filed under as3, Flex. Date: December 30, 2010, 6:42 pm | 17 Comments »

17 Responses

  1. equ Says:

    I think that more appropriate would be using callback from swfobject. In some situations stealing focus by app from another node might not be a good behavior.

    Using callback makes it easier to fix that behavior if you are working in a team (flash dev makes an app and some oteher frontend/backend guy puts it on site).

    Reference:
    Swfobject api for using callback function

  2. Vinícius Says:

    Thank you very much for this!

  3. Andrew Says:

    @equ, In some cases, I found that the callback didn’t work correctly. It could be that the callback is fired when the swf is embedded (but not completely loaded yet). By using applicationComplete, I ensure that everything is completely loaded. I’m also not concerned about stealing focus from another app since I’m dealing with a full-browser flex application.

  4. [Adobe Flex] Definindo o foco na aplicação | Erko Bridee Says:

    [...] http://www.flexjunk.com/2010/12/30/managing-initial-swf-focus-in-all-browsers/ [...]

  5. Vincent Deschenes Says:

    Setting wmode to opaque and tabIndex=0 does the trick but then ctrl-c to copy is not working anymore on the text field. This is a bug or a limitation of the opaque mode.

    Any idea on how to solve this problem ?

  6. fred Says:

    setting wpmode to opaque also seems to have some very weird effect on the performance of the rendering of my app – which got fairly sloppy. My flex + js knowledge is too limited to have any theories on why this would be the case, but I would love to know if you do, and if there are any workarounds that you could think of.

    thank you!

    f

  7. sai Says:

    Works in chrome, but not in safari for windows 3.2

  8. jack Says:

    doesn’t work in chrome beta 14.0.835.94

  9. Karl Says:

    This is working for me now in Explorer 8.0.6, Firefox 4.0.1, and Safari 5.0.5, but it does not work in Chrome 14.0.835.94 beta-m or in Opera 11.50. Any new ideas to get focus in these browsers? Mainly Chrome, I browse in Chrome so I’d love my apps to work the way I want them to in Chrome.

  10. Emmad Says:

    It does not work when i set wmode =”window”.
    I cant change it to “opaque” because i need working scroll bar (which is not available in “opaque mode”).
    I have a sign-in page where i need the focus to be set automatically and after that i also need scroll bar to be working.
    What should I do?
    Brower is “Chrome”

  11. Sujith Says:

    Any updates on this topic as the above mentioned solution is not working on all browsers for me.

  12. Vicente Maciel Jr Says:

    Very useful piece of code! Nice job! Thanks!

  13. Dave Vaughan Says:

    nice one. have trgied a few things this evening, and i think that the size of the flex loading sequence leaves no choice but to do this, an onload nor a callback can be relied upon. this worked first time.

    of course, i’m using a full window app so i dont have to worry about other items on the page.

  14. Matthew Says:

    Shame that adding wmode=”opaque” makes my SWF slow to a crawl… and because I can’t do that, I can’t find any way to focus the SWF on load in Chrome :( I’m very sad.

  15. shool Says:

    worked like a charm both in chrome and firefox thanks.

  16. The New Mr Says:

    Thanks SO much for this!

  17. AllMedia Software's Twitter martketing tool Says:

    Today, I webt to the beachfront with my kids. I found a sea shell and gave
    it tto my 4 year old daughter and said “You can hear the ocean if you put this to your ear.”
    Shhe placed the shel to her ear aand screamed.
    Thewre was a hermit crab inside and itt ppinched her ear.

    She never wants to ggo back! LoL I know tnis is tottally off topic but
    I had too tdll someone!

Leave a Comment

 
Your comment

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.