How to use JavaScript to highlight the active textbox by handling the onfocus and onblur client-side events, and dynamically changing the control appearance attributes or CSS style class.
When your data entry Web forms contain several textboxes, highlighting the textbox that has the input focus can significantly improve the user's experience. This technique is especially effective if your layout doesnbt make immediately clear what the tab order sequence is. For example, if you have multiple columns of textboxes, are they ordered horizontally or vertically? With a few lines of client-side JavaScript code you can easily change the background and foreground color of the active textbox, and thus give immediate feedback about the field that receives the user input. DHTML makes it possible to change the HTML elementsb style (font, colors, position) by means of the controlbs style property and its sub-properties. The following HTML code renders a textbox control that handles the onfocus client-side event to change its background and foreground colors, and the onblur event to restore the original colors when the control loses the focus:
When your data entry Web forms contain several textboxes, highlighting the textbox that has the input focus can significantly improve the user's experience. This technique is especially effective if your layout doesnbt make immediately clear what the tab order sequence is. For example, if you have multiple columns of textboxes, are they ordered horizontally or vertically? With a few lines of client-side JavaScript code you can easily change the background and foreground color of the active textbox, and thus give immediate feedback about the field that receives the user input. DHTML makes it possible to change the HTML elementsb style (font, colors, position) by means of the controlbs style property and its sub-properties. The following HTML code renders a textbox control that handles the onfocus client-side event to change its background and foreground colors, and the onblur event to restore the original colors when the control loses the focus:
id="txtFirstName"
onfocus= "this.style.backgroundColor='Yellow'; this.style.color = 'Blue';"
onblur="this.style.backgroundColor='Window'; this.style.color='WindowText';"
/>
Letbs see how you can dynamically add highlighting support to all ASP.NET server-side controls, instead of hard-coding it manually. All controls that inherit from WebControl have an Attributes collection to which you can add one or more attributename=value pairs; at render-time these pairs are embedded in the standard HTML code that the control generates. The listing below shows the VB.NET and C# methods that dynamically build a piece of JavaScript code that changes the backcolor/forecolor to the specified colors:
Sub SetInputControlColors(ByVal ctl As _
WebControl, ByVal backColor As Color, _
ByVal foreColor As Color, _
ByVal focusBackColor As Color, _
ByVal focusForeColor As Color)
Dim jsOnFocus As String = String.Format( _
"this.style.backgroundColor = '{0}';" _
& "this.style.color = '{1}';", _
focusBackColor.Name, focusForeColor.Name)
Dim jsOnBlur As String = String.Format( _
"this.style.backgroundColor = '{0}';" _
& "this.style.color = '{1}';", _
backColor.Name, foreColor.Name)
ctl.Attributes.Add("onfocus", jsOnFocus)
ctl.Attributes.Add("onblur", jsOnBlur)
End Sub
void SetInputControlColors(WebControl ctl,
Color backColor, Color foreColor,
Color focusBackColor, Color focusForeColor)
{
string jsOnFocus = string.Format(
"this.style.backgroundColor = '{0}';" +
"this.style.color = '{1}';",
focusBackColor.Name, focusForeColor.Name);
string jsOnBlur = string.Format(
"this.style.backgroundColor = '{0}';" +
"this.style.color = '{1}';",
backColor.Name, foreColor.Name);
ctl.Attributes.Add("onfocus", jsOnFocus);
ctl.Attributes.Add("onblur", jsOnBlur);
}
Using the SetInputControlColors method is trivial:
SetInputControlColors(txtFirstName, _
SystemColors.Window, _
SystemColors.WindowText, _
Color.Yellow, Color.Blue)
SetInputControlColors(txtFirstName,
SystemColors.Window,
SystemColors.WindowText,
Color.Yellow, Color.Blue);
Instead of manually calling SetInputControlColors for all the input controls on the form, you can use the SetAllInputControlsColors method shown below to change the onfocus/onblur styles for all the TextBox, ListBox and DropDownList controls in the form.
Sub SetAllInputControlsColors(ByVal parent As _
Control, ByVal backColor As Color, _
ByVal foreColor As Color, _
ByVal focusBackColor As Color, _
ByVal focusForeColor As Color)
For Each ctl As Control In parent.Controls
If TypeOf ctl Is TextBox OrElse _
TypeOf ctl Is ListBox OrElse _
TypeOf ctl Is DropDownList Then
SetInputControlColors(DirectCast( _
ctl, WebControl), _
backColor, foreColor, _
focusBackColor, _
focusForeColor)
Else
SetAllInputControlsColors(ctl, _
backColor, foreColor, _
focusBackColor, _
focusForeColor)
End If
Next
End Sub
void SetAllInputControlsColors(Control parent,
Color backColor, Color foreColor,
Color focusBackColor, Color focusForeColor)
{
foreach (Control ctl in parent.Controls)
{
if (ctl is TextBox || ctl is ListBox ||
ctl is DropDownList)
{
SetInputControlColors(
ctl as WebControl, backColor,
foreColor, focusBackColor,
focusForeColor);
}
else
{
SetAllInputControlsColors(ctl,
backColor, foreColor,
focusBackColor,
focusForeColor);
}
}
}
This method is recursive and affects also the controls nested in control containers. All you need to do now is putting the following code in the handler of the Page.Load event:
SetAllIputControlsColors(Me, _
SystemColors.Window, SystemColors.WindowText, _
Color.Yellow, Color.Blue)
SetAllIputControlsColors(this,
SystemColors.Window, SystemColors.WindowText,
Color.Yellow, Color.Blue);
The figure below shows the result in Internet Explorer.
Using client-side JavaScript isn't the only technique you can adopt to change the style of the active control. In fact, the approach just described works well only if the form contains a small number of fields. When the form has many controls, the amount of JavaScript generated for each control bloats the page's size and indirectly slows down its rendering. In such cases it is recommended that you define the normal and focus style by means of a Cascading Style Sheet (CSS) class in a separate stylesheet file, and write a shorter JavaScript code that just sets the control's className property when the control gets or loses the focus. Say that you define the following class in a .css file:
.ActiveInputControl
{
background-color: Red;
color: Yellow;
font-weight: bold;
}
You can call the SetAllInputControlsClassName method (defined at the end of the article) as shown here:
SetAllInputControlsClassName(Me, "", _
"ActiveInputControl")
SetAllInputControlsClassName(this, "",
"ActiveInputControl");
And the resulting HTML for a single control would be as follows:
onfocus="this.className = 'ActiveTextBox';"
onblur="this.className = '';"
/>
(Notice that when the control does not have the focus it just has no specific style class, and therefore it has the default style.) Not only is this technique faster when a form contains many fields, it is also more easily maintainable, because you can later change the focus style by simply providing a different CSS, without recompiling the ASP.NET application.
Sub SetInputControlClassName(ByVal ctl As _
WebControl, ByVal className As String, _
ByVal focusClassName As String)
Dim jsOnFocus As String = String.Format( _
"this.className = '{0}';", focusClassName)
Dim jsOnBlur As String = String.Format( _
"this.className = '{0}';", className)
ctl.Attributes.Add("onfocus", jsOnFocus)
ctl.Attributes.Add("onblur", jsOnBlur)
End Sub
Sub SetAllInputControlsClassName(ByVal parent _
As Control, ByVal className As String, _
ByVal focusClassName As String)
For Each ctl As Control In parent.Controls
If TypeOf ctl Is TextBox OrElse _
TypeOf ctl Is ListBox OrElse TypeOf
ctl Is DropDownList Then
SetInputControlClassName( _
DirectCast(ctl, WebControl),_
className, focusClassName)
Else
SetAllInputControlsClassName(ctl, _
className, focusClassName)
End If
Next
End Sub
void SetInputControlClassName(WebControl ctl,
string className, string focusClassName)
{
string jsOnFocus = String.Format(
"this.className = '{0}';", focusClassName);
string jsOnBlur = String.Format(
"this.className = '{0}';", className);
ctl.Attributes.Add("onfocus", jsOnFocus);
ctl.Attributes.Add("onblur", jsOnBlur);
}
void SetAllInputControlsClassName(Control parent,
string className, string focusClassName)
{
foreach (Control ctl in parent.Controls)
{
if (ctl is TextBox || ctl is ListBox ||
ctl is DropDownList)
{
SetInputControlClassName(
ctl as WebControl,
className, focusClassName);
}
else
{
SetAllInputControlsClassName(ctl,
className, focusClassName);
}
}
}

