📜 ⬆️ ⬇️

ASP.NET 4.0: ClientID Overview

Introduction


One of the innovations in the fourth version of ASP.NET is the ability to control the formation of identifiers of markup elements on the client. Previously, the framework set a unique identifier for each element. This resulted in the identifiers you define being converted to something like this: ctl00_MasterPageBody_ctl01_Textbox1.

Problem


Modifying identifiers on the client side works fine when you need to ensure the uniqueness of identifiers for each element, but working with such identifiers could upset anyone who had to work with client scripts. And if you worked with ASP.NET, then you most likely faced these difficulties. The problem is that during the execution of the script you cannot know exactly what the identifier can be, which makes it difficult to write client scripts. In addition, any modifications to the page, adding or removing controls, can lead to the generation of other identifiers.

Old-style solution


If you worked with ASP.NET for a sufficient time, then you know how to solve the problem described. Each control contains a read-only ClientID property that defines the client identifier for this item. You can use this property in your server code when dynamically adding scripts or, in a more common case, use it in markup code (old ASP style) to implement client-side scripts.
<script type= "text/javascript" >
function DoSomething(){
alert( '<%= Control.ClientID %>' );
}
</script>


* This source code was highlighted with Source Code Highlighter .


Solution in ASP.NET 4.0


First of all, let me explain why we decided to tackle this problem in the fourth version of the framework. The implementation of support for unique identifiers on the client side with the growth of scripts led to the fact that the code contained more and more tweaks. With such a system, there was no normal way to implement the work of many controls with a large number of external script files. In addition, there would have to be some mechanism for the developer to control this system of assigning unique identifiers. Developers love to control everything, whether they need it or not, that is our nature :). The solution we propose contains four modes that a developer can use to have full control over the system of identifiers. The ID property of the controls is modified based on the ClientIDMode mode set, and, accordingly, forms the identifier on the client side.
')

Modes and what they do


For each control (including Page and MasterPage) a new property has been added, called ClientIDMode, which is used to select the mechanism for generating a client ID.
< asp:Label ID ="Label1" runat ="server" ClientIDMode ="[Mode Type]" />

* This source code was highlighted with Source Code Highlighter .


Modes


Examples


Legacy mode


Legacy-mode generates an ID on the client side in the same way as the framework from version 2.0.

markup:
< asp :TextBox ID ="txtEcho" runat ="server" Width ="65%" ClientIDMode ="Legacy" />

* This source code was highlighted with Source Code Highlighter .


result:
< input id ="ctl00_MasterPageBody_ctl00_txtEcho" style ="width: 65%"
name ="ctl00$MasterPageBody$ctl00$txtEcho" />


* This source code was highlighted with Source Code Highlighter .


Static mode


Static mode is the simplest of all ClientIDMode modes, which allows you to get an ID on the client side the same as the ID specified for the server control. Again, you need to be warned that if a static ClientIDMode is used in a control with duplicate elements, then the developer is responsible for the formation of unique identifiers on the client side.

markup:
< asp:TextBox ID ="txtEcho2" runat ="server" Width ="65%" ClientIDMode ="Static" />

* This source code was highlighted with Source Code Highlighter .


result:
< input id ="txtEcho2" style ="width: 65%" name ="ctl00$MasterPageBody$ctl00$txtEcho2" />

* This source code was highlighted with Source Code Highlighter .


Predictable mode


Predictable mode beats right in the heart of the problem. Previously, the framework generated unique IDs to avoid identifiers coinciding, for example, in the most common case - inside controls with binding to data sources. Although the predictable mode is designed for just such moments, it can be used in other cases. To use the predictable mode, there are three options, each of which is specified through the ClientIDRowSuffix property, which indicates which suffix to use for each element. ClientIDRowSuffix uses values ​​from the collection of key fields of the control, so if the control does not contain such a collection, this property will not work. If this property is not set or not available, then the numeric value of the element index will be used for the suffix.

1. ClientIDRowSuffix is ​​not defined, which can be used when the control does not have a collection of key fields, for example for Repeater. Please note that the framework prefixes the elements as ancestor ID, and the suffix as a simple ordinal value.

markup:
< 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 >


* This source code was highlighted with Source Code Highlighter .


result:
< 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 >


* This source code was highlighted with Source Code Highlighter .


2. ClientIDRowSuffix is ​​specified; in this case, the values ​​of key fields are searched for suffix values.
markup:
< asp:GridView ID ="EmployeesSuffix" runat ="server" AutoGenerateColumns ="false"
ClientIDMode ="Predictable" ClientIDRowSuffix ="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 >


* This source code was highlighted with Source Code Highlighter .


result:
< 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 >


* This source code was highlighted with Source Code Highlighter .


3. ClientIDRowSuffix is ​​specified, but several values ​​are specified instead of one. Causes the suffix to consist of several values.
markup:
< asp:GridView ID ="EmployeesCompSuffix" runat ="server" AutoGenerateColumns ="false"
ClientIDMode ="Predictable" ClientIDRowSuffix ="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 >


* This source code was highlighted with Source Code Highlighter .


result:
< 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 >


* This source code was highlighted with Source Code Highlighter .


Conclusion


The ability to fully control the generation of identifiers on the client side is an opportunity that everyone wanted. We are sure that we have found a good solution and we think that it will add to the developers the necessary functionality that is needed to create a large amount of client code. A preliminary version is available at this CTP , which was presented at PDC 2008. For more information and a more detailed description read this post by Scott Galloway.

Source: https://habr.com/ru/post/48570/


All Articles