The following example shows how you can set focus on a TextInput control in Flex by using the Flex FocusManager class and the setFocus() method.
Full code after the jump.
<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/09/23/setting-focus-in-flex-using-the-focus-manager/ -->
<mx:Application name="FocusManager_setFocus_test"
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
verticalAlign="middle"
backgroundColor="white">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
private function submitButton_click(evt:MouseEvent):void {
Alert.show(evt.currentTarget.label,
Object(focusManager.getFocus()).name);
}
private function resetButton_click(evt:MouseEvent):void {
username.text = "";
password.text = "";
Alert.show(evt.currentTarget.label,
Object(focusManager.getFocus()).name);
}
]]>
</mx:Script>
<mx:ApplicationControlBar dock="true">
<mx:Button label="Set focus to Username"
click="focusManager.setFocus(username);" />
<mx:Button label="Set focus to Password"
click="focusManager.setFocus(password);" />
</mx:ApplicationControlBar>
<mx:Form id="form"
defaultButton="{submitButton}">
<mx:FormItem label="Username:">
<mx:TextInput id="username" />
</mx:FormItem>
<mx:FormItem label="Password:">
<mx:TextInput id="password"
displayAsPassword="true" />
</mx:FormItem>
<mx:FormItem direction="horizontal"
horizontalAlign="right"
width="100%">
<mx:Button id="submitButton"
label="Submit"
click="submitButton_click(event);" />
<mx:Button id="resetButton"
label="Reset"
click="resetButton_click(event);" />
</mx:FormItem>
</mx:Form>
</mx:Application>
View source is enabled in the following example.
Due to popular demand, here is the “same” example in a more ActionScript friendly format:
<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2008/09/23/setting-focus-in-flex-using-the-focus-manager/ -->
<mx:Application name="FocusManager_setFocus_test"
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
verticalAlign="middle"
backgroundColor="white"
initialize="init();">
<mx:Script>
<![CDATA[
import mx.containers.ApplicationControlBar;
import mx.containers.Form;
import mx.containers.FormItem;
import mx.containers.FormItemDirection;
import mx.controls.Alert;
import mx.controls.Button;
import mx.controls.TextInput;
private var usernameButton:Button;
private var passwordButton:Button;
private var username:TextInput;
private var password:TextInput;
private var submitButton:Button;
private var resetButton:Button;
private function init():void {
usernameButton = new Button();
usernameButton.label = "Set focus to Username";
usernameButton.addEventListener(MouseEvent.CLICK,
usernameButton_click);
passwordButton = new Button();
passwordButton.label = "Set focus to Password";
passwordButton.addEventListener(MouseEvent.CLICK,
passwordButton_click);
var appControlBar:ApplicationControlBar;
appControlBar = new ApplicationControlBar();
appControlBar.dock = true;
appControlBar.addChild(usernameButton);
appControlBar.addChild(passwordButton);
addChildAt(appControlBar, 0);
username = new TextInput();
username.name = "username";
password = new TextInput();
password.displayAsPassword = true;
password.name = "password";
submitButton = new Button();
submitButton.label = "Submit";
submitButton.name = "submitButton";
submitButton.addEventListener(MouseEvent.CLICK,
submitButton_click);
resetButton = new Button();
resetButton.label = "Reset";
resetButton.name = "resetButton";
resetButton.addEventListener(MouseEvent.CLICK,
resetButton_click);
var formItem1:FormItem = new FormItem();
formItem1.label = "Username:";
formItem1.addChild(username);
var formItem2:FormItem = new FormItem();
formItem2.label = "Password:";
formItem2.addChild(password);
var formItem3:FormItem = new FormItem();
formItem3.direction = FormItemDirection.HORIZONTAL;
formItem3.setStyle("horizontalAlign", "right");
formItem3.percentWidth = 100;
formItem3.addChild(submitButton);
formItem3.addChild(resetButton);
var form:Form = new Form();
form.defaultButton = submitButton;
form.addChild(formItem1);
form.addChild(formItem2);
form.addChild(formItem3);
addChild(form);
}
private function usernameButton_click(evt:MouseEvent):void {
focusManager.setFocus(username);
}
private function passwordButton_click(evt:MouseEvent):void {
focusManager.setFocus(password);
}
private function submitButton_click(evt:MouseEvent):void {
Alert.show(evt.currentTarget.label,
Object(focusManager.getFocus()).name);
}
private function resetButton_click(evt:MouseEvent):void {
username.text = "";
password.text = "";
Alert.show(evt.currentTarget.label,
Object(focusManager.getFocus()).name);
}
]]>
</mx:Script>
</mx:Application>



