When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
ASPFAQs.com
Message Board
Related Web Technologies
User Tips!
Coding Tips
Search

Sections:
Book Reviews
Sample Chapters
Commonly Asked Message Board Questions
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Security
Stump the SQL Guru!
Web Hosts
XML
Information:
Advertise
Feedback
Author an Article
Jobs

ASP ASP.NET ASP FAQs Message Board Feedback ASP Jobs
 
Print this Page!
Published: Wednesday, February 16, 2011

Focusing and Selecting the Text in ASP.NET TextBox Controls

By Scott Mitchell


Introduction


When a browser displays the HTML sent from a web server it parses the received markup into a Document Object Model, or DOM, which models the markup as a hierarchical structure. Each element in the markup - the <form> element, <div> elements, <p> elements, <input> elements, and so on - are represented as a node in the DOM and can be programmatically accessed from client-side script. What's more, the nodes that make up the DOM have functions that can be called to perform certain behaviors; what functions are available depend on what type of element the node represents.

One function common to most all node types is focus, which gives keyboard focus to the corresponding element. The focus function is commonly used in data entry forms, search pages, and login screens to put the user's keyboard cursor in a particular textbox when the web page loads so that the user can start typing in his search query or username without having to first click the textbox with his mouse. Another useful function is select, which is available for <input> and <textarea> elements and selects the contents of the textbox.

This article shows how to call an HTML element's focus and select functions. We'll look at calling these functions directly from client-side script as well as how to call these functions from server-side code. Read on to learn more!

- continued -

Accessing an HTML Element in the DOM


Before we look at how to call the focus and select functions, we first need to discuss how to access an HTML element in the Document Object Model (DOM). Perhaps the most straightforward way is to use JavaScript's document.getElementById function. To use document.getElementById you pass in the id attribute of the element of interest. The DOM is then examined for a matching element. If such an element is found, it is returned; otherwise, null is returned.

The following JavaScript snippet shows how to reference the txtName textbox and call its focus function. After the JavaScript code executes, the browser will set keyboard focus to the textbox, meaning that the cursor will be in the textbox ready to accept the user's keyboard input, just as if the user had clicked the textbox with his mouse.

<p>
   What is your name?
   <input type="text" id="txtName" name="txtName" />
</p>

<script type="text/javascript">
   // Reference the textbox
   var txt = document.getElementById("txtName");

   // If the textbox was found, call its focus function
   if (txt != null)
      txt.focus();
</script>

One challenge in referencing ASP.NET Web controls from client-side script is that the id attribute generated when the Web control is rendered does not necessarily equate to the Web control's ID property. For example, consider an ASP.NET page that had a TextBox Web control whose ID property was set to txtName:

<p>
   What is your name?
   <asp:TextBox runat="server" ID="txtName" />
</p>

Depending on the ASP.NET page - whether you're using a master page, where the TextBox exists in the ASP.NET control hierarchy, and so on - when the TextBox control is rendered into an <input type="text" /> element the id attribute may be a bit different than the server-side ID property (txtName). The TextBox control might generate HTML like the following:

<p>
   What is your name?
   <input name="ctl00$ContentPlaceHolder1$txtName" type="text" id="ContentPlaceHolder1_txtName" />
</p>

As a result, you need to take care when referencing HTML elements generated from ASP.NET Web controls in client-script.

To get the correct id value there are two options:

  • Set the Web control's ClientIDMode property to Static. This ensures that the server-side ID property value is used in its original form as the client-side id value for the rendered HTML element. See Take Control Of Web Control ClientID Values in ASP.NET 4 for details.
  • Use the Web control's ClientID property to determine the generated client-side id attribute value.
If you use the latter approach, your JavaScript will look like the following:

<p>
   What is your name?
   <asp:TextBox runat="server" ID="txtName" />
</p>

<script type="text/javascript">
   // Reference the textbox
   var txt = document.getElementById("<%=txtName.ClientID%>");

   // If the textbox was found, call its focus function
   if (txt != null)
      txt.focus();
</script>

Note how in the above snippet the document.getElementById function is passed the value <%=txtName.ClientID%>. The <%= ... %> delimiters indicate that the inner content is server-side code. So when the page is visited the<%=txtName.ClientID%> gets executed and returns ContentPlaceHolder1_txtName, which means the browser is actually sent JavaScript code like var txt = document.getElementById("ContentPlaceHolder1_txtName");

Another option for accessing an HTML element out of the DOM is to use jQuery. jQuery is a popular, free, open source JavaScript library that simplifies working with and manipulating the HTML DOM. To reference elements in the DOM using jQuery you use selectors, which are strings that indicate what element(s) to retrieve from the DOM. To get an element by its id attribute, you use the selector #id.

The following snippet shows the JavaScript code to reference a textbox with the id txtName and call its focus function:

