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:
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:
<script
type="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.
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):
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:
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.
Thanks. This also solved my very similar problem. However, in my case, I am using nested master pages and the ScriptManager1 was in the top level master. In order to get a reference to it, I had to use a MasterType directive in both master pages, and also
put a read-only property in each master page passing the reference to the Scriptmanager down to the content page. Works great.
Thanks. This also solved my very similar problem. However, in my case, I am using nested master pages and the ScriptManager1 was in the top level master. In order to get a reference to it, I had to use a MasterType directive in both master pages, and also
put a read-only property in each master page passing the reference to the Scriptmanager down to the content page. Works great.
Hi dhurwitz,
I have a similar case. However, when I compile the statement below, I received an error stating that the scriptmanager1 not found in master page. I checked and it was there. Could you show me how you did the reference thing. I only have one masterpage.
I need one help from you. I am trying to set focus to different controls after my different PostBack events, but this.ScriptManager1.SetFocus(myControlName.ClientID); is not working.
In my ASPX page I have RAD CONTROLS (RadComboBox and RadCalendar) and also I am using AjaxControlToolkit Controls (ToolkitScriptManager and ModalPopupExtender) also.
In my page, RadComboBox is in UpdatePanel - ContentTemplate area and on its SelectedIndexChanged function I am trying to set focus to another Control using the above code:
but this is not working... Do anyone know any solution for this?
Thanks...
ajaxupdatepanel autopostback"ModalPopUpExtender""Update Panel"UpdatePanel ajax"Focus" "UpdatePanel""AJAX Toolkit" "Ajax Control Toolkit"AJax UpdatePanelajax .NET 2.0 AjaxControlKit PopupControlExtender debug There is no source code available for the current location Page_PreRender"AJAX .NET 2.0""Ajax Control Toolkit" disable codebehind
Here I am using a function GetPostBackControl() to identify the current postbacking control and I am setting focus to the same control. If you want to move focus to any other control, just use a Switch Statment.
public static System.Web.UI.Control GetPostBackControl(System.Web.UI.Page page)
{
Control control = null;
string ctrlname = page.Request.Params["__EVENTTARGET"];
if (ctrlname != null && ctrlname != String.Empty)
{
control = page.FindControl(ctrlname);
}
// if __EVENTTARGET is null, the control is a button type and we need to
// iterate over the form collection to find it
else
{
string ctrlStr = String.Empty;
Control c = null;
foreach (string ctl in page.Request.Form)
{
// handle ImageButton controls ...
if (ctl.EndsWith(".x") || ctl.EndsWith(".y"))
{
ctrlStr = ctl.Substring(0, ctl.Length - 2);
c = page.FindControl(ctrlStr);
}
else
{
c = page.FindControl(ctl);
}
if (c is System.Web.UI.WebControls.Button ||
c is System.Web.UI.WebControls.ImageButton)
{
control = c;
break;
}
}
}
return control;
}
hartmacw
Member
208 Points
51 Posts
AJAX UpdatePanel - Textbox focus question - simple example
Mar 14, 2007 04:59 PM|LINK
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
<%@ 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:
<%@ 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);
}
}
hartmacw
Member
208 Points
51 Posts
Re: AJAX UpdatePanel - Textbox focus question - simple example
Mar 16, 2007 12:09 PM|LINK
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:
<script type="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
hartmacw
Member
208 Points
51 Posts
Re: AJAX UpdatePanel - Textbox focus - problem resolved, but WHY?
Mar 16, 2007 04:54 PM|LINK
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
Shweirguy
Member
3 Points
3 Posts
Re: AJAX UpdatePanel - Textbox focus - problem resolved, but WHY?
Mar 23, 2007 11:48 PM|LINK
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.
hartmacw
Member
208 Points
51 Posts
Re: AJAX UpdatePanel - Textbox focus - problem resolved, but WHY?
Mar 24, 2007 09:24 AM|LINK
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
shrirampopha...
Member
2 Points
1 Post
Re: AJAX UpdatePanel - Textbox focus - problem resolved, but WHY?
Jul 26, 2007 12:46 PM|LINK
Many many thanks for your inputs! It really worked![:)]
dhurwitz
Member
87 Points
161 Posts
Re: AJAX UpdatePanel - Textbox focus - problem resolved, but WHY?
Feb 13, 2008 04:32 PM|LINK
Thanks. This also solved my very similar problem. However, in my case, I am using nested master pages and the ScriptManager1 was in the top level master. In order to get a reference to it, I had to use a MasterType directive in both master pages, and also put a read-only property in each master page passing the reference to the Scriptmanager down to the content page. Works great.
blumonde
Participant
1866 Points
494 Posts
Re: AJAX UpdatePanel - Textbox focus - problem resolved, but WHY?
Jun 11, 2008 12:12 AM|LINK
Hi dhurwitz,
I have a similar case. However, when I compile the statement below, I received an error stating that the scriptmanager1 not found in master page. I checked and it was there. Could you show me how you did the reference thing. I only have one masterpage.
this.Master.ScriptManager1.SetFocus(txtLname.ClientID);Thanks.
no pain no gain
augustuslesh
Member
8 Points
4 Posts
Re: AJAX UpdatePanel - Textbox focus - problem resolved, but WHY?
Jun 19, 2008 03:47 PM|LINK
Hi All,
I need one help from you. I am trying to set focus to different controls after my different PostBack events, but this.ScriptManager1.SetFocus(myControlName.ClientID); is not working.
In my ASPX page I have RAD CONTROLS (RadComboBox and RadCalendar) and also I am using AjaxControlToolkit Controls (ToolkitScriptManager and ModalPopupExtender) also.
In my page, RadComboBox is in UpdatePanel - ContentTemplate area and on its SelectedIndexChanged function I am trying to set focus to another Control using the above code:
this.ScriptManager1.SetFocus(myControlName.ClientID);
but this is not working... Do anyone know any solution for this?
Thanks...
ajax updatepanel autopostback "ModalPopUpExtender" "Update Panel" UpdatePanel ajax "Focus" "UpdatePanel" "AJAX Toolkit" "Ajax Control Toolkit" AJax UpdatePanel ajax .NET 2.0 AjaxControlKit PopupControlExtender debug There is no source code available for the current location Page_PreRender "AJAX .NET 2.0" "Ajax Control Toolkit" disable codebehind
augustuslesh
Member
8 Points
4 Posts
Re: AJAX UpdatePanel - Textbox focus - problem resolved, but WHY?
Jun 20, 2008 02:18 PM|LINK
Hi All,
I got solution for the above issue. I was trying to set focus using the code
this.ScriptManager1.SetFocus(myControlName.ClientID);
and I wrote this code in my SelectedIndexChanged Event Function. That time this code didn't work.
Now I changed this code to Page Load Function i.e.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
this.ScriptManager1.SetFocus(myControlName.ClientID);
}
else
{
this.ScriptManager1.SetFocus(GetPostBackControl(this.Page).ClientID);
}
}
Here I am using a function GetPostBackControl() to identify the current postbacking control and I am setting focus to the same control. If you want to move focus to any other control, just use a Switch Statment.
public static System.Web.UI.Control GetPostBackControl(System.Web.UI.Page page)
{
Control control = null;
string ctrlname = page.Request.Params["__EVENTTARGET"];
if (ctrlname != null && ctrlname != String.Empty)
{
control = page.FindControl(ctrlname);
}
// if __EVENTTARGET is null, the control is a button type and we need to
// iterate over the form collection to find it
else
{
string ctrlStr = String.Empty;
Control c = null;
foreach (string ctl in page.Request.Form)
{
// handle ImageButton controls ...
if (ctl.EndsWith(".x") || ctl.EndsWith(".y"))
{
ctrlStr = ctl.Substring(0, ctl.Length - 2);
c = page.FindControl(ctrlStr);
}
else
{
c = page.FindControl(ctl);
}
if (c is System.Web.UI.WebControls.Button ||
c is System.Web.UI.WebControls.ImageButton)
{
control = c;
break;
}
}
}
return control;
}
Thank you,