No Focus from onload event

Asked By tom shad
25-Jul-07 08:25 PM
Earn up to 0 extra points for answering this tough question.
I almost got this to work.
 
I can access the <body ID="myBody" runat="server"> tag from inside my User control and add an onLoad event to the tag.  When I add the onLoad event to the myBody tag - it is there, but the control still doesn't get focus.  I named the User Control to make sure I can get to it, but it still doesn't work.
 
I tried to use:
 
    a.Attributes.Add("onLoad","addForm.LoginID.UserName.focus()")
But got an error that said that LoginID wasn't a member of addForm.  I then tried to loop through the addForm elements and found the Name = LoginID:txtUserName.  I changed the line to:
 
    a.Attributes.Add("onLoad","addForm.LoginID:txtUserName.focus()")
 
I don't get the error now, but it still doesn't seem to work.  It is still not getting focus.
Here are the 2 files:
 
test.aspx:
**********************************************
<%@ Page Language="VB" trace="false" ContentType="text/html" ResponseEncoding="iso-8859-1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@ Register TagPrefix="fts" TagName="Logon" src="test.ascx" %>
<html>
<head>
<title>Login</title>
</head>
<body id="myBody" runat="server" >
 <form id="addForm" runat="server">
   <fts:Logon ID="LoginID" runat="Server"/>     
 </form>
</body>
</html>
***********************************************
 
test.ascx:
***********************************************
<script runat="server" > 
 Sub Page_Load(sender as Object, e as EventArgs)
  dim IsCheckResumes as Boolean = true
  if not IsPostBack
    Dim a as htmlControl
    a = CType(Page.FindControl("myBody"),htmlControl)
    a.Attributes.Add("onLoad","addForm.LoginID:txtUserName.focus()")
  end if
 End Sub
  
 Public Property UserName AS String
  Get
   Return txtUserName.Text
  End Get
  Set
   txtUserName.Text = Value
  End Set   
 End Property
 
</script>
 
<asp:textbox id="txtUserName" TextMode="SingleLine" Columns="25" runat="server" />
 <asp:RequiredFieldValidator
 ControlToValidate="txtUserName"
 Text="User Name Required"
 runat="server" />
**********************************************
 
Here is the Tree from the Trace:
 
__PAGE ASP.test_aspx
    _ctl0 System.Web.UI.LiteralControl
    _ctl1 System.Web.UI.LiteralControl
    myBody System.Web.UI.HtmlControls.HtmlGenericControl
        _ctl2 System.Web.UI.LiteralControl
        addForm System.Web.UI.HtmlControls.HtmlForm
            _ctl3 System.Web.UI.LiteralControl
            LoginID ASP.test_ascx
                LoginID:txtUserName System.Web.UI.WebControls.TextBox
                LoginID:_ctl1 System.Web.UI.LiteralControl
                LoginID:_ctl0 System.Web.UI.WebControls.RequiredFieldValidator
                LoginID:_ctl2 System.Web.UI.LiteralControl
            _ctl4 System.Web.UI.LiteralControl
        _ctl5 System.Web.UI.LiteralControl
    _ctl6 System.Web.UI.LiteralControl
 
Thanks,
 
Tom

  Do a View Source on the rendered page in the browser.

Peter Bromberg replied to tom shad
25-Jul-07 08:57 PM