<script type="text/javascript">
   // Reference the textbox and call its focus function
   var txt = $("#txtName");

   txt.focus();
</script>

Note that we do not need to bother checking if txt is null. txt is actually a collection of matched elements, as some selectors can be used to retrieve multiple DOM elements. The focus function being called above is not the element's focus function, but jQuery's focus function, which enumerates the collection and calls each of its elements' focus functions. If the textbox txtName was found then its focus function will be invoked.

Setting Keyboard Focus on a Web Control


As we saw in the Accessing an HTML Element in the DOM section, the a DOM element's focus function is invoked by first accessing the HTML element of interest and then calling its focus function. To set focus to a Web control you can write your own client-side JavaScript to accomplish this or you can use a server-side option. The ASP.NET Control class has a Focus method. Calling this method prompts ASP.NET to inject some JavaScript into the page that tells the browser to reference the control's corresponding HTML element and call its focus function.

For example, presuming we have a TextBox on the page with a server-side ID of txtName, we can have focus set to it on page load by adding the following code to the code-behind class's Page_Load event handler:

protected void Page_Load(object sender, EventArgs e)
{
   if (!Page.IsPostBack)
      txtName.Focus();
}

When the above method is called, two bits of JavaScript are included in the page's rendered output:

  • A reference to a JavaScript that includes a function named WebForm_AutoFocus is included, and
  • A block of JavaScript is added to the end of the WebForm with a line of script like so: WebForm_AutoFocus(idOfControlToFocus).
In a nutshell, the Control class's Focus method means you can set focus to a Web control without having to write your own JavaScript. And the Focus method is pretty smart. For example, calling a TextBox control's Focus method sets keyboard focus to that TextBox; calling a Login control's Focus method sets the focus to the username textbox.

The Focus method is useful in those scenarios where you want to set the focus to a Web control on page load or after a postback. Most commonly, this method is used to set the initial focus of a Web control (such as to the username textbox in a Login control). If you need to set the focus to a particular HTML element after some user action - say, after a user selects an item from a drop-down you want to immediately set the focus to a corresponding textbox - then you should use client-side script to set the focus so as to not require a postback.

Selecting the Text in a TextBox Web Control


Unfortunately, ASP.NET does not provide a Select method for its TextBox control, so I decided to write my own extension method. (An extension method is a special method written in a particular way that adds functionality to an existing class. By adding the SelectText extension method to your project you can write code like: MyTextBoxID.SelectText() in your code-behind class, which will emit the appropriate JavaScript to call the client-side select function on the rendered textbox.)

The extension method below, which I've named SelectText, injects the appropriate JavaScript into the page to reference and invoke the select function for the rendered textbox. Things are a little tricky when the TextBox in question is inside of an UpdatePanel and the SelectText method is called after a partial-page postback - we'll talk about this wrinkle in more detail in a bit.

The demo available for download includes VB and C# class files in the App_Code folder named TextBoxExtensions that implement this functionality. The code below is the C# version; download the demo to see the VB version.

public static class TextBoxExtensions
{
   public static void SelectText(this TextBox txt)
   {
      // Is there a ScriptManager on the page?
      if (ScriptManager.GetCurrent(txt.Page) != null && ScriptManager.GetCurrent(txt.Page).IsInAsyncPostBack)
         // Set ctrlToSelect
         ScriptManager.RegisterStartupScript(txt.Page,
                                    txt.Page.GetType(),
                                    "SetFocusInUpdatePanel-" + txt.ClientID,
                                    String.Format("ctrlToSelect='{0}';", txt.ClientID),
                                    true);
      else
         txt.Page.ClientScript.RegisterStartupScript(txt.Page.GetType(),
                                          "Select-" + txt.ClientID,
                                          String.Format("document.getElementById('{0}').select();", txt.ClientID),
                                          true);
   }
}

For now, pay attention to the code in the else statement, which is executed if there is not a ScriptManager on the page. Here we inject JavaScript into the page's rendered output using the ClientScript object's RegisterStartupScript method. This adds the following JavaScript to the page, where TextBox-ClientID is the client-side id attribute value of the TextBox Web control. In a nutshell, this references the textbox HTML element and calls its select function.

document.getElementById('TextBox-ClientID').select();

Imagine you had a Web page with a TextBox control named txtName that was initially loaded with the text, "Enter your name...". You could have this textbox's text selected on page load by adding the following code to your Page_Load event handler:

protected void Page_Load(object sender, EventArgs e)
{
   if (!Page.IsPostBack)
      txtName.SelectText();
}

The demo available for download at the end of this article includes a page similar to the one described. Here's a screen shot of the page when it is first loaded. Note how the text of the txtName TextBox is selected. The user can start typing their name immediately, which will erase the existing text.

The contents of the textbox are selected on page load.