Another nice, clean example but… there are loads of issues with the FocusManager. In fact, it rarely works as you would expect and definitely not as your simple example implies. It’s very difficult to set the focus when a .swf loads and the ‘I-Beam’ caret and where you actually are on the page constantly gets out of sync, confusing users.
All in all, it is very broken except in the simplest circumstances so before you try and implement it tyry Googling for “Flex setfocus problem” and see what you will be up against.
And as a reminder, if you do encounter bugs with the Flex SDK (or Flex Builder, Flex Documentation, Flash Player, etc), the best place to report them is http://bugs.adobe.com/flex/ .
Peter
This is a great example but what would you do to make a TextInput field have focus by default?
time2design,
I think something like this should work:
<mx:Application name="FocusManager_setFocus_test" xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle" backgroundColor="white" creationComplete="focusManager.setFocus(username);">Peter
You would think this would work but it was unsuccessful for me… I’m only able to set the focus on a text input box by firing it off via a button push. The creation complete doesn’t do it. Very frustrating. And it’s not even the main form in my application so the swf already received focus (I’m using a togglebuttonbar and a viewstack and the text input is on a form that displays after pushing a menu option on the togglebuttonbar) … not sure why the creation complete doesn’t work.
Ken
Hi OneWorldMedia, try to use the show() method instead of creationcomplete.
Cheers,
Rui
Hi Terroso.Costa, I have tried to use to the show() method instead of creationcomplete. But not success.
show() did not work for me.
tinput.addEventListener(FlexEvent.UPDATE_COMPLETE, focus); public function focus(event:Event):void { var ti:TextInput = TextInput(event.currentTarget); ti.focusManager.setFocus(ti); }FocusManager works half for me ..
It does light up the border around my TextInput but the cursor is not blinking inside nor can I type before actually clicking in the TextInput. This is with use of creationcomplete().
Show() does nothing :(
Hello,
One work around for setting initial focus is to manually dispatch an event, like mouse click, then have the event handler set the focus.
I ran into a tough spot when using the mouse over event to set focus. If you mouse over a component and a wipe plays, when the wipe “reveals” what is underneath, the target/current target becomes what is revealed. When the wipe effect completes, the “curtain” gets the focus again.
So, in my case, I had to do this:
var myPoint:Point = new Point();
myPoint.x = stage.mouseX;
myPoint.y = stage.mouseY;
var i:int = (stage.getObjectsUnderPoint(myPoint).length);
if ( InteractiveObject(stage.getObjectsUnderPoint(myPoint)[i-1].parent).toString()
!=
this.toString()
)
{
trace(”setting focus”);
stage.focus=InteractiveObject(stage.getObjectsUnderPoint(myPoint)[i-1].parent);
}
I am relatively new to Flex development, so I do not know if this approach is “good”, but it works!
Hope this helpls.
Larry
I am sorry, this is wrong:
the “curtain” gets the focus again.
what happens is that the curtain DOES NOT get the focus again. Which is why I had to fire set the focus manually. Otherwise, the subsequent keyboard stroke, which depends on focus, does not occur.
Hello Everyone,
As this blog has really help me so very much in improving my development skills, I wanted to take the time to solve this issue.
Here is the solution:
//Set the focus to the Text input field. private function setFocusOnStart(event:Event):void { stage.focus=InteractiveObject(myTextInput); }If you want to create a login control that has focus and is waiting for user input when your application firsts starts, there are a few things you need to do.
1. Inside the HTML page that serves up your SWF file, create a Javascript function that will automatically give the SWF movie focus, and call it from Flex using the ExternalInterface. This is necessary to give the SWF focus in both FireFox and Internet Explorer.
2. Set focus to the TextInput component. This highlights your TextInput component.
3. Set the selectionBeginIndex and selectionEndIndex to 0. This puts the cursor in the TextInput control and allows the user to just start typing.
********************************************
So here’s the code to make this all happen!
********************************************
1. Create a Javascript function inside your index.template.html or HTML wrapper file that holds your SWF.
<script language="JavaScript" type="text/javascript" > <!-- function setFocus() { window.document.FuelMasterSite.focus(); } // --> </script>NOTE: Replace FuelMasterSite with the name of your SWF movie.
2. Create the MXML Code that will fire an init() method when your application is done loading.
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init(event)" > <mx:TextInput id="TXI_UserName" /> <mx:TextInput id="TXI_Password" /> </mx:Application>3. Create the
init()method in Actionscript:import flash.external.ExternalInterface; import mx.controls.Alert; private const EMPTY_STRING:String = ''; private function init(event:Event):void { if (ExternalInterface.available) { ExternalInterface.call('setFocus'); } else { Alert.show("Browser not available"); } focusManager.setFocus(TXI_UserName); TXI_UserName.text = EMPTY_STRING; TXI_Password.text = EMPTY_STRING; LBL_Feedback.text = EMPTY_STRING; TXI_UserName.selectionBeginIndex = 0; TXI_UserName.selectionEndIndex = TXI_UserName.text.length; }Hi Bryan
Thanks for this. Your solution worked for me.
Seems like a lot of lines of code to do what you’d think would be a fairly simple task.
Another thing I thought I’d - I was having trouble getting it to work until I removed the space you had between “<” and “script” in the JavaScript declaration in step 1. Just something that might also trip up other people….
This works fin in Firefox and IE7, however, it does not work in Safari or Chrome.
Does anyone know how the script can be changed to cater for these browsers.
(ups last post has an error sorry)
ExternalInterface did not do the job for me, but using navitageToURL did:
AS3 code
private function onCreationComplete(event:FlexEvent):void
{
// - - all code related to focus of a specific component place it here - -
var u:URLRequest = new URLRequest(”javascript:focusFlexApp()”);
navigateToURL(u,”_self”);
}
Javascript code on ‘index.template.html’
function focusFlexApp()
{
var app = document.getElementById(’${application}’);
app.focus();
}
Thanks Bryan. Your solution is exactly what I was looking for.