ASP .NET 4.0 - Usando o Web Control ClientIDMode
Em ASP.NET, cada controle web é identificado exclusivamente através da propriedade 'ID' do controle. Assim podemos acessar os controles de servidor no code-behind usando esta propriedade 'ID'. No entanto, quando o formulário web com os controles do lado do servidor é renderizado para HTML, o ID do lado do servidor é convertido em ID lado do cliente.
Ocorre que para os desenvolvedores do lado do cliente, torna-se difícil acessar os elementos HTML usando JavaScript pois a propriedade 'ID' é gerada em tempo de execução e não é conhecida em tempo de projeto. Embora você possa usar expressões para acessá-los, o código não fica muito legível.
Temos assim um problema com o qual o desenvolvedor tem que lidar e sobre o qual ele não tem muito o que fazer.
Felizmente na versão 4.0 da ASP .NET a Microsoft alterou esta situação e deu aos desenvolvedores o controle para processar o ID do lado do cliente para os controles de servidor, através da introdução de uma nova propriedade chamada 'ClientIDMode' .
A propriedade ClientIDMode obtém ou define um algoritmo usado para gerar o valor da propriedade ClientID para o controle. Em outras palavras, esta propriedade determina como o controle será renderizado.
Abaixo temos as opções de algoritmos usados para renderizar o ID do lado do servidor para o cliente:
AutoID | O valor ClientID é gerado pela concatenação do ID pai dos valores de cada contêiner de nomeação com o valor do ID do controle. Em cenários de ligação de dados, onde várias instâncias de um controle são processadas, um valor de incremento é inserido na frente do valor ID do controle. Cada segmento é separado por um caractere de sublinhado (_). Esse algoritmo foi usado em versões do ASP.NET anteriores ao ASP.NET 4. |
Static | O valor do ClientID é definido como o valor da propriedade ID. Se o controle for um contêiner de nomeação, o controle é usado como o topo da hierarquia de recipientes de nomenclatura para todos os controles que ele contém. |
Predictable | È usado para controles de de dados vinculados. O o valor do ClientID é gerado pela concatenação do valor do ClientID do contêiner de nomeação pai com o valor do ID do controle. Se o controle é um controle dados vinculado que gera várias linhas, o valor do campo de dados especificado na propriedade ClientIDRowSuffix é adicionado no final. |
Inherit | O controle herda o ClientIDMode da configuração de seu controle pai. Nesta opção o ClientID será gerado da mesma forma que o ParentID. Ex: Se o ParentID é 'MainContent' então o TextBox 'txtNomeID' será nomeado como 'MainContent_txtNomeID' |
Vamos agora mostrar alguns exemplos de como usar este recurso em aplicações ASP .NET usando o Visual Web Developer 2010 Express Edition.
Abra o Visual Web Developer 2010 Express Edition e no menu File clique em New Web Site;
A seguir selecione a linguagem Visual Basic e o template ASP .NET Web Site, informe o nome ASPNET_ClientID e clique em OK;
Vamos incluir 1 novo Web Form em nosso web site da seguinte forma:
No menu Web Site clique em Add New Item e selecione o template Web Form e informe o nome AutoID.aspx e selecione os itens: Place code in separate file e Select master page e clique em Add;
A seguir selecione a master page e clique no botão OK;
Vamos iniciar com o Web Form AutoID.aspx:
Selecione a página AutoID.aspx e no menu Table -> Insert Table inclua uma tabela com 6 Linhas e 2 colunas;
A seguir inclua os controles Label e TextBox conforme o leiaute abaixo:
Definição dos ID
controles TextBox :
|
O código da página AutoID.aspx deve ser o seguinte:
<%@ Page Title="" Language="VB" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="AutoID.aspx.vb" Inherits="AutoID" %> <asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" Runat="Server"> <style type="text/css"> .style1{width: 100%;} </style> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server"> <script type="text/javascript" language="javascript"> document.writeln('<% =txtNome.ClientID %>' + '<br>'); document.writeln('<% =txtEmail.ClientID %>' + '<br>'); document.writeln('<% =txtCidade.ClientID %>' + '<br>'); document.writeln('<% =txtPais.ClientID %>' + '<br>'); function getValor() { var txt_Email = document.getElementById('<% =txtEmail.ClientID %>'); alert(txt_Email.value) } </script> <table class="style1"> <tr> <td> </td> <td> </td> </tr> <tr> <td bgcolor="#0099FF" colspan="2"> </td> </tr> <tr> <td>Nome</td> <td><asp:TextBox ID="txtNome" runat="server" ClientIDMode="AutoID" height="22px" width="253px"></asp:TextBox></td> </tr> <tr> <td>Email</td> <td><asp:TextBox ID="txtEmail" runat="server" ClientIDMode="Static" Width="253px"></asp:TextBox></td> </tr> <tr> <td>Cidade</td> <td><asp:TextBox ID="txtCidade" runat="server" ClientIDMode="Inherit" height="22px" width="199px"></asp:TextBox></td> </tr> <tr> <td>Pais</td> <td><asp:TextBox ID="txtPais" runat="server" ClientIDMode="Static" Width="199px"></asp:TextBox></td> </tr> <tr> <td> </td> <td><asp:Button ID="btnEnviar" runat="server" Text="Enviar" OnClientClick="getValor()" Width="111px" /></td> </tr> </table> </asp:Content> |
O código da página define o código para escrever no documento o nome dos controles:
document.writeln('<%
=txtNome.ClientID %>' + '<br>');
document.writeln('<% =txtEmail.ClientID %>' +
'<br>');
document.writeln('<% =txtCidade.ClientID %>' +
'<br>');
document.writeln('<% =txtPais.ClientID %>' + '<br>');
A seguir definimos uma função JavaScript chamada getValor que irá obter o valor do controle txtEmail.ClientID e irá exibi-lo em uma caixa de alerta quando o botão Submeter for clicado pelo usuário:
function
getValor() {
var txt_Email =
document.getElementById('<% =txtEmail.ClientID %>');
alert(txt_Email.value)
}
Observe que em cada definição de controle TextBox definimos a propriedade ClienteIDMode da seguinte forma:
Ao executar esta página e clicar no botão Submeter iremos obter o seguinte resultado:
Vemos a exibição dos nomes dos controles após sua renderização para o cliente notando a diferença nos nomes quando a propriedade é definida como AutoID e Static e Inherit;
Ao clicar no botão Submeter a função getValor() obtém o valor do controle txtEmail usando o código javascript: document.getElementById('<% =txtEmail.ClientID %>');
O ClientIDMode Predictable é útil quando usamos os controles de dados vinculados que renderiza mais do que um controle com o mesmo ID. Nestes casos usando Predictable podemos prever o id que o controle irá gerar quando renderizados do lado do cliente.
Vejamos um exemplo com o controle ListView onde usamos um XmlDataSource para definir os dados.
Vamos definir na página Default.aspx o seguinte leiaute e código:
O código fonte definido no modo Design pode ser visto abaixo:
<%@ Page Title="Home Page" Language="VB" MasterPageFile="~/Site.Master" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %> <asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent"> </asp:Content> <asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent"> <p> <asp:XmlDataSource ID="xdsTimes" runat="server"> <Data> <Times> <time id="1" nome="São Paulo" /> <time id="2" nome="Vasco" /> <time id="3" nome="Botafogo" /> <time id="4" nome="Corinthians" /> </Times> </Data> </asp:XmlDataSource> </p> <asp:ListView runat="server" ID="lvMostraNomes" DataSourceID="xdsTimes" ClientIDMode="Predictable" style="color: #0033CC; font-size: large; font-weight: 700"> <ItemTemplate> <asp:Label runat="server" Text='<%# Eval("nome") %>' ID="lblTimeNome"/> <br> </br> </ItemTemplate> </asp:ListView> </asp:Content> |
Como eu defini o ClientIDmode como Predictable , o span que será renderizado no lado do cliente será assim:
<span id="MainContent_lvMostraNomes_lblTimeNome_0">São Paulo</span> <span id="MainContent_lvMostraNomes_lblTimeNome_1">Vasco</span> <span id="MainContent_lvMostraNomes_lblTimeNome_2">Botafogo</span> <span id="MainContent_lvMostraNomes_lblTimeNome_3">Corinthians</span> |
Portanto, você pode ver os ids serão gerados. Ele possui 4 partes (cada uma separada utilizando sublinhados). :
Se você quiser renderizar o sufixo com o mesmo id de cada controle pode usar uma propriedade chamada ClientIDRowSuffix para cada controle vinculado que habilita a usar o próprio sufixo para cada controle.
Para o nosso exemplo basta alterar o código para o ListView conforme abaixo:
<asp:ListView runat="server" ID="lvMostraNomes" DataSourceID="xdsTimes" ClientIDRowSuffix="id" style="color: #0033CC; font-size: large; font-weight: 700"> <ItemTemplate> <asp:Label runat="server" Text='<%# Eval("nome") %>' ID="lblTimeNome"/> <br> </br> </ItemTemplate> </asp:ListView> </asp:Content> |
Após executar o html renderizado deverá ter o seguinte aspecto:
<span id="MainContent_lvMostraNomes_lblTimeNome_1">São Paulo</span> <span id="MainContent_lvMostraNomes_lblTimeNome_2">Vasco</span> <span id="MainContent_lvMostraNomes_lblTimeNome_3">Botafogo</span> <span id="MainContent_lvMostraNomes_lblTimeNome_4">Corinthians</span> |
Assim, o sufixo será o mesmo que o ID de registro de cada time.
Se definirmos a propriedade ClientIDRowSuffix como : ClientIDRowSuffix="id,nome"
Teremos o seguinte resultado:
<span id="MainContent_lvMostraNomes_lblTimeNome_1_São Paulo">São Paulo</span>
<span id="MainContent_lvMostraNomes_lblTimeNome_2_Vasco">Vasco</span> <span id="MainContent_lvMostraNomes_lblTimeNome_3_Botafogo">Botafogo</span> <span id="MainContent_lvMostraNomes_lblTimeNome_4_Corinthians">Corinthians</span> |
Com a inclusão da propriedade ClientIDMode o problema de tratamento do ID do controle do lado do cliente foi resolvido. Uma dor de cabeça a menos...
Pegue o projeto completo aqui: ASPNET_ClientID.zip
"Pensai nas coisas que são de cima, e não nas que são da terra." Colossenses 3:2
Referências: