Monday, October 29, 2007

Webform_AutoFocus() before Sys.Application.Initialize()?

Recently I was developing an ASP.NET Ajax extender control which added behaviors when the target control gained focus. It was a custom implementation of an auto-complete control. Picture your standard auto-complete control but with multiple columns. So if you were to enter customer organizations you could enter by a system id, customer name or city where the customer is located. You could even enter a combination these attributes.

Anyway, if you've worked with the ASP.NET Ajax ScriptControl before you would know that you wire up your events within the initialize method, which you override from the base JavaScript "class". This allows the web browser to complete rendering of the page so all controls are created and properly registered before your code tries to use them.

However, I ran in to a bit of a snag when I tried to use the ScriptManager.Focus() method to set the focus to my target control upon first rendering of the page. I have a user entry screen where users can enter many records in sequence. So basically the users enter data in a few fields, hits submit to add the record and then the focus returns back to the first field, ready for the user to continue entering data.

The idea seemed solid to me, but I found out that the focus behavior wasn't working as I expected. I took a look at the rendered page and noticed that the Webform_AutoFocus() call which is created by the ScriptManager.Focus() runs prior to the Sys.Application.Initialize() call which calls my controls initialize! This means that my focus event handler has not yet been wired up, and there is no way for me to listen to the focus event.

Why is this? I can't think of a reason why the framework would want the focus to occur before initialize. Doesn't the name initialize even seem to imply that it would be the first function to run?

So I thought of a potential workaround. What if I could interrogate the target control to see if it currently has focus when I run the initialize method? It's not the prettiest solution, but it seems like it has potential. Unfortunately this hit a bit of a snag as well. After some research it turned out that IE has a property on the document known as activeElement which will provide the control which currently has focus. The problem? Only IE has such a property to tell me what control has focus, and I hate doing something which only works in a single browser.

Unfortunately I wasn't able to find any other workarounds, and as such only IE will appear to handle the system derived auto focus correctly. I suppose there are worse things to worry about. The control still works without listening to the focus event, it just works a little differently than I would like.

Microsoft, why couldn't you have just put the auto focus after initialize?

--John Chapman

2 comments:

Anonymous said...

Hi JOHN,

I don't think so i understood one hundred percent what you are talking about. But to the knowledge i have, if you want a particular control to have focus by default after the page load completes in asp.net, you can use the property called DefaultFocus of form tag in your page. Set the DefaultFocus = Your Control ID and ASP.NET will take care about setting the focus.

jmlmartin said...

Hi John,

Not sure if you're still interested in this one, but the following link may be of interest - it solved this problem for me:

http://forums.asp.net/t/1324475.aspx

Blogger Syntax Highliter