You need to look at the resultant id of the control - its probably a lot different than what your code thinks. Use control.ClientId from the server side to resolve this. Also, you can use the ClientScript.RegisterXXX set of methods to inject script directly (either from the control or from the Page itself.

Moreover, there are several methods that are built into the ASP.NET control and page framework that will let you set default focus on controls.

  I did and did get it to work but not as I wanted

tom shad replied to Peter Bromberg
25-Jul-07 09:15 PM

I did that as well as the Trace that was in the original post and found the ID = LoginID:txtUserName.  So I don't need to make this variable public.

But I still couldn't get this to work directly from the <body> tag, as I would like.  Shail put me in the right direction to get it to work calling a function - but I would think I should be able to call it directly.

Ok, I got it to work.  But not the way I wanted.

I tried:

    a.Attributes.Add("onLoad","addForm.LoginID:txtUserName.focus();")

and

    a.Attributes.Add("onLoad","LoginID:txtUserName.focus();")

Neither one of these worked.  There was no error but there was no focus,
either.

I made a change by calling a Javascript function from the onload function
and this worked.  The LoginID:txtUserName is the correct name but why does
the above not work???

The files that work are:

test.aspx:
*************************************************
<%@ Page Language="VB" trace="true" ContentType="text/html"
ResponseEncoding="iso-8859-1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@ Register TagPrefix="fts" TagName="Logon" src="test.ascx" %>
<html>
<head>
<title>Login</title>
<script language="JavaScript">
function GetFocus()
{
      if (document.getElementById("LoginID:txtUserName") != null)
   {
           document.getElementById("LoginID:txtUserName").focus();
   }
}
</script>
</head>
<body id="myBody" runat="server">
 <form id="addForm" runat="server">
   <fts:Logon ID="LoginID" runat="Server"/>
 </form>
</body>
</html>
*************************************************

test.ascx:
*************************************************
<script language="vb" runat="server" >
 Sub Page_Load(sender as Object, e as EventArgs)
  dim IsCheckResumes as Boolean = true
  if not IsPostBack
    Dim a as htmlControl
    a = CType(Page.FindControl("myBody"),htmlControl)
    a.Attributes.Add("onLoad","GetFocus();")
  end if
 End Sub

 Public Property UserName AS String
  Get
   Return txtUserName.Text
  End Get
  Set
   txtUserName.Text = Value
  End Set
 End Property

</script>

<asp:textbox id="txtUserName" TextMode="SingleLine" Columns="25"
runat="server" />
 <asp:RequiredFieldValidator
 ControlToValidate="txtUserName"
 Text="User Name Required"
 runat="server" />
*************************************************

This works but I would rather do the focus directly from the <body> tag and
not have to build an extra function for each page that needs to have focus.

Can anyone explain to me why this isn't working?  Does it have to do with
timing on when a control is put on the page?  I would assume this wouldn't
be the case as the page is built before the onload function is called (isn't
it?).

I don't know of the other methods that are built into asp.net control to set default focus.  When I was looking in this - this was the only method I was told about that worked when I wasn't dealing with a User Control.  I am using Asp.net 1.1, BTW.

Thanks,

Tom

  if you r using usercontrol then do as under

SAM K replied to tom shad
25-Jul-07 10:23 PM
on the pageload of your user control add below code

 Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

            Dim str As String = "<script language=javascript>function SetControlfocus(){document.getElementById('" & Me.txtLogin.ClientID & "').focus();}</script>"

        If Not Page.IsStartupScriptRegistered("SetCtlFocus") Then
            Page.RegisterStartupScript("SetCtlFocus", str)
        End If

end sub

and after this on the page at the end (after the body's end tag) call the same javascript function like below:
<html>
<body>
    ...
</body>
<script language=javascript>
    SetControlfocus();
</script>
</html>

I hope this helps.


setcontrolfocus();
  Not sure why I need to do IsStartupScriptRegistered
tom shad replied to SAM K
26-Jul-07 12:33 PM

Why do I need to do that if I can do:

<script language="JavaScript">
function GetFocus(ctrl)
{
      if (document.getElementById(ctrl) != null)
   {
           document.getElementById(ctrl).focus();
   }
}
...
    Dim a as htmlControl
    a = CType(Page.FindControl("myBody"),htmlControl)
    a.Attributes.Add("onLoad","GetFocus(LoginID:txtUserName);")

also -

I am confused as to why the following doesn't work

    a.Attributes.Add("onLoad","LoginID:txtUserName.focus();")

or

    a.Attributes.Add("onLoad","addFormLoginID:txtUserName.focus();")

(where addForm is the Form Name).

If it is on the same page and not part of the form, this does work:

    a.Attributes.Add("onLoad","addForm.email.focus();")

(Where email is a TextBox on the main page and not in a control)

So the problem seems to be that you can't do an inline focus if the object is part of a control - but you can if it is on the main page.

You can do use focus on an object control if you do it from inside a Javascript function.

Have no idea why.

Thanks,

Tom

  ok let me answer one by one
SAM K replied to tom shad
26-Jul-07 07:24 PM
First thing, you can use the script block which you told me but you are hard coding id of the control. Now, when u use usercontrol its better to pass it through your page. that way in case if u r using multiple instance of the control or u change the textbox id u dont miss to change it on the page.

Secondly, IsStartupScriptRegistered() is basically used to avoid writing duplicate script blocks on page.

and Finally, onLoad is normally used with Body and window. I dont have a specific answer for that but microsoft says that it can be used with APPLET, BODY, EMBED, FRAME, FRAMESET, IFRAME, IMG, LINK, SCRIPT and window elements (http://msdn2.microsoft.com/en-us/library/ms536942.aspx). Although its not working with img at all.

I hope my answers helps you.
  Sounds Good
tom shad replied to SAM K
27-Jul-07 12:16 PM

But the onLoad is used with Body in my case and works textbox is on the page and not in a control.

If in a control it doesn't work - which doesn't make much sense as the textbox (input) is on the page at that point.  Obviously, it is there as it works if the onload calls a function that sets the focus doing exactly the same thing with exactly the same ID as the inline onload statement of the body tag.

Oh well, the subroutine is working fine and I can use it with multiple textboxes using the same code whether it is directly on the page or in a control.

Thanks for explanation,

Tom

Create New Account