Thursday, June 11, 2009

Keep the TextBox Focus inside UpdatePanel

At this time, let's talk about the old issue -- UpdatePanel Focus problem
Assuming that you have a TextBox inside UpdatePanel, when you set an Ajax Timer for this UpdatePanel or set TextChanged event of TextBox in order to make the TextBox do postback, you will find it losts focus from TextBox after you type something and do postback.
For instance, please check the following sample:

<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:TextBox ID="TextBox1" runat="server" OnTextChanged="TextBox1_TextChanged"

AutoPostBack="true"></asp:TextBox>
<asp:Label runat="server" Text="" ID="Label1"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>



protected void TextBox1_TextChanged(object sender, EventArgs e)
{
Label1.Text="you inputed " + TextBox1.Text;
//ScriptManager1.SetFocus(TextBox1);

}


In above sample, TextBox will lost focus after you press enter and doing postback.

As a solution, We can use ScriptManager1.SetFocus(TextBox1) to focus the Textbox1 again after postback. As a result, it gets the focus, but the cursor in TextBox is changed and initialized(It goes to the first charactor location, instead of keeping to the current location).

To resolve this problem so that it can keep the current location in Textbox after postback, we can use the following JavaScript to set the location in TextBox manually.


function setfocus() {
var txb = $get("<%=TextBox1.ClientID%>");
var t = txb.createTextRange();
t.collapse(true);

t.moveStart("character", txb.value.length);
t.select();

}


In addition, we need use JavaScript to store the current location in TextBox before postback and set it back after postback. See the entire sample as below.


<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:TextBox ID="TextBox1" runat="server" OnTextChanged="TextBox1_TextChanged"

AutoPostBack="true"></asp:TextBox>
<asp:Label runat="server" Text="" ID="Label1"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>

<script type="text/javascript">
var currentCaret;
function getCaret(textbox) {
var textbox = $get("<%=TextBox1.ClientID%>");
var control = document.activeElement;
textbox.focus();
var rang = document.selection.createRange();
rang.setEndPoint("StartToStart", textbox.createTextRange());
return rang.text.length;
}


function setfocus() {
var txb = $get("<%=TextBox1.ClientID%>");
var t = txb.createTextRange();
t.collapse(true);

t.moveStart("character", currentCaret);
t.select();

}

Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(
function(sender, e) {
currentCaret = getCaret($get("<%=TextBox1.ClientID%>"));

});
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(
function(sender, e) {

setfocus();
});

</script>



protected void TextBox1_TextChanged(object sender, EventArgs e)
{
Label1.Text = "you inputed " + TextBox1.Text;

}


Following this sample, it will store the current cursor loacation in TextBox in beginRequest event, and set it back in endRequest event. In this way, it will achieve keeping the current location in TextBox.

(It's also working if you use an Ajax Timer inside UpdatePanel.)

7 comments:

Mike Malloy said...

I have a bunch of textboxes in an updatepanel. I have them use the same TextChanged event.

When you hit tab, I WANT it to go to the next textbox. How do I set the focus of where it WAS going?

Vince Xu said...

That sounds another problem. You can set the keypress event to handle what key the user pressed. If it is tab key, you can set the focus by using the same approach.

Anonymous said...

That sounds another problem.
___________________

Vince

Your movies on demand

Anonymous said...

Thanks Vince...just what I needed.

Unknown said...

Do you have code sample that would show in an update panel containing 3 or more textboxes, how to:

1. Move cursor to next textbox after postback while retaining value?
1. Retain cursor position in current field/location after the form is refreshed using F5 (before or after a postback has occurred)while retaining value?

Anonymous said...

Hi,
i have a ajax editor under some textboxes ,i tried your code to focus on the first text box.Even on page load the focus is inside the ajax editor. Is there any way to bring the focus up inside the textbox. (this code is not working for me. :( )

Prasanna said...

Hi,
I have a textbox inside a update panel and no events for that text box.When I set text-align to right alignment to the text box then the cursor was not blinking. Please help me