Keep control in focus during a partial-page update
I was writing a tool using ASP.net and UpdatePanel that would automatically save the data any time the data entered changed. I was using AutoPostBack="true" to and thanks to the UpdatePanel, the save was invisible to the users.
Well, except for one little problem: if any control had focus before posting the page back to the server, it was lost at the end of the request. Which is rather annoying when you have a form and are used to TABbing between input elements.
I've looked around for a solution, but there was nothing that really worked for me. Some of them had a tab index in the element and assumed the focus should go to the next element after the update. But what happen if I shift-tab? Hummm. So I wrote this javascript code that does a pretty good job, but it is not perfect.
The issues are: there is a flicker of the caret between the time the AJAX framework clears focus and when I reset it. Also, the normal behavior of selecting the entire text in an input field (so that you can overwrite it) is lost; instead the caret is positioned at the end of the text. Finally (for what I've discovered so far), if you click from a AutoPostBack control to the middle of a text control (like click between the 'o' and 'r' in the word 'word'), the caret will be repositioned at the end of the word.
There may be other quirks as well, but the value of getting rid of any 'save' button is too good not to use. Why does Microsoft AJAX framework behave like this? After all, they have all the tools necessary to track which element has the focus. Maybe they will give us some options in a future patch. Or maybe there is something I simply overlooked and it is already there.
In any case here is my solution. You'll need this javascript:
function manageFocus_addOnFocus()
{
var el = document.forms[0].elements;
var el_type = "";
for(var i=0;i
{
el_type = el[i].type;
if( el_type )
{
if( el_type == "text" || el_type == "textarea" || el_type.indexOf("select") >-1 ||
el_type == "radio" || el_type == "checkbox" || el_type == "submit" || el_type == "button" )
{
el[i].onfocus=function()
{
manageFocus_lastInFocusElement=this;
}
}
}
}
}
var manageFocus_lastInFocusElement = null;
function manageFocus_RestoreFocus(source, args)
{
if( manageFocus_lastInFocusElement )
{
document.getElementById(manageFocus_lastInFocusElement.id).focus();
}
}
function manageFocus_AddEventHandlers()
{
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(manageFocus_RestoreFocus);
}
function manageFocus_Init()
{
manageFocus_addOnFocus();
manageFocus_AddEventHandlers();
}
And a way to run manageFocus_Init() when the page loads. I use the following code to inject both the code and the onload command:
ScriptManager.RegisterClientScriptInclude(this, typeof(string),"manageFocus", "manageFocus.js"); ScriptManager.RegisterStartupScript(this, typeof(string), "manageFocus_startup", "manageFocus_Init();", true);
Labels: asp.net javascript focus html

0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home