Of course, you can also select the text in a textbox by calling its select function directly through client-side code. For instance, my blog entry Select a textbox's text on focus using jQuery shows how to write a bit of JavaScript so that a textbox's text is automatically selected whenever the textbox receives focus.

Getting the SelectText Method to Work in an UpdatePanel


The UpdatePanel is a control that's part of the ASP.NET Ajax Library and is designed to simplify implementing Ajax scenarios. The UpdatePanel defines a region on the page that causes a partial-page postback as opposed to a traditional full-page postback. A partial-page postback is one where the browser makes its request back to the server via an asynchronous HTTP call, initiated by JavaScript. For more information about the ASP.NET Ajax Library and the UpdatePanel, see Building Interactive User Interfaces with Microsoft ASP.NET AJAX: Using the UpdatePanel.

The code we paid attention to in the SelectText method used the ClientScript object's RegisterStartupScript method to inject JavaScript into the page to call the select function for the specified TextBox control. This works fine for pages that do not use the UpdatePanel control, but for those pages that do use an UpdatePanel control, the script emitted by the ClientScript object's RegisterStartupScript method is only added to the page on the first page load (or after a full-page postback). That is, the script added via the ClientScript object's RegisterStartupScript method is not added to the page if a partial-page postback just occurred.

To get JavaScript into the page after a partial-page postback we need to use the ScriptManager class's RegisterStartupScript method. The conditional statement in the SelectText extension method uses ScriptManager (instead of ClientScript) if there exists a ScriptManager object on the page and we are currently in the midst of a partial-page postback.

Initially, I presumed I could emit the same script on a partial-page postback as on a full-page postback to select the textbox, namely document.getElementById('TextBox-ClientID').select(). While this works in Firefox, it does not work in Internet Explorer. What happens is that the script gets emitted and executed, selecting the specified textbox's text, but between that point and when the browser completes the partial-page postback the focus gets lost and the text becomes unselected.

I spent some time investigating how the Focus method works underneath the covers (as it correctly sets the focus on a partial-page postback), and discovered that the ASP.NET Ajax Library has a special case for the Focus method in its client-side library scripts. Namely, it sets a flag if the Focus method is called and then waits until the client-side endRequest event fires and, at that point, sets the focus to the control, if needed. (The client-side endRequest event is raised by the browser at the very end of a partial-page postback.)

The solution for SelectText, then, was to have the extension method set a flag (namely, set the client-side variable ctrlToSelect to the id value of the textbox) and then add script to the page (or master page) that subscribes to the client-side endRequest event and calls the select function of the specified textbox.

So, when the SelectText extension method is invoked for a page that has a ScriptManager control on it and is in the midst of a partial-page postback, the following script is emitted:

ctrlToSelect = 'TextBox-ClientID';

Next, add the following script block to the <head> section of the page (or master page):

<script type="text/javascript">
   var ctrlToSelect = null;

   function pageLoad() {
      Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function (sender, e) {
         if (ctrlToSelect != null && $get(ctrlToSelect) != null)
            $get(ctrlToSelect).select();
      });
   }
</script>

The above script creates a client-side event handler for the endRequest event. It checks to see if the ctrlToSelect variable has been set and, if so, if there is a corresponding HTML element on the page with a matching id value. If so, it's select function is called.

To recap, in order to get the SelectText extension method to work for TextBox controls in an UpdatePanel during a partial-page postback, you need to add the above <script> block to the page. The SelectText extension method will emit the appropriate JavaScript to get things to work as expected.

Conclusion


HTML elements in the DOM can receive keyboard focus or have their text selected by calling the focus and select functions. These functions can be executed via JavaScript by first referencing the HTML element of interest and then calling the function of interest. To facilitate setting keyboard focus to an element, ASP.NET Web controls all have a Focus method that, when called from the code-behind class, injects JavaScript into the page that references the Web control's corresponding HTML element and calls its focus function.

While ASP.NET offers a server-side Focus method, there is no corresponding Select method. We can, however, write our own method to add such functionality. The demo available for download at the end of this article provides such an implementation (as an extension method on the TextBox class). In testing the SelectText extension method I found one issue - namely, it didn't work in Internet Explorer for TextBoxes in an UpdatePanel on a partial-page postback. To remedy this you need to make sure you add the <script> block presented in the Getting the SelectText Method to Work in an UpdatePanel section, which creates a client-side event handler for the endRequest event and selects the textbox of interest.

Happy Programming!

  • By Scott Mitchell


    Attachments:

  • Download the Demo Code Used in this Article

    Further Reading

  • Take Control Of Web Control ClientID Values in ASP.NET 4
  • Select a textbox’s text on focus using jQuery
  • Extending Base Type Functionality with Extension Methods
  • Building Interactive User Interfaces with Microsoft ASP.NET AJAX: Using the UpdatePanel


  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article