Articles

jQuery Datatables

In jquery on diciembre 29, 2009 by racar

El trabajo con tablas es muy común en las aplicaciones Web, específicamente para manejar información de registros. A menudo el manejo de tablas se dificulta cuando queremos hacer cosas mas complicadas que simplemente mostrar datos, por ejemplo, seleccionar registros, asociar información adicional a un fila o registro, cargar grandes cantidades de datos para desplegar, etc.

 

Para hacer este tipo de cosas y que nuestras aplicaciones no parezcan de los años 90’s debemos usar javascript. Como desarrollador de aplicaciones empresariales típicamente utilizaba frameworks java como JSF, y sus derivados como iceFaces, rich faces, o ADF y el framework de .net el popular ASP-ajax que permiten “incluir” componentes ajax sin codificar javascript.

 

Desafortunadamente este modelo no es flexible, y crear un componente a medida dentro de los frameworks es algo complicado. Por este motivo empecé a explorar otras alternativas al ajax de “estado gaseoso”. En esta búsqueda y en medio de todos estos toolkits javascript que existen me decidí por jQuery, ¿Por que? Bueno, me gusto  programar con el.

 

JQuery tiene una gran cantidad de plugins para manipular tablas html entre ellos esta datatables.net. Este plugin es muy bueno y me ha permitido hacer cosas que antes no podía a nivel de presentación y es fácilmente integrable con cualquier backend (java, .net, php o ruby) mediante diversos formatos, pero el más interesante sin duda es el llamado asíncrono de datos en formato JSON.    

 

Acá va un pedazo de código para que se den cuenta lo fácil que es crear una tabla. (Este código es ilustrativo, no pretende ser un tutorial ya que la documentación es bastante buena):

