Set Cursor Focus in Flex
I have a pet peeve, although I’ll admit it’s one of many. The pet peeve is this. When starting a Flex application that requires authentication, I have to use tabbing or, heaven forbid, my mouse to set focus to the “user name” field on the login screen. Why!! We have been doing this for years in DHTML-based applications. Why stop now?!
Using Flex does throw a couple of a curve balls at you, so I thought I’d go ahead and share the solution with you.
Let’s start with the basis. The UIComponent class has a property called focusManager which gets the FocusManager that controls focus for the component and its peers. And since all UI controls inherit from UIComponent, they all automatically have this property as well. This give you access to a couple of key methods and properties necessary to set the cursor focus to a specific control.
First, you need the setFocus( ) method. The argument to setFocus() is the id of the control you want the cursor to show on. Using just this method does set focus to the control and it highlights the control as well, but it doesn’t show the cursor. You also need to set the showFocus(). Sets showFocusIndicator to true and draws the visual focus indicator on the focused object, if any.
So the code might look like this:
private function onCreationComplete():void
{
focusManager.setFocus( username );
focusManager.showFocus();
}
If you run this application as is, you’ll notice that something is still missing… the cursor!
The second part of the solution is to set focus to the flash object in the HTML wrapper. This means that you have to edit the index.template.html file in the html-template directory of your project. It also means that you have to conjure up some of the old JavaScript and DOM stuff we used to do before Flex.
All you have to do is get the flash object reference from the DOM and invoke focus() on it. Place this code at the bottom of the script that loads the flash object.
So the code might look like this:
document.getElementById("${application}").focus();
Because this file is a “template” we can use the variable, ${application}, for the application name.
The HTML page should now set focus on the Flex application and then Flex application will set focus on the TextInput control.
Now for the big “but”. This doesn”t work in Windows Firefox or Mac Safari. arrrgh!
But once you click on the SWF, it does set the focus. PS: these are know bugs in the browser.
In the Firefox 3 rc1, this has been resolved. Thanks Joe.





Your solution works on Firefox 3.
thaks.
I have no “html-template” dir. What to do?=)
The html-template directory is created by Flex Builder when you create a project. It creates this directory based on the templates folder in your Adobe Flex Builder installation. C:\Program Files\Adobe\Flex Builder 3\sdks\3.0.0\templates.
Note that there are several different templates based on the build options and that there is a set for each SDK.
I have been battling this issue for the last two days and still cannot get it to work. I think there must be a timing issue involved. It seems like I am always one TAB away from getting it to work! I have implemented your same technique total success. I see the highlight rectangle around my TextFiel, but I have to press another TAB to get the cursor in the TextField. Any suggestions?
I finally found the solution as indeed it was a timing problem and I verified it works in Internet Explorer and Firefox and Safari:
// @see http://www.kirupa.com/forum/showthread.php?t=278510
So now my code is like this:
addEventListener(FlexEvent.CREATION_COMPLETE, setDefaultFocus);
…
private function setDefaultFocus(event:FlexEvent):void {
setTimeout(setCursorPosition, 10);
}
private function setCursorPosition():void {
_propertyName.setFocus();
_propertyName.setSelection(0, 0);
}
But where in index.template.html do you put the statement;
document.getElementById(”${application}”).focus();
???
do you have a sample index.template.html to show please?
Place the code at the bottom of the script that loads the flash object (in between line 98 and 99).
document.write(alternateContent); // insert non-flash content
}
——-Here——
// –>
Hi all!
I had a problem like you.
I tryed to use “document.getElementById(”${application}”).focus();”
the same Rush’s guiding! but it is not action.
I try using by putting it on
It actions correctly.
But it must have a condition: The control you want to setFocus have cursor, must be set focus.
Cheer!
Input it like this : “”
Sorry!
body scroll=”no” onload=”document.getElementById(‘${application}’).focus()”
I don’t know why it is lost!
but it not run on FireFox and Safari.
huhuhu
I confirm it doesn’t work on FF 3.05 … Anyone has got any idea ?
Thanks a lot, you save my time.