
Coincidence made it that this week people have asked me twice about how to preserve focus during postbacks, especially during auto postbacks. I didn't really know much about how ASP.Net does this other than building your own script, so I started investigating.
When you post back, there is a postback event reference that is used. The
Page.ClientScript property, of the type
ClientScriptManager, has a bunch of methods called
GetPostBackEventReference which return different script strings for different options. The options are encapsulated into a
PostBackOptions object which has, interestingly enough, a property called
TrackFocus. Wow! Exactly what I wanted.
The problem comes when digging in the
System.Web sources and seeing that no one actually sets this property. I did a bunch of code to add the script with the
TrackFocus property and it seems it works. Not only does it preserve the focus before the postback, but also the scroll bars position. I tested in Internet Explorer, FireFox and Chrome and it worked on all.
So what is going on?
Why does this feature, which I imagine is quite useful, seem only half done? And that since the era of .Net 2.0? I have no idea. I will post this method, applicable on TextBox controls, although I guess it could be applied on most if not all AutoPostback controls, that replaces the script for a normal AutoPostback with one that also preserves focus:
private void fixAutoPostBack(TextBox tb)
{
if (!tb.AutoPostBack)
return;
tb.AutoPostBack = false;
PostBackOptions options
= new PostBackOptions(tb, string.Empty)
{
TrackFocus = true,
AutoPostBack = true
};
if (tb.CausesValidation)
{
options.PerformValidation = true;
options.ValidationGroup = tb.ValidationGroup;
}
string onchange = string.Empty;
if (tb.HasAttributes)
{
onchange = tb.Attributes["onchange"];
if (!string.IsNullOrEmpty(onchange))
{
onchange = onchange.TrimEnd(';') + ";";
}
}
onchange += ClientScript
.GetPostBackEventReference(options, true);
tb.Attributes["onchange"] = onchange;
}
As you can see, the only thing I do differently from the normal AutoPostback code is to set TrackFocus to true.