Read only if you want to invest in your deep knowledge of technology.
This Guest Post is by Arjun Marwaha. Arjun graduated with a Technology degree from Kurukshetra University in 2005. Since then he has worked with some of the leading software development companies in India. In his spare time Arjun enjoys basketball, watching movies and listening to techno music. I have had the pleasure of working with Arjun for several years in my day-job.
One of the new features of .NET Framework 4 and ASP.NET 4 is related to the handling of the client Id of the controls generated by the ASP.NET. With this new feature, the client Id’s can be more cleanly handled and also provides some level of control to the user to decide how the client Id’s would be generated.
Up to now we only had ClientId property which gave us the Unique Id of the control to be referred at client side. However this Id generated is very long and unpredictable which made life tough for developers doing client side programming. Also the Ids were generated based on their location in the control hierarchy. So if they were moved around or any modification on the page, the Ids would change and thereby break the Javascript code written based on them.
With ASP.NET 4.0, a new property “ClientIdMode” has been introduced which gives control to the developer upon the ID generation of the control and generate much cleaner HTML markup.
This property can be set at:
- Control Level: This sets the ClientIdMode property for individual controls.
<asp:panel id=”pnl” runat=”server” cssclass=”newStyle1″ ClientIDMode=”Static”> </asp:panel>
- Page Level: Use this to set the CLientIdMode property for all the controls on the page.
<%@ Page Language=”C#” ClientIDMode =”Inherit” AutoEventWireup=”true” CodeBehind=”Default.aspx.cs” Inherits=”WebApplication3.Cat” %>
- Application Level (Web.Config): This sets the ClientIdMode for all the controls throughout the application.
<system.web>
<pages ClientIDMode=”Predictable”>
</pages>
</system.web>
The ClientIdMode property has 4 Mode Types to select for the Id generation.
For further explanation, let’s take an example.
<asp:Content ID=”Content2″ ContentPlaceHolderID=”ContentPlaceHolder1″ Runat=”Server”>
<asp:Panel ID=”Panel1″ runat=”server”>
<asp:TextBox ID=”TextBox1″ runat=”server”></asp:TextBox>
</asp:Panel>
</asp:Content>
ClientIDMode=”AutoId”
This is the same algorithm used in ASP.Net 2.0. In the above example, set the ClientIdMode for the “TextBox” to AutoId.
<asp:TextBox ID=”TextBox1″ runat=”server” ClientIDMode=”AutoID”></asp:TextBox>
The output HTML would look like:
<input name=”ctl00$ContentPlaceHolder1$TextBox1″ type=”text” id=”ctl00_ContentPlaceHolder1_TextBox1″ />
You can see the ID of the control is modified to refer the ContentPlaceHolder name with an AutoId just before the Id. AutoId mode is best when you don’t want to handle the uniqueness of the control id yourself and want to rely totally on ASP.NET.
ClientIDMode=”Static”
It makes the ClientId static. In other words, whatever the developer enters for the ID that will be used as is for the ClientId. So the output HTML in case of “Static” would be
<input name=”ctl00$ContentPlaceHolder1$TextBox1″ type=”text” id=”Text1″ />
This mode comes in handy when we do not want to change the ID of the controls on clientside. However the uniqueness of the ID would not be taken care by ASP.Net; in fact is the responsibility of the developer.
ClientIDMode=”Predictable”
This is primarily for data controls like Repeater, GridView etc. It concatenates the ID property of the control’s naming container however the ID would not have strings like “ctlxxx” prefixed. As databound controls generate multiple rows, a sequential number will be suffixed with the ClientId for uniqueness. This suffix/sequential number can be controlled using the ClientIdRowSuffix property of the control. For example, we can set the ClientIdRowSuffix property to the name of a data field which would be used as a suffix. The default value is suffix value if ClientIdRowSuffix property is not specified is 0.
For Predictable mode, if the markup is
<asp:ListView runat=”server” ID=”lvwDemo” ClientIDMode=”Predictable”>
<LayoutTemplate>
<table>
<asp:PlaceHolder runat=”server” ID=”itemPlaceholder” />
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Label runat=”server” ID=”lblItemName” Text=’<%#Eval(“Name”) %>‘ />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
With no ClientIdRowSuffix defined, the output would be:
<tr>
<td>
<span id=”ContentPlaceHolder1_lvwDemo_lblItemName_0″>Cat</span>
</td>
</tr>
<tr>
<td>
<span id=”ContentPlaceHolder1_lvwDemo_lblItemName_1″>Dog</span>
</td>
</tr>
In the above output, note that the auto incremented number is used to create the unique Ids. Now let’s say I want to use a data field to make it more meaningful. In that I case the ClientIdRowSuffix property would be used as shown below.
<asp:ListView runat=”server” ID=”lvwDemo” ClientIDMode=”Predictable” ClientIDRowSuffix=”Id”>
With this change, the output HTML would be
<tr>
<td>
<span id=”ContentPlaceHolder1_lvwDemo_lblItemName_11″>Cat</span>
</td>
</tr>
<tr>
<td>
<span id=”ContentPlaceHolder1_lvwDemo_lblItemName_12″>Dog</span>
</td>
</tr>
If we see the output, the Id is still somewhat long. We can shorten the ClientId of the child controls with a few permutations.
Set the ClientIdMode for the parent to “Static” and for Child to “Predictable”.
<asp:ListView runat=”server” ID=”lvwDemo” ClientIDMode=”Static” ClientIDRowSuffix=”Id”>
<LayoutTemplate>
<table>
<asp:PlaceHolder runat=”server” ID=”itemPlaceholder” />
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Label runat=”server” ID=”lblItemName” Text=’<%#Eval(“Name”) %>‘ ClientIDMode=”Predictable” />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
The output would then be:
<tr>
<td>
<span id=”ctrl0_lblItemName_11″>Cat</span>
</td>
</tr>
<tr>
<td>
<span id=” ctrl0_lblItemName_12″>Dog</span>
</td>
</tr>
ClientIDMode=”Inherit”
When using this algorithm, the control inherits the ClientIdMode property of its “Naming container” and not the parent container.
ASP.NET Markup:
<asp:Content ID=”Content2″ ContentPlaceHolderID=”ContentPlaceHolder1″ Runat=”Server” ClientIDMode=”Static”>
<asp:Panel ID=”Panel1″ runat=”server” ClientIDMode=”Predictable”>
<asp:TextBox ID=”txtName” runat=”server” Text=”Textbox one” ClientIDMode=”Inherit” />
</asp:Panel>
</asp:Content>
The output would be:
<input name=”ctl00$ContentPlaceHolder1$txtName” type=”text” value=”Textbox one” id=”Text2″ />
The Inherit algorithm is a bit trickier than others and the documentation is slightly misleading. As per the documentation, “The control inherits the ClientIDMode setting of its parent control”. However if we see in the above example, the control derives its Id from the “Naming Container” i.e. “ContentPlaceHolder1”. As the ClientIdMode for “ContentPlaceHolder1” is set to Static and for the TextBox it is “Inherit”; the TextBox inherits the mode from the “ContentPlaceHolder1” and have the same ClientId as in markup i.e. “txtName”.

Good info! Someone was telling me that you are an ace Flash programmer too.