IBlog<Johan>

This and that in a developer's life in general

News

Follow johandanforth on Twitter

Random Links

Walkthroughs and Tutorials

Set focus on a clicked control in ASP.NET

Jan-Erik just blogged about how to set focus on a clicked control in an ASP.NET page. Sometimes you need to do that if the page you have is very, very long or if you have a list with vertical controls and you want to put focus on the clicked control after a postback. One way of doing it is to set focus in each and every control event (button1_clicked, button2_clicked) and so on. But what Jan-Erik is looking for is to put the focus-code in one place only.

Jan-Erik thought that his solution was a bit hacky and asked for another way of doing it, and I think I have a pretty simple one. The trick is to override the OnBubbleEvent() and check who the sender is. This seems to work pretty well:

protected override bool OnBubbleEvent(object sender, EventArgs e)

{

           if(sender is Button ||

                      sender is ImageButton)

           {

                      WebControl webControl = (WebControl)sender;

                      Debug.WriteLine("Clicked " + webControl.ClientID);

                      StringBuilder sb = GetFocusScriptBlock(webControl);

                      RegisterClientScriptBlock("FocusScript", sb.ToString());

           }

           return base.OnBubbleEvent(sender, e);

}

 

private static StringBuilder GetFocusScriptBlock(WebControl webControl)

{

           StringBuilder sb = new StringBuilder(1000);

           sb.Append("<script language = \"javascript\">");

           sb.Append("function ControlFocus() {");

           sb.Append("document.getElementById('" + webControl.ClientID + "').focus();");

           sb.Append("}");

           sb.Append(String.Concat(Environment.NewLine, Environment.NewLine, "window.onload = ControlFocus;"));

           sb.Append("</script>");

           return sb;

}

 

Any comments on this code? You think this is useful?

It may be good to know in what order the events happen in a Page:

1. Page_Load()
2. The specific event for the clicked control (Button1_Click() for example)
3. OnBubbleEvent()

Comments

Rick Scott said:

I did this by using a base class that inherits from PageBase and overrides the Render() function with something like this:

protected override void Render(HtmlTextWriter writer)
{
writer.WriteLine("<HTML>\r\n<HEAD>");
writer.WriteLine(" <TITLE>" + PageTitle + "</TITLE>");

WriteNoCacheCommands(writer);

writer.WriteLine(" <LINK HREF='" + sStyleSheet + "' TYPE='TEXT/CSS' REL='STYLESHEET' />");

writer.WriteLine("</HEAD>\r\n");
if(ctrlFocusOnLoad != null)
writer.WriteLine("<BODY ONLOAD='JAVASCRIPT:document.Form1." + ctrlFocusOnLoad.ClientID + ".focus();'>\r\n");
else
writer.WriteLine("<body>\r\n");

writer.WriteLine("<NOSCRIPT><H2>This page requires JavaScript.<BR>Your Browser does not support JavaScript<BR>");
writer.WriteLine("OR is configured with JavaScript DISABLED.<BR><BR>To view this page, upgrade your Browser and/or ENABLE JavaScript.");
writer.WriteLine("<BR><A HREF='http://www.mozilla.org'><B>DOWNLOAD FireFox now</A><HR></H2></NOSCRIPT>\r\n\r\n");

base.Render( writer );

writer.WriteLine("\r\n</BODY>");

// To see why this duplicate <head> section is here, see http://support.microsoft.com/kb/q222064/
writer.WriteLine("<HEAD>");
WriteNoCacheCommands(writer);
writer.WriteLine("</HEAD>");

writer.WriteLine("</HTML>");

}

// In order to avoid writing the same commands out twice, here is a function used only by Render()
private static void WriteNoCacheCommands(HtmlTextWriter writer)
{
writer.WriteLine(" <META HTTP-EQUIV='PRAGMA' CONTENT='NO-CACHE'>");
writer.WriteLine(" <META HTTP-EQUIV='CACHE-CONTROL' CONTENT='NO-CACHE'>");
writer.WriteLine(" <META NAME='CACHE-CONTENT' CONTENT='NO-CACHE'>");
writer.WriteLine(" <META HTTP-EQUIV='EXPIRES' CONTENT='0'>");
}

Of course, there is lots more site-specific functionality in my base class (rendering header logo, menu, login verification, etc.), but you get the idea :)
# March 31, 2005 9:46 AM

Paul M said:

Try out Strength Technologies Smart Scroller. It is a free lightweight control whose speciality is ensuring the page is scrolled to the correct position after postback. I use it in many apps and its just plain awesome.

http://www.asp.net/ControlGallery/ControlDetail.aspx?Control=1351&tabindex=2

Enjoy
# March 31, 2005 1:45 PM