De .NET a jQuery: Mejorando el GridView de ASP.NET con jQuery y DataTables

marzo 6, 2011
By

Para nadie es un secreto que el GridView de ASP.NET, sucesor del DataGrid, carece de algunas funcionalidades básicas que podrían mejorar notablemente su desempeño. Vamos a ver aquí cómo usando jQuery y algunos plugins podemos mejorar notablemente la experiencia de los usuarios. Para ello vamos a usar lo siguiente:

jQuery 1.4.2: No necesita presentación ;-)

DataTables: Plugin de jQuery que premite agregar a una tabla capacidades de ordenación, filtrado y paginado. Es el componente principal de nuestra solución.

Metadata: Plugin de jQuery que permite extraer de los propios elementos HTML metadatos en formato JSON. Lo usaremos para definir en el propio GridView las columnas que soportarán ordenación.

Si tenemos una MasterPage, ahi es donde debemos agregar las referencias a los ficheros JavaScript y colocar el código que “mejora” nuestros GridViews, de forma que solo tengamos que escribirlo una sola vez. En el encabezado de la página agregar las referencias:

<script type="text/javascript" src="scripts/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="scripts/jquery.metadata.js"></script>
<script type="text/javascript" src="scripts/jquery.dataTables.min.js"></script>

Luego, ponemos el siguiente código que se ejecutará cuando la página termine de cargar y será el encargado de aplicar a los GridViews, o más bien a las tablas que éstos generan, las mejoras del pluging DataTables.

$(document).ready(function () {

          // Indicar al pluging Metadata que los metadatos deberá buscarlos en el atributo class.
          $.metadata.setType("class"); 

          $("table.grid").each(function () {
                var grid = $(this); 

                // Por cada GridView que se encuentre modificar el código HTML generado para agregar el THEAD.
                if (grid.find("tbody > tr > th").length > 0) {
                    grid.find("tbody").before("<thead><tr></tr></thead>");
                    grid.find("thead:first tr").append(grid.find("th"));
                    grid.find("tbody tr:first").remove();
                } 

                // Si el GridView tiene la clase "sortable" aplicar el plugin DataTables si tiene más de 10 elementos.
                if (grid.hasClass("sortable") && grid.find("tbody:first > tr").length > 10)
                {
                    grid.dataTable({
                            sPaginationType: "full_numbers",
                            aoColumnDefs: [
                                { bSortable: false, aTargets: grid.metadata().disableSortCols }
                            ]
                    });
                }
          });
});

El código anterior realiza 3 acciones principales. La primera mediante la instrucción $.metadata.setType(“class”); estamos diciendo al plugin Metada que deberá buscar los metadatos en el atributo class. La segunda acción es preparar la tabla generada por el GridView de modo que sea compatible con el plugin DataTables, en escencia consiste en modificar el código de la tabla de forma que tenga los encabezados de las columnas dentro de la etiqueta THEAD. Por último, se chequea si la tabla tiene el atributo sortable y tiene más de 10 filas, y en ese caso se aplica el plugin DataTables, indicando entre sus opciones la lista de columnas que no serán ordenables, que se obtiene mediante el plugin Metadata del atributo class de la tabla. A continuación se muestra un fragmento del código donde se declara el GridView.

<asp:GridView ID="GridViewHotels" runat="server" CssClass="grid sortable {disableSortCols: [4]}">
...
</asp:GridView>

El resultado sería algo similar al que se muestra en la figura. Note que se ha desabilitado la opción de ordenar en la última columna que solo posee los links de acciones. Para poder ordenar por la columna Category hay que aplicar un truco, y es generar un texto que mantenemos oculto, que se usará en la ordenación, pues el plugin DataTables no tiene forma de saber como ordenar las imágenes.

Usando jQuery hemos logrado de forma sencilla dar un nuevo aire al viejo GridView, que aunque con sus deficiencias es un control que permite generar de forma rápida datos con formato tabular. Para aquellos entusiastas de jQuery, los invito a crear un plugin que permita encapsular el código visto aquí. Nos vemos en la próxima aventura “De .NET a jQuery” :)

