Friendly Form Field Highlighting

by Martin Millar

Last updated : 11th September 2006

Background

You have a form based input screen that users must navigate. The problem is that there are a number fields on display and the user is getting lost when they move there eyes away from the screen. Especially true if users are not good typists.

Strategy

We will change the background colour of the currently selected form field. This will stand out from the other fields and make it easy for our user to find it on the screen.

We will handle the focus and blur events using client side JavaScript to dynamically change the CSS class of the control and thus change the background colour.

Implementation

First, let's see how the final result should look. Notice how the currently selected field is differently coloured to the rest of the form fields.

Form showing highlighted field

Step 1 - Add the CSS

We will start of by adding two simple CSS classes. One that can be applied to the form field when the user enters it and another to reset it back to its default display when the user exits the field.

.normalfld 
{
    background-color: #FFFFFF;
}
.focusfld 
{
    background-color: #FFFFCC;
}

Step 2 - Add the JavaScript

We need to use client side code to change the CSS class assigned to the form field. There are a number of ways to add this in ASP.NET projects. One practice, which I'm not a great fan of, is to use the ClientScriptManager classes. For this example I will create a simple JavaScript file and attach it to the page using standard HTML <script> notation.

function DoBlur(fld) {
    fld.className='normalfld';
}

function DoFocus(fld) {
    fld.className = 'focusfld';
}

Step 3 - Plumbing the JavaScript

We will add the plumbing to the ASP.NET form controls in the Page_Load event of the page. We loop through all the controls on the form and add the necessary events to our target fields. In this case we are searching for only textboxes.

   Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not Page.IsPostBack Then
            SetHighlightFields(Page.Form)
            Me.txtForename.Focus()
        End If
    End Sub

    Sub SetHighlightFields(ByVal frm As Control)
        Dim TempCheckbox As CheckBox = Nothing
        Dim TempTextBox As TextBox = Nothing
        For Each tmpctl As Control In frm.Controls
            If TypeOf tmpctl Is TextBox Then
                TempTextBox = CType(tmpctl, TextBox)
                TempTextBox.Attributes.Add("onFocus", "DoFocus(this);")
                TempTextBox.Attributes.Add("onBlur", "DoBlur(this);")
            End If
        Next
    End Sub

    Sub ClearFields(ByVal frm As Control)
        For Each tmpctl As Control In frm.Controls
            If TypeOf tmpctl Is TextBox Then
                CType(tmpctl, TextBox).Text = ""
            End If
        Next
    End Sub

That's all there is to it. Now when the user tabs or clicks through in your form each field will be highlighted when it receives the focus.

Summary

This has hopefully given you a few ideas of your own on how to provide some 'value add' features to your web applications. As you can see from the code, or lack of it, it's easy to implement this functionality. When developing, try to imagine your application from the users perspective who is going to be using it 8 hours a day!

About the author

Martin Millar is an solutions architect for a large consultancy firm based in Melbourne, Australia. Previously he worked as a senior applications developer for a large Telecoms firm in the UK. He specialises in web development using ASP.NET and SQL Server and is a Microsoft Certified Solutions Developer(MCSD). In his spare time he runs a fledgling web design company called bracora at http://www.bracora.com.

 

Comments

Name : Vikram
Comment : Good Trick
Name : Michael
Comment : Hello, Can you supply C# code to download? Thanks
Name : Henrik
Comment : I think this is a really bad solution for this kind of functionally. For all modern browsers (thats not IE) only css is needed: .normalfld { background-color: #FFFFFF;} .normalfld:focus {background-color: #FFFFCC;} ...and for IE you should do this with a javascript method (using getElementsByTagName and attaching methods to the blur and focus events). Much cleaner and probably much faster....

Martin : See later comment for a better CSS2 solution. Remember though 80% of users browse with IE ;-)

Name : Cesar De La Hoz
Comment : I´m just learning how to integrate de correct use of CSS with ASP.NET 2.0, this is a good example that improve the UX, I´ll use it rigth now in the User Registration form of an App i´m working on. Thanks, it´s very usefull. I register to your RSS feed so keep writing.
Name : VISWES
Comment : VERY GOOD
Name : aspnetx
Comment : Hello,Martin Millar I hava translated this article into Chinese to share more developers in China,and that url is http://www.cnblogs.com/aspnetx/archive/2006/10/01/519873.html.
I promise,this is a non-business translate,I just feel this artile is pretty good and wanna share more people who don't be good at English,and I want to say Thank you for your article. Thank you,aspnetx from China
Name : Annoymous
Comment :

I'd like to add that with all CSS 2 compliant browsers, you can acomplish the same effect simply using ":focus" pseudo-class and without any javascript line of code:
input:focus
{
background-color: #FFFFCC;
}

http://www.w3.org/TR/REC-CSS2/selector.html#dynamic-pseudo-classes

Martin : This is a good CSS2 solution that I wasn't aware of.
Worked great with Firefox but not IE6. Thanks

Name : Gabriel Rodriguez
Comment : I think this was taken (stolen?) from Marco Bellinaso's book on ASP.NET 2.0....the exact same tip is given on the first or second chapter...using exactly the same color...anyways.

Martin : Hi Gabriel
I have been using this onblur/onfocus technique in IE since at least 2000 with plain old HTML. This just shows how you can attach the onblur/focus events at runtime with asp.net. You can still use the same technique with plain old HTML controls.
I have not seen Marco's book and he may have used this technique, probably along with thousands of other experienced developers.

Name : K Ivanov
Comment : Very good JavaScript solution here: http://www.dynamicdrive.com/dynamicindex11/highlightform.htm
You can select what HTML elements to highlight.
Name : Chad Green
Comment : Good tip, but will not work correctly if used along with Master Pages. You can get the same results by adding the following code to your Master Page's Page_Load event:
                        
 For Each ctrlMaster As Control In Page.Form.Controls
  If TypeOf ctrlMaster Is ContentPlaceHolder Then
    For Each ctrlContent As Control In ctrlMaster.Controls
      If TypeOf ctrlContent Is TextBox Then
        Dim objTBox As TextBox = CType(ctrlContent, TextBox)
        objTBox.Attributes.Add("onFocus", "DoFocus(this);")
        objTBox.Attributes.Add("onBlur", "DoBlur(this);")
      End If
    Next ctrlContent
  End If
Next ctrlMaster
                        
Name : Anonymous
Comment : Wow. I guess I'd better be careful when I post a tip and use the same color someone else has used. Good to know that yellow is already copyrighted.
Name : Darren Kopp
Comment : here is the c# card. i hand typed it so there may be a couple of errors. enjoy.
   Protected void Page_Load(object sender, EventArgs e)
   {
        If (!Page.IsPostBack)
        {
            SetHighlightFields(Page.Form);
            this.txtForename.Focus();
        }
   }

    void SetHighlightFields(Control frm)
    {
        CheckBox TempCheckbox = null;
        TextBox TempTextBox = null;
        foreach(Control tmpctl in frm.Controls)
        {
            if (tmpctl.GetType() == typeof(TextBox)) 
            {
                TempTextBox = (TextBox)tmpctl;
                TempTextBox.Attributes.Add("onFocus", "DoFocus(this);");
                TempTextBox.Attributes.Add("onBlur", "DoBlur(this);");
            }
        }
    }

    void ClearFields(Control frm)
    {
        foreach(Control tmpctl in frm.Controls)
        {
            if (tmpctl.GetType == typeof(TextBox)
            {
                ((TextBox)tmpctl).Text = ""
            }
        }
    }
Name : Vish C
Comment : superb trick, implemented it in our intranet, here is it is converted to c#:
        private void SetHighlightFields(Control frm)
        {
            CheckBox    TempCheckbox    = null;
            TextBox     TempTextBox     = null;
            DropDownList TempDDL        = null;

            foreach (Control tmpctl in frm.Controls)
            {
                if (typeof(TextBox) == tmpctl.GetType())
                {
                    TempTextBox = (TextBox)tmpctl;
                    TempTextBox.Attributes.Add("onFocus", "DoFocus(this);");
                    TempTextBox.Attributes.Add("onBlur", "DoBlur(this);");
                }

                if (typeof(DropDownList) == tmpctl.GetType())
                {
                    TempDDL = (DropDownList)tmpctl;
                    TempDDL.Attributes.Add("onFocus", "DoFocus(this);");
                    TempDDL.Attributes.Add("onBlur", "DoBlur(this);");
                }
            }
Name : Surjit
Comment : It works with Visual Studio 2005 Page.Form is accessible But with Visual Studio 2003 Page.Form is not accessible.It says Form is private read only. Has anyone workaround for VS 2003? let me know

Martin :
With 2003 you'll have to recursively loop through the ControlCollections as controls are embeded within controls. see example below for 2003.

   Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Put user code to initialize the page here
        If Not Page.IsPostBack Then
            SetHighlightFields(Page.Controls)
        End If

    End Sub

    Sub SetHighlightFields(ByVal frm As ControlCollection)
        Dim TempCheckbox As CheckBox = Nothing
        Dim TempTextBox As TextBox = Nothing
        For Each tmpctl As Control In frm
            ' check to see if this has a sub collection of controls
            If tmpctl.Controls.Count > 0 Then
                SetHighlightFields(tmpctl.Controls)
            End If
            If TypeOf tmpctl Is TextBox Then
                TempTextBox = CType(tmpctl, TextBox)
                TempTextBox.Attributes.Add("onFocus", "DoFocus(this);")
                TempTextBox.Attributes.Add("onBlur", "DoBlur(this);")
            End If
        Next
    End Sub
Name : Sebastian
Comment : What about using jQuery instead of bloating the C#/VB.NET code? It would only take two lines of Javascript and an addition script tag to include the library.

$("input").focus(function() { $(this).addClass("focusfld"); })
$("input").blur(function() { $(this).removeClass("focusfld"); })

Cheers, Sebastian

Name
Comment