Xavi Navarro
06 octubre de 2008
Esto de jQuery es divertido. Igual de divertido que javascript pero más fácil.

Hace unos días di una primero introducción a jQuery e hice mi primer plugin que llamé macEmulator.

Ahora presento un nuevo plugin que responde a una necesidad real y casi diaria de todo programador en ASP.NET (a no ser que trabaje con MVC).

Se trata de emular el FindControl de ASP.NET pero con javascript. Vayamos a un ejemplo:

Tenemos un DataList con un ItemTemplate que tiene dos Panels y un Label en cada Panel

<asp:DataList ID="DataList1" runat="server">
    <ItemTemplate>
        <asp:Panel ID="Panel1" runat="server">
            <asp:Label ID="Label1" runat="server" Text="Label1"></asp:Label>
        </asp:Panel>
        <asp:Panel ID="Panel2" runat="server">
            <asp:Label ID="Label2" runat="server" Text="Label2"></asp:Label>
        </asp:Panel>
    </ItemTemplate>
</asp:DataList>


Esto generará un código HTML que convertirá las Label en elementos <span /> con un identificador de este estilo: DataList1_ctl00_Label1

Pero yo lo que quiero es acceder a las Label1 por jQuery... ¿cómo lo hago?

No hay una forma directa porque los IDs los genera ASP.NET, pero con el plugin que presento podremos hacer algo como esto:

var controls = $(document).findControl('Label1');
for (i = 0; i < controls.length; i++) { alert(controls[i].innerHTML); }


El plugin no es que sea una obra de arte. Más bien es sencillito, jeje. Lo autoexplican los comentarios:

jQuery.fn.findControl = function(clientId) {
    var ids = new Array();
   
    // Para cada elemento que tenga un atributo ID dentro de "this"
    $(this).find('*[id]').each(function(i) {
        // Si el ID del elemento termina como el clientId, lo añadimos al array
        if (this.id &&
            (this.id.lastIndexOf(clientId) >= 0) &&
            (this.id.lastIndexOf(clientId) == (this.id.length - clientId.length))) {
                ids.push(this);
            }
        });
       
    // Devolvemos el array
    return ids;
}


El plugin ya viene con bugs por defecto, como el hecho de que si otro elemento se llamara MyLabel1, el plugin se creería que es Label1... pero bueno, es una primera aproximación.

Escribe:   Xavi Navarro
3 Comentarios
1
Arturo sugerencia
Muchas gracias por tu ayuda. Muy útiles tus 2 blogs. Yo usaba FileUpload AJAX pero la verdad no me había fijado quien lo desarrollaba (que mal agradecido que soy) y ahora me vengo a topar con el blog del desarrollador... Muchas gracias Seria bueno que en vez de buscar Label1, busques Label1 de 6 caracteres (osea LEN("Label1") ) o _Label1 de mas caracteres... con lo cual evitas la inclusión de MyLabel1 saludos y gracias nuevamente!
2
Lainon Otra posible implementación
Buenas, he visto tu implementación y tras ver las problemáticas que tenía me puse a pensar en como se podría hacer de otra forma para que devolviera objetos jQuery en vez objetos DOM. Para no alargarme mucho, la implementación sería esta: jQuery.fn.findControl = function(clientId) { return $('*[id*="_' + clientId + '"]'); } Además se arregla el problema del guión bajo, aunque no diferenciaría entre controles con IDs repetidos (como en un DataGrid), sino que los devolvería todos. Yo estoy usando esta implementación y va bastante bien para lo que se necesita. De todas formas es sólo una alternativa posible, más simple y que devuelve otros resultados dependiendo de lo que se necesite. Espero que os sirva para algo. Un saludo.
3
Micha-kun Mejora del código
he visto tu implementación y, aun siendo la idea buena, creo que sería mejor que utilizaras como selector lo siguiente: $(this).find('[id$=' + clientId + ']'); Esto en si ya te devolvería en un objeto jQuery todos aquellos objetos DOM que finalicen ($=) en el id que le pases por parámatero, así que ya se obtienen todos asi sin mucho lio, ademas que la consulta interna te la saltas! Si el parametro a buscar tambien está entre medio de la ID, busca de la siguiente forma: $(this).find('[id*=' + clientId + ']'); El asterisco hace la función de buscar en cualquier lado. Un saludo, sigue así
Añadir un nuevo comentario
Titulo
Nombre de usuario
Avanzis S.L.
C/ Seúl 88, nº1 dcha. Pta 1.46900 Torrente (Valencia)
Telf: +34 96 158 01 84 - Fax: +34 96 156 59 92

Copyright 2010