how to set Client IDs in asp.net 4.0
The new ClientIDMode property addresses a long-standing issue in ASP.NET, namely how controls create the id attribute for elements that they render. Knowing the id attribute for rendered elements is important if your application includes client script that references these elements.
The id attribute in HTML that is rendered for Web server controls is generated based on the ClientID property of the control. The algorithm up to now for generating the id attribute from the ClientID property has been to concatenate the naming container (if any) with the ID, and in the case of repeated controls (as in data controls), to add a prefix and a sequential number. While this has always guaranteed that the IDs of controls in the page are unique, the algorithm has resulted in control IDs that were not predictable, and were therefore difficult to reference in client script.
The new ClientIDMode property lets you specify more precisely how the client ID is generated for controls. You can set the ClientIDMode property for any control, including for the page. Possible settings are the following:
· AutoID – This is equivalent to the algorithm for generating ClientID property values that was used in earlier versions of ASP.NET.
· Static – This specifies that the ClientID value will be the same as the ID without concatenating the IDs of parent naming containers. This can be useful in Web user controls. Because a Web user control can be located on different pages and in different container controls, it can be difficult to write client script for controls that use the AutoID algorithm because you cannot predict what the ID values will be.
· Predictable – This option is primarily for use in data controls that use repeating templates. It concatenates the ID properties of the control's naming containers, but generated ClientID values do not contain strings like "ctlxxx". This setting works in conjunction with the ClientIDRowSuffix property of the control. You set the ClientIDRowSuffix property to the name of a data field, and the value of that field is used as the suffix for the generated ClientID value. Typically you would use the primary key of a data record as the ClientIDRowSuffix value.
· Inherit – This setting is the default behavior for controls; it specifies that a control's ID generation is the same as its parent.
You can set the ClientIDMode property at the page level. This defines the default ClientIDMode value for all controls in the current page.
The default ClientIDMode value at the page level is AutoID, and the default ClientIDMode value at the control level is Inherit. As a result, if you do not set this property anywhere in your code all controls will default to the AutoID algorithm.
You set the page-level value in the @ Page directive, as shown in the following example:
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs"
Inherits="_Default"
ClientIDMode="Predictable" %>
You can also set the ClientIDMode value in the configuration file, either at the machine level or at the application level. This defines the default ClientIDMode setting for all controls in all pages in the application. If you set the value at the machine level, it defines the default ClientIDMode setting for all Web sites on that computer. The following example shows the ClientIDMode setting in the configuration file:
<system.web>
<pages clientIDMode="Predictable"></pages>
</system.web>
As noted earlier, the value of the ClientID property is derived from the naming container for a control’s parent. In some scenarios, such as when you are using master pages, controls can end up with IDs like those in the following rendered HTML:
<div id="ctl00_ContentPlaceHolder1_ParentPanel">
<div id="ctl00_ContentPlaceHolder1_ParentPanel_NamingPanel1">
<input name="ctl00$ContentPlaceHolder1$ParentPanel$NamingPanel1$TextBox1"
type="text" value="Hello!"
id="ctl00_ContentPlaceHolder1_ParentPanel_NamingPanel1_TextBox1" />
</div>
Even though the input element (from a TextBox control) shown in the markup is only two naming containers deep in the page (the nested ContentPlaceholder controls), because of the way master pages are processed, the end result is a control ID like the following:
ctl00_ContentPlaceHolder1_ParentPanel_NamingPanel1_TextBox1
This is a long ID. It is guaranteed to be unique in the page, but is unnecessarily long for most purposes. Imagine that you want to reduce the length of the rendered ID, and to have more say in how the ID is generated (for example, you want to eliminate “ctlxxx” prefixes). The easiest way to achieve this is by setting the ClientIDMode property as shown in the following example:
<tc:NamingPanel runat="server" ID="ParentPanel" ClientIDMode="Static">
<tc:NamingPanel runat="server" ID="NamingPanel1" ClientIDMode="Predictable">
<asp:TextBox ID="TextBox1" runat="server" Text="Hello!"></asp:TextBox>
</tc:NamingPanel>
</tc:NamingPanel>
In this sample, the ClientIDMode property is set to Static for the outermost NamingPanel element, and set to Predictable for the inner NamingControl element. These settings result in the following markup (the rest of the page and the master page is assumed to be the same as in the previous example):
<div id="ParentPanel">
<div id="ParentPanel_NamingPanel1">
<input name="ctl00$ContentPlaceHolder1$ParentPanel$NamingPanel1$TextBox1"
type="text" value="Hello!" id="ParentPanel_NamingPanel1_TextBox1" />
</div>
The Static setting has the effect of resetting the naming hierarchy for any controls inside the outermost NamingPanel element, and of eliminating the ContentPlaceHolder and MasterPage IDs from the generated ID. (Note that the name attribute of rendered elements is unaffected, so that the normal ASP.NET functionality is retained for events, view state, and so on.) A nice side effect of resetting the naming hierarchy is that even if you move the markup for the NamingPanel elements to a different ContentPlaceholder control, the rendered client IDs remain the same.
Note It is up to you to make sure that the rendered control IDs are unique. If they are not, it can break any functionality that requires unique IDs for individual HTML elements, such as the client document.getElementById function.
Creating Predictable Client IDs in Data-Bound Controls
The ClientID values that are generated for controls in a data-bound list control by the legacy algorithm can be long and are not really predictable. The ClientIDMode functionality can help you have more control over how these IDs are generated.
Look at the following markup, which includes a ListView control:
<asp:ListView ID="ListView1" runat="server" DataSourceID="SqlDataSource1"
OnSelectedIndexChanged="ListView1_SelectedIndexChanged"
ClientIDMode="Predictable"
RowClientIDRowSuffix="ProductID">
</asp:ListView>
In the previous example, the ClientIDMode and RowClientIDRowSuffix properties are set in markup. The ClientIDRowSuffix property can be used only in data-bound controls, and its behavior differs depending on which control you are using. The differences are these:
· GridView control — You can specify the name of one or more columns in the data source, which are combined at run time to create the client IDs. For example, if you set RowClientIDRowSuffix to “ProductName, ProductId”, control IDs for rendered elements will have a format like the following:
rootPanel_GridView1_ProductNameLabel_Chai_1
· ListView control — You can specify a single column in the data source that is appended to the client ID. For example, if you set ClientIDRowSuffix to “ProductName”, the rendered control IDs will have a format like the following:
rootPanel_ListView1_ProductNameLabel_1
In this case the trailing 1 is derived from the product ID of the current data item.
· Repeater control— This control does not support the ClientIDRowSuffix property. In a Repeater control, the index of the current row is used. When you use ClientIDMode="Predictable" with a Repeater control, client IDs are generated that have the following format:
Repeater1_ProductNameLabel_0
The trailing 0 is the index of the current row.
The FormView and DetailsView controls do not display multiple rows, so they do not support the ClientIDRowSuffix property.
Posted in: asp.net | Tags: asp.net 4.0 clientid static clientidrowsuffix clientidmode parentpanel autoeventwireup predictable