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
