Flex: TextInput Focus issues…

Posted by admin at 20 January 2009

Category: programming

Tags: , , ,

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.

40 Comments

  1. Demian says

    Thanks, this was the exact information I was looking for! :-)

  2. james says

    Hey, this is interesting, but only seems to work with internet explorer and firefox. It fails with chrome and safari.

  3. admin says

    It also fails with Opera. Not sure why though…

  4. fayez says

    thx dude.

  5. BoicynC says

    mm… really like it ))

  6. sivaganesh says

    work with internet explorer and firefox. It fails with chrome and safari.

  7. sivaganesh says

    any one provide me answer for this?any code change?

  8. admin says

    @sivaganesh
    Yes… this fact has already been established.

  9. admin says

    sivaganesh :

    any one provide me answer for this?any code change?

    You may want to check this out:

    http://stackoverflow.com/questions/594821/object-focus-problem-with-safari-and-chrome-browsers

  10. Vajahat says

    Thanks Dear!
    Regards,
    Vajahat Ali
    Software Innovations,
    Lahore Pakistan

  11. SarSkenny says

    mm… thanks ))

  12. fabiohiga says

    Thanks!
    I was looking for this!.. work fine!

  13. Constantine says

    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.

  14. admin says

    Yay Flex.

  15. scripter says

    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?

  16. admin says

    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?

  17. scripter says

    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.

  18. scripter says

    Sorry, I failed to include the call to the onLoad function. It is

    Thanks.

  19. admin says

    @scripter
    I’m still not seeing the call to the onLoad function within your MXML…

  20. Ken says

    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

  21. admin says

    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.

  22. Ofir Herzas says

    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);

  23. admin says

    @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.

  24. handoyo says

    Thanks a lot Sir..It works…I use the last approach…

  25. Jasmine says

    Thanks a lot. This really helped

  26. Steve says

    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?

  27. norman says

    nice mannn. this solve my problem.
    thx

  28. admin says

    @ 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;
         }
    }
    
  29. Barabas says

    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

  30. Rahul says

    thanks …….

    It works…..

  31. admin says

    Barabas :

    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

    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

  32. suresh says

    thanks ,this is what exactly iam looking for

  33. [...] 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 [...]

  34. Daniel says

    Thanks for this writeup. It works!

  35. yussef says

    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

  36. Ignatius Ahamiojie says

    Has anyone tried stage.focus= thetextinput

  37. Robertus Lilik says

    I love it. This solution works for me. Thanks a lot

  38. Manohar says

    Thanks you very much for the solution ….

  39. Patricial says

    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.

  40. The Hard says

    Men!!! Thanks very much!!!!!! you are mi hero!!!

Leave a Reply

Leave a Reply
  • (required)
  • (required) (will not be published)