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">
<!-- 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.
{
//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.

