Pages

Advertisement

Friday, July 13, 2007

Using Client-side Script to Focus Controls in ASP.NET

Many users want Web applications to be as responsive as Windows applications. With Windows, you get some really nice default behaviors and with the Web you get some really nice deployment features. Generally, the ease of deployment—update a Web page and every user gets the update—doesn't come cheaply with Windows applications, and default, user-friendly features such as "focusing" control behavior—call SetFocus in Windows—doesn't come cheaply with Web applications. Usability is a nice benefit of developing for Windows Forms; deployment is a nice feature of Web Forms.

In this article, I will demonstrate how you can use injected JavaScript to set the focus control in ASP.NET. You will learn how to write a bit of JavaScript and use VB.NET to determine which control should have the focus and how to inject dynamic JavaScript to affect this client-side behavior.

Writing the JavaScript to Focus a Control

 

A user performs a task that causes your Web application to post back to the server. When the Web Form is recreated on the server, the user has to manually reposition the focus to their last point of interest. On a simple page with a few controls, this is easy enough; however, if you are building a complex Web application, repositioning the focus may become a nuisance issue.

Recently, I was responsible for building some very complex Web Forms that had collapsible regions and various edit points of interest. Manually re-expanding and positioning focus made the application seem clumsy. To resolve the problem, we elected to dynamically figure out which region and control had the user's interest and re-focus that control. Refocusing the same control requires about two lines of JavaScript (see Listing 1); dynamically re-focusing a specific control required that dynamic JavaScript be emitted to the rendered client page. Here is some pseudo-code to focus the same control. In the next section, I will show you how to convert the static JavaScript into a dynamic script block.

Listing 1: Pseudo-code to focus the same control on the client.

<script language="javascript">
var control = document.getElementById(<control name>);
if( control != null ){ control.focus(); }
</script>

In Listing 1, we obtain the control by passing the control's name to the document.getElementById. If a valid control object is returned, we call the control's focus method, as demonstrated in the listing. Working forward, we need to figure out the control and dynamically inject a similar block of JavaScript to the rendered client page in such a manner that the script block will be run when the page is loaded in the browser.

Registering the Startup Script

ASP.NET pages contain a method named RegisterStartupScript. By invoking Page.RegisterStartupScript, we can inject a block of script that will run just before the page is rendered in the browser. The arguments we need to pass to RegisterStartupScript are a unique name for the script block and a properly formatted block of script.

To solve this problem I defined a utility routine named SetFocusControl that accepts the string name of the control to focus. SetFocusControl inserts the control to focus in the formatted script string and Page.RegisterStartupScript inserts the formatted script into the page. Listing 2 contains the implementation of SetFocusControl and Listing 3 shows the HTML of a very simple Web page illustrating the placement of the injected code block. All that remains for you to do is to call SetFocusControl in your Web Page's code-behind prior to posting the page back. Suitable places for calling SetFocusControl include postback points, such as button clicks.

Listing 2: The implementation of SetFocusControl.

Public Sub SetFocusControl(ByVal ControlName As String)
' character 34 = "

Dim script As String = _
"<script language=" + Chr(34) + "javascript" + Chr(34) _
+ ">" + _
" var control = document.getElementById(" + Chr(34) + _
ControlName + Chr(34) + ");" + _
" if( control != null ){control.focus();}" + _
"</script>"

Page.RegisterStartupScript("Focus", script)
End Sub

Listing 2 uses the Chr(34) function to insert the double-quote into the preformatted script block to embed double-quotes into the script block. Calling SetFocusControl(control.ClientID)—for example, SetFocusControl(TextBox2.ClientID)—results in the script block shown in Listing 3 to be added to the rendered HTML.

Listing 3: The dynamically rendered startup script block.

<script language="javascript">
var control = document.getElementById("TextBox2");
if( control != null ){control.focus();}
</script>

Listing 3 shows the dynamically rendered script. As the page is read by the browser, the preceding block of script will run and the control passed to getElementById will have the focus.

Summary

Customers usually want specific usability features and seldom care about the details. Often, things that seem easy to do are harder than a customer would expect. By sharing techniques, we can provide features without a lot of re-innovation.

In this article, I demonstrated how to set a control's focus dynamically by using a preformatted script block and the Page.RegisterStartupScript method. Client-side JavaScript will often yield some of the snappy usability customers have come to expect; one simply needs to know what services are available for creating this script.

As an aside, one would expect setting the focus to exist in ASP.NET controls, but if you check the help documentation for Web controls, you will find this capability does not exist. Perhaps we will get it in future versions of ASP.NET.

No comments:

Post a Comment