Introduction
I've been working on trying to set the focus of client side controls today and thought
I'd submit this as I think it could be useful. I hope I haven't missed a method that
is already built into ASP.NET that already does this.
I've created a helper class that enables you to set the client side focus
with a single call. I decided against creating a subclass of the Page
class
as I think the helper class approach is better and easier to implement
on existing systems.
How it worked originally
All that is required is the ID of the form which the control is in and the
ID of the control itself. There are a couple of overloaded functions that
automatically find these IDs depending on what type of server control
you pass as a parameter.
private void Page_Load(object sender, System.EventArgs e)
{
if( !this.IsPostBack )
{
McGiv.Web.UI.ClientSideFocus.setFocus(this.TextBox1);
this.ViewState["focus"] = "WebControl";
}
}
The JavaScript script is then generated and registered to the given Page
object.
The script itself makes a copy of the document.body.onload
function and
replaces it with the focus setting function which in turn calls the original
onload
function, which means that you won't have to tinker with any existing
onload
scripts you may have within your pages.
if(document.body.onload)
original = document.body.onload;
document.body.onload = document_onLoad;
function document_onLoad()
{
try
{
document.FormID.ControlID.focus();
}
catch(e){}
original();
}
function original()
{
}
How it works now
After being notified that the original code could potentially steal
the focus of another window (which can be irritating), I switched from
using the document.body.onload
event to the document.body.onfocus
event.
var called = false;
if(document.body.onfocus)
orig_document_body_onfocus = document.body.onfocus;
document.body.onfocus = document_body_onfocus;
function setFocus()
{
var control = document.getElementById("html");
if(control)
control.focus();
}
function orig_document_body_onfocus(){}
function document_body_onfocus ()
{
if( !called )
{
called = true;
setFocus();
}
orig_document_body_onfocus();
}
if( window.__smartNav && window.__smartNav.restoreFocus)
{
orig_window__smartNav_restoreFocus = window.__smartNav.restoreFocus;
window.__smartNav.restoreFocus = window__smartNav_restoreFocus;
}
function orig_window__smartNav_restoreFocus(){}
function window__smartNav_restoreFocus()
{
setFocus();
orig_window__smartNav_restoreFocus
}
I�ve also tried to solve the problem with Smart Navigation by overriding
the restoreFocus
function from within SmartNav.js file but this seems to only
work on my local machine at the moment. This may be due to a security issue
or due to the loading time taken from remote hosts.
I removed the need for the ID of the HTML form, as with most cases within ASP.NET, the page will only use one form. This modification alone removes about
half the content from the original code. I�ve included the original code
if you still need to reference the form's ID as well as the control ID.
Known Issues
Currently, the helper class doesn�t function properly when Smart Navigation is enabled.
The demo
I've included a simple demo that switches focus between a WebControl
,
HtmlControl
and a hard coded HTML input control.
I use the viewstate to keep track of which control has focus.
private void Button1_Click(object sender, System.EventArgs e)
{
string focus = this.ViewState["focus"] as string;
if( focus == null )
focus = "WebControl";
switch(focus)
{
case "Html":
{
McGiv.Web.UI.ClientSideFocus.setFocus(this.TextBox1);
this.ViewState["focus"] = "WebControl";
break;
}
case "HtmlControl":
{
McGiv.Web.UI.ClientSideFocus.setFocus(this, "html");
this.ViewState["focus"] = "Html";
break;
}
case "WebControl":
{
McGiv.Web.UI.ClientSideFocus.setFocus(this.HtmlControl1);
this.ViewState["focus"] = "HtmlControl";
break;
}
}
}
In order to get it to work, unzip the demo files into a virtual directory
mapped to http://localhost/ClientSideFocus/.
I've also setup an online demo here.
Enjoy.
Version History
- Version 1.3: Wednesday 21 Jan 2003
- Fixed null object JavaScript bug.
- Version 1.2: Tuesday 20 Jan 2003
- Moved the call to
setFocus
from the document.body.onload
event to
the document.body.onfocus
event. This stops the focus being taken from
another browser window that has the focus.
- Discovered that the code only works with Smart Navigation on my
local machine & not my remote host. Don't know if this is a security
issue or a loading time issue.
- Version 1.1: Wednesday 14 Jan 2003
- Removed script from
onload
event. Allows it to work with Mozilla browsers too.
- Used
getElementById([control name])
instead of using [form name].[control name]
.
- Removed need to search for form's ID - with ASP.NET, only 1 form is used
normally removing the need to supply the form ID.
- Overrides
restoreFocus
Smart Navigation function.
Now works when smart navigation is enabled.
- Version 1.0: Tuesday 13 Jan 2003
- Will function if Smart Navigation is enabled on the WebForm. Only tested on IE 6.1.