Filling out electronic forms is loads of fun… everyone can agree on that. However, when the focus is placed on the first input control, the fun level increases exponentially.
Why?
Because moving your hand from the keyboard to the mouse requires work… and nobody likes that.
In MXML and ActionScript, setting the focus to an input control is extremely easy. For example take the following component:
<?xml version="1.0" encoding="utf-8"?> <mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="abolute" width="400" height="300"> <mx:Form> <mx:FormItem label="Username:"> <mx:TextInput id="uname" /> </mx:FormItem> <mx:FormItem label="Password:"> <mx:TextInput id="pwd" displayAsPassword="true" /> </mx:FormItem> </mx:Form> </mx:TitleWindow>
Typically, Title Window components are viewed as Pop Ups. When the Pop Up is launched via the PopUpManager the Title Window component gains focus within Flash player (I’ll get to why this is important later). To set the focus to a text input control, add code to the creationComplete event of the Title Window, like so:
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
layout="horizontal" width="400" height="300"
creationComplete="{onLoad(event)}">
<mx:Script>
<![CDATA[
import mx.managers.FocusManager;
private function onLoad(event:Event):void{
focusManager.setFocus(this.uname);
}
]]>
</mx:Script>
<mx:Form>
<mx:FormItem label="Username:">
<mx:TextInput id="uname" />
</mx:FormItem>
<mx:FormItem label="Password:">
<mx:TextInput id="pwd" displayAsPassword="true" />
</mx:FormItem>
</mx:Form>
</mx:TitleWindow>
Additionally, you can bypass the call to the focusManager object and call the setFocus() method of the Text Input component:
this.uname.setFocus();
Now, to the PROBLEM…
If you want to give a Text Input control focus that is part of an Application File, e.g. a Login Page, you will run into a minor problem. When you call setFocus() you will see that your component will in fact GET focus, however the cursor will not be present. Once you click in the Browser window (and not even inside of the Text Input!), the cursor will become available.
Before you can place the focus on a component within Flash Player, you need to first give focus to the Flash Player Application. This can be done via JavaScript.
The more common approach would be to add a JavaScript function to your html-wrapper and then call that function via ExternalInterface.call() Note, if you are using Flex Builder to generate your html-wrappers, add the function to the index.template.html file.
The function needed is shown below:
function setBrowserFocus(){
document.getElementById('${application}').focus();
}
To invoke this function, use ExternalInterface.call():
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="onLoad(event)">
<mx:Script>
<![CDATA[
import flash.external.ExternalInterface;
private function onLoad(event:Event):void {
ExternalInterface.call('setBrowserFocus');
this.uname.setFocus();
}
]]>
</mx:Script>
<mx:VBox>
<mx:HBox>
<mx:Label text="Username:" />
<mx:TextInput id="uname" />
</mx:HBox>
<mx:HBox>
<mx:Label text="Password:" />
<mx:TextInput id="pwd" displayAsPassword="true" />
</mx:HBox>
</mx:VBox>
</mx:Application>
The other approach is to place the JavaScript function directly inside of the ExternalInterface.call() method (replace \’Login\’ with the name of your .mxml application file):
ExternalInterface.call('function browserFocus(){document.getElementById(\'Login\').focus();}');
Launch the application and the cursor should be blinking inside of the Text Input.
Thanks, this was the exact information I was looking for!
Hey, this is interesting, but only seems to work with internet explorer and firefox. It fails with chrome and safari.
It also fails with Opera. Not sure why though…
thx dude.
mm… really like it ))
work with internet explorer and firefox. It fails with chrome and safari.
any one provide me answer for this?any code change?
@sivaganesh
Yes… this fact has already been established.
You may want to check this out:
http://stackoverflow.com/questions/594821/object-focus-problem-with-safari-and-chrome-browsers
Thanks Dear!
Regards,
Vajahat Ali
Software Innovations,
Lahore Pakistan
mm… thanks ))
Thanks!
I was looking for this!.. work fine!
Weird… worked like a charm on one project, and completely failed on the other. onInit() functions are exactly the same in both projects, as well as html templates. Just …weird.
Yay Flex.
This is just the solution I need, but it’s not working for me in IE7.
I have my Flex IDE open, and when I run my app from there (just a simple login screen), the browser opens, and the focus and blinking cursor are there, but when I type, ALL of the text goes into my Flex Builder screen.
I have been working on this little issue for three days now, and have verified my source is exactly the same as yours.
Does anyone else have this problem?
No idea. If it works fine when launching from the browser, it shouldn’t be an issue for deployment.
On a side note: when you are launching from flex builder, is the URI a file:/// type or are you using a web server?
The literal link that it gets redirected to is:
http://localhost:8500/ProductDesignFeatures-debug/ProductDesignFeatures.html
Again, in my index.template.html file I have:
function setBrowserFocus(){
document.getElementById(‘${application}’).focus();
//alert(‘Set Browser focus successful.’);
}
And within my MXML file, I have:
and onLoad is defined as follows:
private function onLoad(event:Event):void{
ExternalInterface.call(’setBrowserFocus’); usernameText.setFocus();
Makes absolutely no sense. I’ve done EVERYTHING outlined in this tutorial.
If you can provide more help, please advise. I see other applications behaving properly.
Thanks.
Sorry, I failed to include the call to the onLoad function. It is
Thanks.
@scripter
I’m still not seeing the call to the onLoad function within your MXML…
I have no idea why you want to go to JS route.
Here is the simple solution which works perfectly fine on all browser and simple as hell..
I have popup window which ask for certain information and need focus on textinput (not just focus but cursor to type right away without clicking on textfield e.g. google textfield on homepage)
In creationComplete of Application call init() function or one have define.
private function init():void {
focusManager.setFocus();
patientext.addEventListener(MouseEvent.CLICK, myClick);
.dispatchEvent(new MouseEvent(MouseEvent.CLICK, true, false));
}
that’s it and I got focus + cursor on textfield when popup window shows on screen.
Flexible Flex
Ken,
Clearly you did not read the post to which you are supplying a ’simple solution’ for. If you did you would have realized that I am not talking about POP-UP WINDOWS.
In flex, when you use the PopUpManager, the object (TitleWindow or whatever you are using) automatically gets focus WITHIN THE BROWSER when it is displayed – thus using focusManager.setFocus() works like a charm.
This is not the case when you are trying to give focus to a TextInput that is NOT IN A POP-UP WINDOW when the page is first loaded…
Good Day Sir.
As I understand setFocus only moves the focus (not the cursor) to the specified component. If you want to move the cursor you should do it yourself:
this.uname.setFocus();
this.uname.setSelection(0,0);
@Ofir Herzas
You are incorrect.
Please look at the post and above comments to understand the real issue at hand (it appears that people are jumping to conclusions after reading just the title of this post).
The setFocus() method works fine (it will also place the cursor in the text input) when it is used on a pop up … but not when it is used to give focus to a text input that is a child of the Application – e.g. a login page.
Also, the setSelection(0,0) call is identical to the setFocus(). You don’t need both if you are passing 0 and 0 as arguments to setSelection().
setSelection() should be used to set focus AND highlight the entered text. This would be useful to highlight some invalid data so that the user can just start typing again and their previous data will be replaced.
Good Day Sir.
Thanks a lot Sir..It works…I use the last approach…
Thanks a lot. This really helped
I don’t suppose anyone knows how to set focus on the first TextInput in the UIComponent? Dynamic I know :”D It’s a requirement in the project I am on.
I am trying to recursively walk the displaylist to find the first TextInput, so far it’s being a wee biatch. Anyone have any ideas?
nice mannn. this solve my problem.
thx
@ Steve
Have you tried something like this: (where foo is a Box container)?
for each (var o:UIComponent in foo.getChildren()) { if (flash.utils.getQualifiedClassName(o) == "mx.controls::TextInput") { o.setFocus(); break; } }we suppose that your textinput id is: “txt”
All u need to do is to simulate a mouseoverevent like this:
txt.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_OVER,true,false));
That was Ken’s solution, i trayed it and it works fine.
Thanks Ken
thanks …….
It works…..
Yes that will work… in a pop up.
Please check out the link below to see why that will not work in this example…
http://stackoverflow.com/questions/594821/object-focus-problem-with-safari-and-chrome-browsers
thanks ,this is what exactly iam looking for
[...] 8, 2010 at 10:19 am (Uncategorized) check out the blog post . We can set focus on textinput control at a time when application just get launched and it is [...]
Thanks for this writeup. It works!
GRACIAS, muy buena explicacion, muy bien explicado, colocaste justo lo necesario para que funcione y funciona muy bien. no como otras paginas que ponen las cosas a medias o no saben explicar
Has anyone tried stage.focus= thetextinput
I love it. This solution works for me. Thanks a lot
Thanks you very much for the solution ….
Hi Robertus,
You said that it worked for you. I tried all the solutions in the comments. It just doesn’t work. I cannot figure it out why. Can you share some code?
Thanks,
pat.
Men!!! Thanks very much!!!!!! you are mi hero!!!