Click here to Skip to main content
15,860,943 members
Articles / Web Development / HTML

ASP.NET 4.0 Client ID Feature

Rate me:
Please Sign up or sign in to vote.
4.41/5 (16 votes)
15 Mar 2009CPOL5 min read 197.5K   20   12
This article shows ASP.NET 4.0 ClientID feature and its related properties for client side development.

Introduction

This article will focus on a new feature added in ASP.NET Framework 4.0. More efforts have been put to make client side development model much easier and increase productivity. When it comes to the client side, we all know about ClientID which gives us a unique ClientID of control to refer on the client side. But so far it was read-only (you cannot set it in code). The clientID you get on the client side is something like this ctl00_MasterPageBody_ctl01_Textbox1, let's say where ctl00 is content id of content placeholder on master page, etc. Basically it inherits outer control’s id from parent control or place holders and generates a unique id.

Background About the Problem and Solution

Problem

The ClientID property works great to ensure that each element is uniquely identified. But when you do the client side scripting, it becomes much more difficult and you run into the issue in ASP.NET because until runtime you do not know what the client side ID would be, making it difficult to do any kind of client side scripting. In addition any modification of the page, adding removing controls, can result in a different client side ID being generated.

Solution

In the ASP.NET versions we have so far, there is a workaround for this issue. Each control has a property called ClientID that is a read only and supplies the unique client side ID. You can use this in a code behind when dynamically adding scripts or more commonly use inline code to supply the value to client side scripts.

JavaScript
<script type="text/javascript">
function DoSomething() 
{
   alert('<%= Control.ClientID %>');
}
</script>

If you move the control or make the control as a user control, ClientID property you get at client side keeps changing ctl00_MasterPageBody_ctl01_Textbox1 and sometimes we do need to refer to the control using this uniquely generated id (mostly we hard-code the values :) take it easy dude.).

Now Look at ASP.NET 4.0 Solution

ASP.NET 4.0 has the new feature for client side Id which you can set in code and other properties at design time and make use of them at run-time in client side development.

ASP.NET 4.0 has defined a new property on ASP.NET control named ClientIDMode. Once you set the ClientIDMode property for a control, the ClientID is modified accordingly and then used as the client side id. You can even set ClientID property on the control itself.

The cool thing about this property is that, you define it at control level or page level or application level (in web.config file).

So now look at what the Client ID Modes are and what they do.

There is now a new property on every control (this includes pages and master pages as they inherit from control) called ClientIDMode that is used to select the behavior of the client side ID. ClientIDMode supports the Mode Types given below.

Static

This is most basic, simple mode and it makes the client side ID static. Whatever value you put for the ClientID or ID is that which will be used for the client side ID. One odd condition here, if a static ClientIDMode is used in a repeating control, the developer is responsible for ensuring client side ID uniqueness. Below is the code example:

ASP.NET
Markup: <asp:TextBox ID="txtEcho2" runat="server" ClientIDMode="Static" /> 
Output: <input id="Text1" name="ctl00$MasterPageBody$ctl00$txtEcho2" />

Setting a ClientID property separates the server side and client side ids. You will have client id for client side development which makes code much easier and clean.

ASP.NET
Markup: <asp:TextBox ID="TextBox1" ClientID=""Echo"" runat="server" 
	ClientIDMode="Static" /> 
Output: <input id="Text2" name="Echo" />

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. Below is a code example:

ASP.NET
Markup: <asp :TextBox ID ="txtEcho" runat ="server" ClientIDMode ="Legacy" />

Output: <input id="ctl00_MasterPageBody_ctl00_txtEcho" 
	name="ctl00$MasterPageBody$ctl00$txtEcho" />

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 control's parent.

Predictable

The above mode works well if you have only a single control but what happens when it comes to databound controls where you will have different controls inside the control. For example, let's say, repeater control.

What this mode does is, it says render out the client id followed by some type of predictable suffix but still unique enough to make each individual item different from each other.

This mode is commonly used on databound controls and this mode is used when the framework needs to ensure uniqueness. The framework will traverse the control hierarchy prefixing the supplied ID with its 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. Below is a code example:

Markup
ASP.NET
<asp:GridView ID="EmployeesNoSuffix" runat="server" 
	AutoGenerateColumns="false" ClientIDMode="Predictable">
<Columns>
    <asp:TemplateField HeaderText="ID">
         <ItemTemplate>
              <asp:Label ID="EmployeeID" runat="server" Text='<%# Eval("ID") %>' />
         </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Name">
         <ItemTemplate>
              <asp:Label ID="EmployeeName" 
		runat="server" Text='<%# Eval("Name") %>' />
         </ItemTemplate>
    </asp:TemplateField>
</Columns>
</asp:GridView>
Output
ASP.NET
<table id="EmployeesNoSuffix" style="border-collapse: collapse" 
	cellspacing="0" rules="all" border="1">
  <tbody>
    <tr>
       <th scope="col">ID</th>
       <th scope="col">Name</th>
    </tr>
    <tr>
       <td><span id="EmployeesNoSuffix_EmployeeID_0">1</span></td>
       <td><span id="EmployeesNoSuffix_EmployeeName_0">EmployeeName1</span></td>
    </tr>
    ...
    <tr>
      <td>
         <span id="EmployeesNoSuffix_EmployeeID_8">9</span>
      </td>
      <td>
         <span id="EmployeesNoSuffix_EmployeeName_8">EmployeeName9</span>
      </td>
    </tr>
  </tbody>
</table>

Another useful property RowClientIDSuffix is used to generate client side ids for bound control in user friendly manner and with a RowClientIDSuffix defined. This looks in the control’s datakeys collection for the value and then suffixes the ID with that value.

