Showing posts with label focus. Show all posts
Showing posts with label focus. Show all posts

Wednesday, March 28, 2012

AJAX UpdatePanel - Textbox focus question - simple example

I have run across an issue recently while incorporating AJAX into one of my applications. The issue demonstrates either my fundamental lack of understanding about how this technology works, or a problem in my implementation of it. I have created an bare-bones simple example to demonstrate what I'm seeing. I know how to remedy the problem, but I'd prefer the discussion center around *WHY* it's happening.

Here are the details. Consider a project with a default.aspx. That page has two controls, Button1 and PlaceHolder1. The project also contains as usercontrol, uc1.ascx, which simply contains a TextBox control, TextBox1. The click event of Button1 dynamically loads uc1 into the placeholder via the Page.LoadControl method. All I really want to do is set focus to to TextBox1 after the control is loaded. Without the UpdatePanel, I can do it two ways. I can either put TextBox1.Focus(); in UC1's page load event, or I can register a startup javascript to find the textbox and use its focus() method. Either way works fine. See example code below.

Now introduce UpdatePanel. Enclose Button1 and PlaceHolder1 in the same UpdatePanel. The result, no focus to the textbox. Move Button1 outside of the UpdatePanel, focus will work. Fundamental question is - WHY? Why does it matter where that button control is in relation to the Placeholder and UpdatePanel. I've done a lot of searching on this topic and I've found lots of questions but not many answers. Here's the code I'm using, to get focus to work correctly, move Button1 outside of the UpdatePanel:

Default.aspx

<%@dotnet.itags.org. Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div>
<asp:UpdatePanel ID="up1" runat="server">
<ContentTemplate>
<asp:Button ID="Button1" runat="server" Text="Load UC1" OnClick="Button1_Click" />
<br />
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>

Button1_Click Event:

protected void Button1_Click (object sender, EventArgs e)
{
Control ctrl = new Control();
this.PlaceHolder1.Controls.Clear();
ctrl = Page.LoadControl("uc1.ascx");
ctrl.ID = "DynamicCtrl";
this.PlaceHolder1.Controls.Add(ctrl);
}

uc1.ascx:

<%@dotnet.itags.org. Control Language="C#" AutoEventWireup="true" CodeFile="uc1.ascx.cs" Inherits="uc1" %>
UserControl 1 <br />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>

uc1.ascx.cs:

using System;
using System.Web.UI;

public partial class uc1 : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
//use either of these two lines in the example
//this.TextBox1.Focus();
ScriptManager.RegisterStartupScript(this, typeof(UserControl), "focus", "document.getElementById('DynamicCtrl_TextBox1').focus();", true);
}
}

OK, now I'm really annoyed and I'm punchy enough to reply to my own posts. In reading a multitude of UpdatePanel/focus related threads, I found a snipped of javascript code that I though I'd try. I inserted the following section of code in the default.aspx contained in my original post. First I inserted it in the head section of the page and that resulted in the dreaded 'Sys' is undefined message. Then I moved the javascript *below* the scriptmanager and the page loaded with no errors. Here's the code I now have inserted in default.aspx just before the end form tag:

<scripttype="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(pageLoaded);
function pageLoaded(sender, args)
{
if (args.get_panelsUpdated().length > 0)
{
$get('DynamicCtrl_TextBox1').focus();
}
}
</script>

So here's what is making me punchy. I try the page in IE 6 & 7, no focus to the textbox. Try in FireFox, *FOCUS WORKING CORRECTLY*!! Now that's annoying. Could someone please take a stab at either reproducing what I'm seeing or possibly explaining it?? Thanks.

...BillH


I am developing a liking to responding to my own posts - makes me feel loved.

OK, so a few minutes ago I tried something that made my above scenario work. Don't know why, but now I have textbox focus in both IE and Firefox and the solution fits within the context of the project I'm working on. I don't need any startup scripts or Focus() methods on the textbox control.

What I did was create a public accessor for TextBox1 in the user contol codebehind as such:

public TextBox t
{
get
{
return this.TextBox1;
}
}

Then I added the following one line to the Button1 click event (after the dynamic control is added to the placeholder):

this.ScriptManager1.SetFocus(((uc1)ctrl).t.ClientID);

Viola. Textbox focus in both IE7 and Firefox. No idea why, take it for what it's worth.

...BillH


Thank you so much!

I've been working on this issue for a while now... I couldn't get any of my TextBoxes inside any UpdatePanels to set focus.

The solution seems like you just have to set the focus like this:

this.ScriptManager1.SetFocus(TextBox1);

and voila it works.


Yep, that works when your textbox is on the page that's loaded. In my case, it was in a user control that was being dynamically loaded via button click events. At any rate, while your above sample would work when the control is within the same form as the ScriptManager, I would strongly suggest you explicitly pass the SetFocus method the ClientID of the control:

this.ScriptManager1.SetFocus (this.TextBox1.ClientID);

In that way if you go back and reuse this code somewhere and you have a textbox on a usercontrol or within some other dynamically loaded control it would still work.

...BillH


Many many thanks for your inputs! It really worked!Smile

Ajax update panel focus problem

Hi

I have a asp.net 2 web app that uses asp.net ajax and master pages. I have a very common problem that I think most people get when using an update panel and textboxes. The tab order after leaving the text box is lost, so I have heard the fix is to use

Me.ScriptManager1.SetFocus(Textbox1.ClientID);

Rather than adding the ScriptManager to every page I have added it to my Master page. However my update panel exists within a user control, which is then embeded in a master page. So the above syntax does not work in my user control as it does not know about the ScriptManager as it is defined in my master page.

Any ideas on how I could get this to work? Or any other methods to get round this textbox focus problem?

Many thanks inadvance

Use ScriptManager.GetCurrent() to get a reference to the page's ScriptManager.


See for more detail.

http://asp.net/AJAX/Documentation/Live/mref/O_T_System_Web_UI_ScriptManager_SetFocus.aspx


Hi,

You may get reference to the scriptManager instance via
ScriptManager.GetCurrent(this.Page)

Hope this helps.


I'm having a similar problem, except that I have a timer that refreshes some content every 4 seconds. I set the

this.ScriptManager1.SetFocus(tbMessage.ClientID);

but when the content refreshes, it sends the cursor to the beginning of the text box. Even when i'm in the middle of typing something.Tongue Tied

Is there a way to keep the cursor exactly where it was when content was updated in the update panel?

- Albert

(PS - Sorry to hijack this thread.)