50 Responses to De .NET a jQuery: Mejorando el GridView de ASP.NET con jQuery y DataTables

  1. Ana Alvarez on marzo 18, 2011 at 1:13 am

    Saludos, me puedes indicar si este tip podria tambien funcionar con jquery 1.4.1, es que aun no hay la libreria de visual studio para la version 1.4.2

  2. miguel on abril 24, 2011 at 12:42 pm

    hola,
    lo ke pasa ke no me funciona ami
    no genera las etiquetas thead
    puedes ayudarme(enviame un modelo)

    gracias

    • Cristian on noviembre 24, 2011 at 1:47 pm

      Que tal! Muy bueno el ejemplo. Lo único que no me funciono fue lo del header. Si saben como solucionarlo, se los agradecería. Saludos1

    • Cristian on noviembre 24, 2011 at 2:30 pm

      Que tal. Encontre como solucionar lo del header. Se debe cambiar esta linea:
      grid.find(“tbody”).before(“”);

      por esta:
      grid.find(“tbody”).before(“”);

      Saludos!

      • Cristian on noviembre 24, 2011 at 2:31 pm

        grid.find(“tbody”).before(“”);

        por esta:
        grid.find(“tbody”).before(“”);

        • Cristian on noviembre 24, 2011 at 2:33 pm

          Parece que el navegador no permite formatea las etiquetas. Lo que se debe hacer es escribir las siguientes etiquetas dentro del before:

          • Cristian on noviembre 24, 2011 at 2:34 pm
  3. Ivan on abril 26, 2011 at 8:44 am

    Saludos, muy bueno me va ahorrar mucho trabajo, lo estoy probando con jquery-1.5.2.min.js y va bien, pero tampoco me genera las etiquetas thead, me puedes mandar un ejemplo, gracias

  4. Victor Pinto on agosto 12, 2011 at 1:44 pm

    Hola,

    Primero, muchas gracias por la solución, me salvaste… ahora solo tengo un problema: no se me ve la fila de encabezados y traté de darle altura con estilos, pero igual no me resulta.

    Puedes ayudarme o mandarme un ejemplo por favor

    Saludos y gracias :)

  5. Fernando on agosto 29, 2011 at 9:48 pm

    Primero que nada muchas gracias, muy bueno el tutorial, me podrías enviar un ejemplo de como lookear el gridview como lo muestras en la imagen, esta muy bueno.

    Saludos y desde ya muchas gracias

  6. juan on septiembre 4, 2011 at 6:09 pm

    Saludos!! excelente aporte. me funcionó al chele!!! justo lo que necesitaba. te doy un 1000 de 100. gracias.

    • Christian on octubre 8, 2011 at 6:46 pm

      Hola estimado podrias compartir tu codigo ya que cuando uso este ejemplo no me muestra los nombres de los campos de la tabla. Muchas gracias…

    • ragdepg on octubre 28, 2011 at 8:24 pm

      Hola, me podrías compartir de favor un ejemplo de tu código, pues aun no me ha funcionad. De antemano gracias.

  7. Christian on octubre 8, 2011 at 6:31 pm

    Hola mucho gusto, probe tu query y no me aparece el nombre de las columnas. Otra consulta como llegaste hacer que en una columna te muestre estrellas. Por favor enviame un ejemplo a mi correo, estaria bien agradecido.

    Gracias

  8. lucecita on noviembre 10, 2011 at 11:47 am

    HOla!! excelente aporte, me podrias compartir tu codigo?? por fa..

  9. juan on noviembre 24, 2011 at 12:33 pm

    muy bueno el aporte, pero podrias compartir tu codigo. porque intente y no me funciona

  10. JuanMiguel on noviembre 24, 2011 at 12:37 pm

    muy bueno. porfavor podrias compartir tu codigo.

  11. Lester Sánchez
    Lester Sánchez on diciembre 28, 2011 at 11:25 am

    Hola a todos y gracias por vuestros comentarios. Ofrezco disculpas por no haber respondido antes pero el tiempo no me lo permitía.

    Ciertamente el código del post no funciona la parte de los headers, pues al parecer al publicar la entrada, algunas etiquetas HTML desaparecieron, y esto hizo que el código fuera inválido.

    Como indicó Cristian en su comentario, el problema radica en la línea 11, que ya aperece corregido en el propio post y siempre debió ser así:

    grid.find(“tbody”).before(“<thead><tr></tr></thead>”);

  12. javier jimenez on enero 20, 2012 at 8:45 pm

    Hola Lester: nos conocemos de cuando impartiste el curso de seguridad en la maestria CC de la uh, me gusato este articulo y me gustaria intercambiar sobre estos temas has probado Ext.net? dame tu opinion sobre este framework
    saludos
    Javier

  13. Andres Gutierrez on marzo 17, 2012 at 9:34 am

    Estoy haciendo todo tal cual esta en el articulo pero al parecer en la linea $.metadata.setType(“class”); no encuentra nada, estoy haciendolo en vb.net me podrian colaborar.

    Gracias de antemano.

    • Lester Sánchez
      Lester Sánchez on marzo 17, 2012 at 12:31 pm

      Andrés, no debe ser problema que uses VB.NET. Verifica bien que el plugin Metadata se esté cargando correctamente.

      • Programatic on agosto 6, 2012 at 1:19 pm

        Necesito el codigo para descargar

      • C#ristian on agosto 30, 2013 at 3:12 pm

        No carga!!!

  14. Andres Gutierrez on marzo 22, 2012 at 10:48 am
    • Erick on marzo 23, 2012 at 6:51 pm

      El mismo error, lograste solucionarlo, podrian publicar el metadata que estan usando en el ejemplo?

      El error que me salta al ejecutarlo: “Unable to get value of the property ‘setType’: object is null or undefined”

    • Carolina on marzo 31, 2012 at 7:12 pm

      Hola! Gracias por tu aporte, tengo el mismo problema de Andres Gutierrez, me podrías ayudar? Gracias!!!

  15. Andres Gutierrez on marzo 22, 2012 at 4:32 pm
  16. angela on abril 11, 2012 at 6:20 am

    hola teng un problema tengo millones de registros y el tiempo de carga es muy lento que puedo hacer?

    • Jac on abril 13, 2012 at 12:49 pm

      Amigo, antes que nada deberías delimitar el número de registros a mostrar, para que quieres cargar tantos?

  17. Ronald Vargas on abril 20, 2012 at 4:59 pm

    podrias proporcionarme un ejemplo con la hoja de estilos utilizada en la imagen mostrada

  18. Miguel Castro on junio 9, 2012 at 8:41 pm

    No me funciona me marca *Error en tiempo de ejecución de Microsoft JScript: ‘$.metadata’ es nulo o no es un objeto*

    $(document).ready(function() {

    // Indicar al pluging Metadata que los metadatos deberá buscarlos en el atributo class.
    $.metadata.setType(“class”); tr > th”).length > 0) {
    grid.find(“tbody”).before(“”);
    grid.find(“thead:first tr”).append(grid.find(“th”));
    grid.find(“tbody tr:first”).remove();
    }

    // Si el GridView tiene la clase “sortable” aplicar el plugin DataTables si tiene más de 10 elementos.
    if (grid.hasClass(“sortable”) && grid.find(“tbody:first > tr”).length > 10) {
    grid.dataTable({
    sPaginationType: “full_numbers”,
    aoColumnDefs: [
    { bSortable: false, aTargets: grid.metadata().disableSortCols }
    ]
    });
    }
    });
    });

  19. sexual on julio 31, 2012 at 6:45 am

    hola ^^

  20. Erik Ferrera on agosto 6, 2012 at 12:51 pm

    Si a alguien tiene este ejemplo para descargar me ayudaria mucho

  21. Programatic on agosto 6, 2012 at 1:14 pm

    Hey yo tambien ocupo el codigo por favor ponganlo para descargar….

  22. cesar on septiembre 3, 2012 at 9:27 am

    no funciona

    • Carlos Alberto Pinto on noviembre 23, 2012 at 8:17 am

      Si funciona

  23. Ricardo on noviembre 16, 2012 at 5:36 pm

    El estilo no me funciona, pero los demas si me funciona correctamente : filtros, paginacion, numeracion de pagina, pero no toma el estilo por favor a alguien le ha salido …

  24. andres on enero 3, 2013 at 10:48 am

    no funciona, ya he realizado todo lo que esta en los comentarios y no funciona si pueden pasar para descargar el proyecto serian de gran ayuda

    • C#ristian on agosto 30, 2013 at 2:47 pm

      Eso es lo que me pregunto, por qué diablos no puso el proyecto comprimido, o por lo menos unos links buenos donde poder descargar las librerías…

  25. jose on enero 17, 2013 at 11:32 pm

    No podrias enviarme el proyeco completo porfavor con los plugins.
    GRACIAS

  26. Guido on marzo 15, 2013 at 2:01 pm

    No funcionan los estilos

  27. Manuel mireles on abril 3, 2013 at 1:16 pm

    me pudieras mandar un ejemplo con los plugins ya no que no me funcionan los que estoy usando muchas gracuas

  28. Jorge G on junio 14, 2013 at 5:18 pm

    YA ME FUNCIONO… GRACIAS EXCELENTE APORTACION

    • C#ristian on agosto 30, 2013 at 2:49 pm

      Dónde pusiste la función de jquery? Podes subir el proyecto completo? yo estoy batallando con los .js pero me siguen dando error:

      TypeError: $.metadata is undefined

  29. Jorge G on junio 14, 2013 at 5:22 pm

    Alguien tendra una hoja de estilos para mejorar la imagen del grid??

    (O.o)

  30. Christian on agosto 30, 2013 at 2:40 pm

    Es que siempre se debe incluir un zip con todo el proyecto para no andar tonteando para buscar los .js.
    Ya llevo como media hora buscándolos y solo me falta el de Metadata, porque encontré un par por ahí pero no funcionan :-/

  31. Christian on agosto 30, 2013 at 2:44 pm

    TypeError: $.metadata is undefined

    Este es mi archivo .js, le quité los comentarios del inicio para optimizar espacio.

    (function($) {

    $.extend({
    metadata : {
    defaults : {
    type: ‘class’,
    name: ‘metadata’,
    cre: /({.*})/,
    single: ‘metadata’
    },
    setType: function( type, name ){
    this.defaults.type = type;
    this.defaults.name = name;
    },
    get: function( elem, opts ){
    var settings = $.extend({},this.defaults,opts);
    // check for empty string in single property
    if ( !settings.single.length ) settings.single = ‘metadata’;

    var data = $.data(elem, settings.single);
    // returned cached data if it already exists
    if ( data ) return data;

    data = “{}”;

    if ( settings.type == “class” ) {
    var m = settings.cre.exec( elem.className );
    if ( m )
    data = m[1];
    } else if ( settings.type == “elem” ) {
    if( !elem.getElementsByTagName )
    return undefined;
    var e = elem.getElementsByTagName(settings.name);
    if ( e.length )
    data = $.trim(e[0].innerHTML);
    } else if ( elem.getAttribute != undefined ) {
    var attr = elem.getAttribute( settings.name );
    if ( attr )
    data = attr;
    }

    if ( data.indexOf( ‘{‘ ) <0 )
    data = "{" + data + "}";

    data = eval("(" + data + ")");

    $.data( elem, settings.single, data );
    return data;
    }
    }
    });

    /**
    * Returns the metadata object for the first member of the jQuery object.
    *
    * @name metadata
    * @descr Returns element's metadata object
    * @param Object opts An object contianing settings to override the defaults
    * @type jQuery
    * @cat Plugins/Metadata
    */
    $.fn.metadata = function( opts ){
    return $.metadata.get( this[0], opts );
    };

    })(jQuery);

  32. C#ristian on agosto 30, 2013 at 4:27 pm

    Este es el error que me da al paginar con el GridView (y quitando la paginación del DataTable de jQuery):

    DataTables warning (table id = ‘mainCopy_GridView1′): Requested unknown parameter ’1′ from the data source for row 10

  33. roberto on septiembre 16, 2013 at 10:14 am

    hola, puedes por favor enviarme el ejemplo a mi correo, ya probe pero no me funciona, necesito urgentemente ,.. gracias
    saludos,

  34. Hugo on noviembre 12, 2013 at 3:18 pm

    Ya revisé metadata y me sigue mandando el error:

    0x800a138f – Error en tiempo de ejecución de JavaScript: No se puede obtener la propiedad ‘setType’ de referencia nula o sin definir.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

*

Acerca del autor...

Lester Sánchez

Web: http://www.linkedin.com/in/lestersanchez
Lester Sánchez
Profesor de la Facultad de Matemática y Computación de la Universidad de La Habana. Entusiasta de las tecnologías .NET y en especial de SharePoint. Webmaster de weboomania.comLeer completo