If you're using ASP.NET 4.0, you can use ClientIDMode="static" or 
ClientIDMode="predictable"
http://weblogs.asp.net/asptest/archive/2009/01/06/asp-net-4-0-clientid-overview.aspx

<asp:Label ID="Label1" runat="server" ClientIDMode="[Mode Type]" />
The Mode Types

  *   Legacy: The default value if ClientIDMode is not set anywhere in the 
control hierarchy. This causes client side IDs to behave the way they did in 
version 2.0 (3.0 and 3.5 did not change this code path) of the framework. This 
mode will generate an ID similar to "ctl00_MasterPageBody_ctl01_Textbox1."
  *   Inherit: This is the default behavior for every control. This looks to 
the controls parent to get its value for ClientIDMode. You do not need to set 
this on every control as it is the default, this is used only when the 
ClientIDMode has been changed and the new desired behavior is to inherit from 
the controls parent.
  *   Static: This mode does exactly what you think it would, it makes the 
client side ID static. Meaning that what you put for the ID is what will be 
used for the client side ID. Warning, this means that if a static ClientIDMode 
is used in a repeating control the developer is responsible for ensuring client 
side ID uniqueness.
  *   Predictable: This mode is used when the framework needs to ensure 
uniqueness but it needs to be done so in a predictable way. The most common use 
for this mode is on databound controls. The framework will traverse the control 
hierarchy prefixing the supplied ID with it's parent control ID until it 
reaches a control in the hierarchy whose ClientIDMode is defined as static. In 
the event that the control is placed inside a databound control a suffix with a 
value that identifies that instance will also be added to the supplied ID. The 
ClientIDRowSuffix property is used to control the value that will be used as a 
suffix (see samples). This mode will generate an ID similar to 
"Gridview1_Label1_0"


From: [email protected] [mailto:[email protected]] On 
Behalf Of David Walker
Sent: Thursday, 5 January 2012 2:15 PM
To: ozDotNet
Subject: Re: getElementById failing (sort of solved)

I think its' all to do with the INamingContainer that it belongs to inferring a 
name for it. Someone else suggested predictablenames which sounds like what you 
want.

On 5 Jan 2012, at 02:14, Greg Keogh wrote:


>Havent' done ASP.Net<http://ASP.Net> for a while but could you try do it later 
>than you are - pre_render or something.

You're right !!! Page_Load is too early ... well ... I suppose it is, but the 
symptoms of getting mismatching ClientIDs is quite frightening and misleading. 
I moved the register script call to  before base.OnPreRender in the vague hope 
that the IDs would be "stable" by them.

At the same time I changed my code. Instead of smartly enabling the save button 
as the text changes, I dumbly block save on click if the text is empty. This is 
not as elegant, but still acceptable for live use. The old code had a bug where 
the state of the button was incorrect when the page first loaded and I couldn't 
figure out how to fire the script on load to set the initial state correctly, 
that wasted another 30 minutes. The working code now looks like this:

Page.ClientScript.RegisterStartupScript(GetType(), "s3",
            string.Format(@"function CheckNote()
{{
    var text = document.getElementById('{0}');
    if (text.value == '')
    {{
        alert('You cannot save a blank message.');
        return false;
    }}
    else
    {{
        return true;
    }}
}}", textNote.ClientID), true);
        btnConSave.Attributes["onClick"] = "return CheckNote();";

I also found that using <%=textNote.ClientID%> does not work in the get.

So there you go, I've spent 2 and a half hours this morning trying to make this 
work. Why does it have to be so hard?

Greg

Reply via email to