Markup
ASP.NET
<asp:GridView ID="EmployeesSuffix" runat="server" 
	AutoGenerateColumns="false" 
		ClientIDMode="Predictable" RowClientIDSuffix="ID">
  <Columns>
      <asp:TemplateField HeaderText="ID">
         <ItemTemplate>
            <asp:Label ID="EmployeeID" runat="server" Text='<%# Eval("ID") %>' />
         </ItemTemplate>
      </asp:TemplateField>
      <asp:TemplateField HeaderText="Name">
         <ItemTemplate>
            <asp:Label ID="EmployeeName" runat="server" Text='<%# Eval("Name") %>' />
         </ItemTemplate>
      </asp:TemplateField>
   </Columns>
</asp:GridView>
Output
HTML
<table id="EmployeesSuffix" style="border-collapse: collapse" 
	cellspacing="0" rules="all" border="1">
   <tbody>
      <tr>
          <th scope="col">ID</th>
          <th scope="col">Name</th>
      </tr>
      <tr>
          <td>
             <span id="EmployeesSuffix_EmployeeID_1">1</span>
          </td>
          <td>
             <span id="EmployeesSuffix_EmployeeName_1">EmployeeName1</span>
          </td>
      </tr>
      ...
      <tr>
          <td>
             <span id="EmployeesSuffix_EmployeeID_9">9</span>
          </td>
          <td>
             <span id="EmployeesSuffix_EmployeeName_9">EmployeeName9</span>
          </td>
      </tr>
   </tbody>
</table>

With a RowClientIDSuffix defined, but instead of just one value, a compound value will be used. Exhibits the same behavior as one value but it will suffix both values onto the ID.

Markup
ASP.NET
<asp:GridView ID="EmployeesCompSuffix" runat="server" AutoGenerateColumns="false" 
	ClientIDMode="Predictable" RowClientIDSuffix="ID, Name">
    <Columns>
          <asp:TemplateField HeaderText="ID">
               <ItemTemplate>
                    <asp:Label ID="EmployeeID" runat="server" 
			Text='<%# Eval("ID") %>' />
              </ItemTemplate>

         </asp:TemplateField>

        <asp:TemplateField HeaderText="Name">
             <ItemTemplate>
                   <asp:Label ID="EmployeeName" 
			runat="server" Text='<%# Eval("Name") %>' />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>
Output
HTML
<table id="EmployeesCompSuffix" style="border-collapse: collapse" 
			cellspacing="0" rules="all" border="1">
     <tbody>
         <tr>
               <th scope="col">ID</th>
               <th scope="col">Name</th>
         </tr>
         <tr>
             <td>
                 <span id="EmployeesCompSuffix_EmployeeID_1_EmployeeName1">1</span>
             </td>
             <td>
                 <span id="EmployeesCompSuffix_EmployeeName_1_EmployeeName1">
			EmployeeName1</span>
             </td>
          </tr>
          ..
          <tr>
              <td>
                 <span id="EmployeesCompSuffix_EmployeeID_9_EmployeeName9">9</span>
              </td>
              <td>
                 <span id="EmployeesCompSuffix_EmployeeName_9_EmployeeName9">
			EmployeeName9</span>
              </td>
          </tr>
     </tbody>
</table>

Please share your thoughts and valuable suggestions. Thanks!

Reference

History

  • 15th March, 2009: Initial post 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
Sachin has been developing software professionally for more than five years. Mostly working with .NET Framework 3.5/3.0/2.0/1.x, Windows Communication Foundation (WCF), Windows Presentation Foundation (WPF)\Smart Client, ASP.NET 3.5/2.0/1.x (WebForm), XAML, ASP.NET AJAX 1.0, C# (3.0), LINQ, VB.NET, ADO.NET, WinForm, Web Services, MS Sync Framework, Window Services, UI Automation Framework, SQL Server and good experience in agile/scrum development methodology.

Comments and Discussions

 
QuestionClientID attribute not coming Pin
vaishali choudhary3-Jun-14 19:30
vaishali choudhary3-Jun-14 19:30 
GeneralMy vote of 4 Pin
devbrat20-Nov-12 19:56
devbrat20-Nov-12 19:56 
Questionhttp://weblogs.asp.net/asptest/archive/2009/01/06/asp-net-4-0-clientid-overview.aspx Pin
Member 811109122-May-12 6:12
Member 811109122-May-12 6:12 
Generalmany thanks Pin
Sim_Card17-Apr-12 1:19
Sim_Card17-Apr-12 1:19 
GeneralMy vote of 1 Pin
kalpesh2917-Nov-09 23:40
kalpesh2917-Nov-09 23:40 
GeneralLong waited feature.... finally implemented! Pin
Sandeep Aparajit23-Apr-09 22:58
Sandeep Aparajit23-Apr-09 22:58 
GeneralGreat [modified] Pin
Talking Dotnet18-Mar-09 21:04
Talking Dotnet18-Mar-09 21:04 
Generalnice and simple Pin
Andre Sanches (alvs)16-Mar-09 14:28
Andre Sanches (alvs)16-Mar-09 14:28 
GeneralThanks! Pin
CCMint16-Mar-09 5:44
CCMint16-Mar-09 5:44 
GeneralRe: Thanks! Pin
Saki Sachin16-Mar-09 10:53
Saki Sachin16-Mar-09 10:53 
GeneralCool feature! Pin
Sohel_Rana16-Mar-09 2:09
Sohel_Rana16-Mar-09 2:09 
GeneralRe: Cool feature! Pin
Saki Sachin16-Mar-09 10:54
Saki Sachin16-Mar-09 10:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.