oTable = $('#canred').dataTable( {
          "bProcessing": true,    
          "bServerSide": true,
          "bJQueryUI": true,
          "bLengthChange": false, 
          "iDisplayLength": 3,
          "sPaginationType": "two_button",
          "sAjaxSource": "json_source/OpCandidatasRdcto.aspx",
         }

“canred” es el id de una tabla vacía y la página OpCandidatasRdcto.aspx nos entrega los datos en formto JSON convencional, algo como esto:

{"sEcho":1,"iTotalRecords":135,"iTotalDisplayRecords":135, "aaData":[
  [
    "22***",
    "PETROLEOS DEL MILENIO C.I S.A",
    "81***",
    "****",
    "2008/6/27",
    "MEDELLIN",
    "LS",
    "AVANCE DE OBRA NUMERO 002",
    "CONSTRUCCION",
    "MAQUINARIA Y EQUIPO",    
    "<img src=\"images/details_open.png\"/>"
  ],
  [
    "22***",
    "GIRALDO O*** ",
    "71**",
    "****",
    "2008/5/6",
    "MEDELLIN ",
    "LS",
    "TRACTO MULA",
    "TRANSPORTE CARGA",
    "AUTOMOTOR",    
    "<img src=\"images/details_open.png\"/>"
  ],
  [
    "22***",
    "NEWTRANS LTDA",
    "***",
    "***",
    "2008/7/29",
    "MEDELLIN ",
    "LS",
    "CARROCERIA",
    "CARROCERIA",
    "AUTOMOTOR",    
    "<img src=\"images/details_open.png\"/>"
  ]
]}
 

Entonces el servidor se encarga de entregar los datos y el cliente se dedica a mostrarlos, de la forma como queramos, acá un ejemplo para desplegar información adicional de un registro cuando damos clic en un botón de detalles.

$('td img', oTable.fnGetNodes() ).each( function () {
$(this).click( function () {
var nTr = this.parentNode.parentNode;
if ( this.src.match('details_close') ){
this.src = "images/details_open.png";
var nRemove = $(nTr).next()[0];
nRemove.parentNode.removeChild( nRemove );
}else if(this.src.match('details_open') ){
this.src = "images/details_close.png";
oTable.fnOpen( nTr, fnFormatDetails2(nTr), 'details' );
}
} );
} );

 

Finalmente una muestra de lo que podemos obtener como resultado final:

 

La flexibilidad de jquery datatables ofrece la posibilidad de mejorar las experiencias de los usuarios frente a nuestras aplicaciones con listas de registros y sin mucho esfuerzo podemos creaa aplicaciones enriquecidas. Es una buena manera de agregar herramientas a nuestro toolbox y es muy entretenido de programar.

7 respuestas to “jQuery Datatables”

  1. se ve muy bien la tabla, tiene la posibilidad de ordenar editar, buscar y eliminar?

    saludos

  2. hola buenas tardes

    Amigos por favor ayudenme, necesito que al hacer doble click en una fila pueda abrir una ventana y cargar todo el registro para editarlo y luego al grabar mandarlo actualizado al datatable, quizas sea una tonteria pero no logro hacerlo por favor es urgente

    gracias de antemano

    SERVER_SIDA.HTML
    ****************

    DataTables example

    @import «../../media/css/demo_page.css»;
    @import «../../media/css/demo_table_jui.css»;
    @import «../examples_support/themes/smoothness/jquery-ui-1.8.custom.css»;

    var oTable;
    var giRedraw = false;

    $(document).ready(function() {
    oTable = $(‘#example’).dataTable( {
    «bJQueryUI»: true,
    «sPaginationType»: «full_numbers»,
    «bLengthChange»: true,
    «iDisplayLength»: 25,
    «bStateSave»: true,
    «bAutoWidth»: false,
    «bServerSide»: true,
    «sAjaxSource»: «../examples_support/server_processing.php»
    } );
    } );

    $(document).ready(function() {
    /* Add a click handler to the rows – this could be used as a callback */
    $(«#example tbody»).click(function(event) {
    $(oTable.fnSettings().aoData).each(function (){
    $(this.nTr).removeClass(‘row_selected’);
    });
    $(event.target.parentNode).addClass(‘row_selected’);
    var anSelected = fnGetSelected( oTable );
    });

    /* Init the table */

    /* Get the rows which are currently selected */
    function fnGetSelected( oTableLocal )
    {
    var aReturn = new Array();
    var aTrs = oTableLocal.fnGetNodes();

    for ( var i=0 ; i<aTrs.length ; i++ )
    {
    if ( $(aTrs[i]).hasClass('row_selected') )
    {
    aReturn.push( aTrs[i] );
    }
    }
    return aReturn;
    }

    } );

    DataTables server-side processing example

    CODIGO
    NOMBRE
    CEDULA/RIF
    GRUPO
    TELEFONO

    Cargando data desde el servidor

    DataTables © Allan Jardine 2008-2010

    SERVER_PROCESSING.PHP
    *********************
    <?php
    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    * Easy set variables
    */

    /* Array of database columns which should be read and sent back to DataTables */
    $aColumns = array( 'codigo', 'nombre', 'rif', 'grupo', 'tel1' );

    /* Indexed column (used for fast and accurate table cardinality) */
    $sIndexColumn = "codigo";

    /* Database connection information */
    $gaSql['user'] = "root";
    $gaSql['password'] = "salvacion40";
    $gaSql['db'] = "0001_ventas";
    $gaSql['server'] = "localhost";

    /* REMOVE THIS LINE (it just includes my SQL connection user/pass) */
    // include( $_SERVER['DOCUMENT_ROOT']."/datatables/mysql.php" );

    /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    * If you just want to use the basic configuration for DataTables with PHP server-side, there is
    * no need to edit below this line
    */

    /*
    * MySQL connection
    */
    $gaSql['link'] = mysql_pconnect( $gaSql['server'], $gaSql['user'], $gaSql['password'] ) or
    die( 'Could not open connection to server' );

    mysql_select_db( $gaSql['db'], $gaSql['link'] ) or
    die( 'Could not select database '. $gaSql['db'] );

    /*
    * Paging
    */
    $sLimit = "";
    if ( isset( $_GET['iDisplayStart'] ) && $_GET['iDisplayLength'] != '-1' )
    {
    $sLimit = "LIMIT ".mysql_real_escape_string( $_GET['iDisplayStart'] ).", ".
    mysql_real_escape_string( $_GET['iDisplayLength'] );
    }

    /*
    * Ordering
    */
    if ( isset( $_GET['iSortCol_0'] ) )
    {
    $sOrder = "ORDER BY ";
    for ( $i=0 ; $i<intval( $_GET['iSortingCols'] ) ; $i++ )
    {
    $sOrder .= $aColumns[ intval( $_GET['iSortCol_'.$i] ) ]."
    ".mysql_real_escape_string( $_GET['sSortDir_'.$i] ) .", ";
    }
    $sOrder = substr_replace( $sOrder, "", -2 );
    }

    /*
    * Filtering
    * NOTE this does not match the built-in DataTables filtering which does it
    * word by word on any field. It's possible to do here, but concerned about efficiency
    * on very large tables, and MySQL's regex functionality is very limited
    */
    $sWhere = "";
    if ( $_GET['sSearch'] != "" )
    {
    $sWhere = "WHERE ";
    for ( $i=0 ; $i<count($aColumns) ; $i++ )
    {
    $sWhere .= $aColumns[$i]." LIKE '%".mysql_real_escape_string( $_GET['sSearch'] )."%' OR ";
    }
    $sWhere = substr_replace( $sWhere, "", -3 );
    }

    /*
    * SQL queries
    * Get data to display
    */
    $sQuery = "
    SELECT SQL_CALC_FOUND_ROWS ".implode(", ", $aColumns)."
    FROM clientes
    $sWhere
    $sOrder
    $sLimit
    ";
    $rResult = mysql_query( $sQuery, $gaSql['link'] ) or die(mysql_error());

    /* Data set length after filtering */
    $sQuery = "
    SELECT FOUND_ROWS()
    ";
    $rResultFilterTotal = mysql_query( $sQuery, $gaSql['link'] ) or die(mysql_error());
    $aResultFilterTotal = mysql_fetch_array($rResultFilterTotal);
    $iFilteredTotal = $aResultFilterTotal[0];

    /* Total data set length */
    $sQuery = "
    SELECT COUNT(".$sIndexColumn.")
    FROM clientes
    ";
    $rResultTotal = mysql_query( $sQuery, $gaSql['link'] ) or die(mysql_error());
    $aResultTotal = mysql_fetch_array($rResultTotal);
    $iTotal = $aResultTotal[0];

    /*
    * Output
    */
    $sOutput = '{';
    $sOutput .= '"sEcho": '.intval($_GET['sEcho']).', ';
    $sOutput .= '"iTotalRecords": '.$iTotal.', ';
    $sOutput .= '"iTotalDisplayRecords": '.$iFilteredTotal.', ';
    $sOutput .= '"aaData": [ ';
    while ( $aRow = mysql_fetch_array( $rResult ) )
    {
    $sOutput .= "[";
    for ( $i=0 ; $i

  3. Tiene muy buena pinta.

    ¿Alguien sabe como hacerlo todo dinámicamente?

    Con el tema del jQuery estoy un poco pez.

  4. Buenas tengo un problema tengo muchos registros para una tabla como 3 millones y tarda mucho en cargarlos que puedo hacer?

  5. Angela, en general tienes que paginar los registros (http://datatables.net/release-datatables/examples/basic_init/alt_pagination.html). En jquery/datatables se puede simular un listado «sin fin» como explican aquí:http://datatables.net/release-datatables/examples/basic_init/scroll_y_infinite.html .

    Recomendable aplicar algunos filtros o agregar un buscador pues al usuario (según mi experiencia) no le resulta muy útil tener esta cantidad de información «cruda» en un tabla.

  6. Hola,

    he hecho una aplicacion con datatables, tiene filtros en todas las columnas y paginación.

    El problema es que voy metiendo registros y a partir de 4000 cada vez que entro le cuesta 3-4 min cargarse la pagina. Una vez cargada funciona ok.

    Firefox indica que no responde, IE se cuelga y se cierra y con chrome aunque tarda se abre.
    Cuando entro en la pagina, veo que se cargan todos los registros (7000-8000), empieza a procesar y a los 3-4 min se ve la pginacion y los filtros de columna.

Replica a racar Cancelar la respuesta