En ocasiones tenemos demasiados datos para mostrar en la tabla. Por ejemplo, supongamos que tenemos, en nuestra lista de personal, o de clientes, o lo que sea, un campo de observaciones, o comentarios, de texto libre. Puede que, en algunos registros, el contenido de este campo sea tan grande que no podamos encajarlo, de forma cómoda, en una estructura tabular, ya que excedería el ancho de la pantalla, o descolocaría el resto de los contenidos. En esos caso, tenemos que buscar una alternativa, si debemos mostrar este campo junto a los demás.
Afortunadamente, DataTables nos ofrece una solución muy conveniente a estos efectos. En este artículo vamos a ver como podemos colocar estos contenidos “ocultos”, de forma que la tabla incluya un enlace para desplegarlos de forma elegante, práctica y usable.
PREPARANDO EL ENTORNO
Lo primero es preparar el escenario para tener esos contenidos que, en principio, desbordarían nuestra tabla. Lo que vamos a hacer es, en la tabla personal
de la base de datos que estamos usando, agregarle (con PHPMyAdmin o cualquier otra herramienta similar) un campo llamado comentarios
, de tipo text
(texto libre). A continuación pondremos un texto de pruebas (el que queramos), en los campos de los 57 registros que tenemos. Para facilitarte el seguimiento de este artículo, te dejo aquí la base de datos modificada.
EL SCRIPT PRIMARIO
Ya tenemos nuestros datos de tal forma que, como hemos apuntado, existe un campo de texto libre, que puede tener un contenido más amplio de lo que podemos encajar en una estructura tabular. Lo que vamos a hacer es crear una columna, a la izquierda de la tabla, que no contenga datos. En su lugar, tendrá un icono con el signo más (+
) o el que decidamos, para desplegar este campo debajo del registro correspondiente. Cuando este campo esté desplegado aparecerá cómo si fuese una fila más de la tabla. En ese momento, el icono cambiará a un signo menos (-
). Si lo pulsamos, esta fila se replegará de nuevo, desapareciendo de la vista. El script primario se llama articulo_10.php
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Uso de DataTables</title> <!-- El CSS de DataTables --> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/jszip-2.5.0/pdfmake-0.1.18/dt-1.10.12/af-2.1.2/b-1.2.2/b-colvis-1.2.2/b-flash-1.2.2/b-html5-1.2.2/b-print-1.2.2/cr-1.3.2/fc-3.2.2/fh-3.1.2/kt-2.1.3/r-2.1.0/rr-1.1.2/sc-1.4.2/se-1.2.0/datatables.min.css"/> <!-- El CSS de Bootstrap --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <!--<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css">--> <!-- El CSS de Font Awesome --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body> <div class="container"> <br> <div class="row"> <div class="col-sm-12"> <table id="tabla_de_personal" class="table display table-bordered table-striped"> <thead> <tr> <th> </th> <th>NOMBRE</th> <th>APELLIDO</th> <th>CARGO</th> <th>CIUDAD</th> <th>INGRESO</th> <th>SALARIO</th> <th>OPERACIONES</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> </div> <!-- jQuery --> <script language="javascript" src="https://code.jquery.com/jquery-3.1.1.min.js"></script> <!-- El JavaScript de DataTables --> <script language="javascript" type="text/javascript" src="https://cdn.datatables.net/v/dt/jszip-2.5.0/pdfmake-0.1.18/dt-1.10.12/af-2.1.2/b-1.2.2/b-colvis-1.2.2/b-flash-1.2.2/b-html5-1.2.2/b-print-1.2.2/cr-1.3.2/fc-3.2.2/fh-3.1.2/kt-2.1.3/r-2.1.0/rr-1.1.2/sc-1.4.2/se-1.2.0/datatables.min.js"></script> <!-- El JavaScript de BootStrap --> <script language="javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> <!-- El código JavaScript --> <script> var objetoDataTables_personal = $('#tabla_de_personal').DataTable({ "language": { "emptyTable": "No hay datos disponibles en la tabla.", "info": "Del _START_ al _END_ de _TOTAL_ ", "infoEmpty": "Mostrando 0 registros de un total de 0.", "infoFiltered": "(filtrados de un total de _MAX_ registros)", "infoPostFix": "(actualizados)", "lengthMenu": "Mostrar _MENU_ registros", "loadingRecords": "Cargando...", "processing": "Procesando...", "search": "Buscar:", "searchPlaceholder": "Dato para buscar", "zeroRecords": "No se han encontrado coincidencias.", "paginate": { "first": "Primera", "last": "Última", "next": "Siguiente", "previous": "Anterior" }, "aria": { "sortAscending": "Ordenación ascendente", "sortDescending": "Ordenación descendente" } }, "lengthMenu": [[5, 10, 20, 25, 50, -1], [5, 10, 20, 25, 50, "Todos"]], "iDisplayLength": 10, "bServerSide": true, "responsive" : false, "bJQueryUI": false, "sAjaxSource": "datos_externos_10.php", "columns" : [ { "className": 'celda_de_descripcion', "orderable": false, "data": null, "defaultContent": '<div class="text-center fa fa-plus-circle" style="width:100%; color: #3dc728;"></div>' }, {"data": 0}, {"data": 1}, {"data": 2}, {"data": 3}, {"data": 4}, {"data": 5}, {"data": 6, 'orderable' : false} ], "order": [[1, "asc"]] }); $('label').addClass('form-inline'); $('select, input[type="search"]').addClass('form-control input-sm'); function operaciones(id, op){ var mensaje = "El id es " + id + ", y la operación es " + op; alert (mensaje); } $('#tabla_de_personal tbody').on('click', 'td.celda_de_descripcion', function () { var filaDeLaTabla = $(this).closest('tr'); var filaComplementaria = objetoDataTables_personal.row(filaDeLaTabla); var celdaDeIcono = $(this).closest('td.celda_de_descripcion'); if (filaComplementaria.child.isShown() ) { // La fila complementaria está abierta y se cierra. filaComplementaria.child.hide(); celdaDeIcono.html('<div class="text-center fa fa-plus-circle" style="width:100%; color: #3dc728;"></div>'); } else { // La fila complementaria está cerrada y se abre. filaComplementaria.child(formatearSalidaDeDatosComplementarios(filaComplementaria.data(), 7)).show(); celdaDeIcono.html('<div class="text-center fa fa-minus-circle" style="width:100%; color: #e80909;"></div>'); } }); function formatearSalidaDeDatosComplementarios (filaDelDataSet, columna) { var cadenaDeRetorno = ''; cadenaDeRetorno += '<div>'; cadenaDeRetorno += 'COMENTARIOS: ' + filaDelDataSet[columna]; cadenaDeRetorno += '</div>'; return cadenaDeRetorno; } </script> </body> </html> |
En el listado superior vemos el código completo del script primario. Vamos a fijarnos en las novedades, que son las líneas que están resaltadas.
En primer lugar, vemos que en la cabecera de la tabla HTML definimos una columna adicional al principio, sin rótulo de encabezamiento, como se ve en la línea 24
:
<th> </th>
Esta columna será la que tenga los iconos para desplegar y replegar la fila con los comentarios de cada registro.
En la definición de las columnas, dentro de la creación del objeto DataTables, encontramos otra novedad, en las líneas 81
a 86
:
{
"className": 'celda_de_descripcion',
"orderable": false,
"data": null,
"defaultContent": '<div class="text-center fa fa-plus-circle" style="width:100%; color: #3dc728;"></div>'
},
Cómo todas las columnas, la que contendrá el icono para desplegar y replegar contenidos adicionales, también debe definirse. Sin embargo, se define de un modo particular. Hay que establecer algunos parámetros necesarios, en notación de objeto de JavaScript, cómo puedes ver, que son los siguientes:
className
. Hay que darles, a las celdas de esta columna, un nombre de clase específico, que luego nos servirá para referenciarlas desde jQuery.orderable
. Esta celda NO debe ser ordenable, y debemos indicarlo explícitamente.data
. Esta celda no contendrá ningún dato del dataset que recuperemos del script secundario. Por lo tanto, no podemos darle un número de índice, porque no vamos a meter aquí el contenido de ningún campo del dataset. Es necesario indicar, explícitamente, que el data esnull
.defaultContent
. En realidad este es un parámetro que podemos establecer en cualquier columna de la tabla. Sin embargo, hasta ahora no lo habíamos necesitado. Indica cual es el contenido por defecto, a la carga de la página, si no se coloca ningún dato procedente del script secundario. En este caso, hemos decidido que, por defecto, en esta celda aparecerá el icono+
.
Observa que el resto de las celdas que definen columnas no sufren modificación alguna con respecto al ejercicio del artículo anterior.
En las líneas 105
a 125
encontramos el jQuery y el JavaScript necesario para que el icono despliegue la fila con los contenidos complementarios, y cambie a un signo -
cuando lo pulsemos, o los repliegue y cambie a un signo +
si lo pulsamos de nuevo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
$('#tabla_de_personal tbody').on('click', 'td.celda_de_descripcion', function () { var filaDeLaTabla = $(this).closest('tr'); var filaComplementaria = objetoDataTables_personal.row(filaDeLaTabla); var celdaDeIcono = $(this).closest('td.celda_de_descripcion'); if (filaComplementaria.child.isShown() ) { // La fila complementaria está abierta y se cierra. filaComplementaria.child.hide(); celdaDeIcono.html('<div class="text-center fa fa-plus-circle" style="width:100%; color: #3dc728;"></div>'); } else { // La fila complementaria está cerrada y se abre. filaComplementaria.child(formatearSalidaDeDatosComplementarios(filaComplementaria.data(), 7)).show(); celdaDeIcono.html('<div class="text-center fa fa-minus-circle" style="width:100%; color: #e80909;"></div>'); } }); function formatearSalidaDeDatosComplementarios (filaDelDataSet, columna) { var cadenaDeRetorno = ''; cadenaDeRetorno += '<div>'; cadenaDeRetorno += 'COMENTARIOS: ' + filaDelDataSet[columna]; cadenaDeRetorno += '</div>'; return cadenaDeRetorno; } |
Aunque no vamos a entrar en detalles acerca del uso específico de jQuery, ya que eso es más propio de un tutorial dedicado a esta hetrramienta, si vamosa fijarnos que, cuando se hace click en una celda de la clase celda_de_descripcion
(que es la clase que le asignamos a las celdas de la izquierda en la línea 80
) se desencadena todo el proceso. En primer lugar se identifica la fila “más próxima” a la que contiene la celda sobre la que hemos hecho clic. Si te gusta jQuery, encontrarás el método .closest()
muy útil para muchas cosas. Puedes verlo en la documentación oficial. A continuación definimos la fila completa en una variable llamada filaComplementaria
. Lo hacemos mediante el método .row()
, que es del plugin DataTables. Forma parte del una colección de métodos auxiliares que cumplen funcionalidades específicas para integrarlos en otros procesos. Básicamente, lo que hacemos es identificar cual será la fila de contenidos complementarios, y cual es la celda que se ha pulsado, y que referenciamos en la veriable celdaDeIcono
.
A continuación comprobamos si la fila con los contenidos complementarios relativos al registro cuya celda del icono se ha pulsado está desplegada o no. Eso lo hacemos con el método .isShown()
, que es nativo de DataTables (línea 110
del listado). Si está desplegada, cambiamos el icono de la celda a +
y la replegamos, con el método .hide()
(este es nativo de jQuery, cómo puedes ver aquí). Si está replegada, la desplegamos (en seguida vemos cómo), y cambiamos el icono de la celda izquierda a -
.
Para desplegar la fila de tabla que contiene los datos complementarios (los comentarios, en este ejemplo), recurrimos a una pequeña función auxiliar llamada formatearSalidaDeDatosComplementarios
. Esta recibe dos parámetros. El primero es una referencia al registro con el que estamos trabajando. Esto es importante, porque necesitamos desplegar la fila justo debajo de dicho registro, y con los datos que están asociados al mismo, en la base de datos. El segundo parámetro es el índice de campo que contiene los datos complementarios que se mostrarán en la fila desplegable. Fíjate que el índice es 7
. Sin embargo, en la definición del objeto DataTables no existe una columna con índice 7
. Esto es porque estos contenidos no los cargamos al inicio. Vendrán en el dataset que nos envíe el script secundario (en seguida lo vemos), pero son ignorados por el objeto DataTables que hemos creado, hasta que se despliega la fila destinada a mostrarlos.
La función formatearSalidaDeDatosComplementarios
lo único que hace es renderizar un contenedor con los datos solicitados, cómo puedes ver en el código (líneas 119
a 125
).
EL SCRIPT SECUNDARIO
El script secundario, datos_externos_10.php
, obedece al siguiente listado:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
<?php // Establecemos la codificacion para las llamadas y respuestas HTTP mb_internal_encoding ('UTF-8'); /* CREAMOS LA CONEXION A LA BASE DE DATOS, O BIEN LA IMPORTAMOS DESDE UN ARCHIVO EXTERNO DE CONFIGURACION. */ $conexion = new PDO('mysql:host=localhost;dbname=datatables;charset=UTF8', 'root', ''); $conexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); /* RECUPERAMOS TODOS LOS PARAMETROS DE $_GET. LOS QUE NO APAREZCAN EN LA CONSULTA RECIBIRAN UN VALOR PREDETERMINADO. ESTOS DATOS SON LOS QUE SE RECIBEN CADA VEZ QUE EL PLUGIN DATATABLES LLAMA A ESTE SCRIPT. */ $datosDeLlamada = $_GET; /* SE INDICA(N) LA(S) TABLA(S) QUE SE VA(N) A USAR EN LA CONSULTA. */ $tablasDeBBDD = array( 'personal', 'ciudades', 'cargos' ); /* SE DEFINE LA LISTA DE COLUMNAS QUE SE DEVOLVERON PARA SER MOSTRADAS EN LA TABLA HTML. LOS NOMBRES DE ESTAS COLUMNAS DEBEN COINCIDIR CON LOS DE LAS COLUMNAS DE LA(S) TABLA(S) AFECTADA(S) POR LA CONSULTA. */ $columnasParaRetorno = array( $tablasDeBBDD[0].'.nombre', $tablasDeBBDD[0].'.apellido', $tablasDeBBDD[2].'.cargo', $tablasDeBBDD[1].'.ciudad', $tablasDeBBDD[0].'.fecha_de_ingreso', $tablasDeBBDD[0].'.salario_bruto_anual', $tablasDeBBDD[0].'.id', $tablasDeBBDD[0].'.comentarios' ); $numeroDeColumnas = count($columnasParaRetorno); //////////////////////////////////////////////// REGLAS DE FILTRADO //////////////////////////// /* PREPARAMOS EL FILTRADO POR COLUMNAS PARA LA CAJA DE BUSQUEDA */ $reglasDeFiltradoDeUsuario = array (); if (isset($datosDeLlamada['sSearch']) && $datosDeLlamada['sSearch'] !== "") { for($i = 0; $i < $numeroDeColumnas; $i++) { if (isset ($datosDeLlamada['bSearchable_'.$i]) && $datosDeLlamada['bSearchable_'.$i] == 'true') { $reglasDeFiltradoDeUsuario[] = $columnasParaRetorno[$i]." LIKE '%".addslashes($datosDeLlamada['sSearch'])."%'"; } } } if (!empty($reglasDeFiltradoDeUsuario)){ $reglasDeFiltradoDeUsuario = ' ('.implode(" OR ", $reglasDeFiltradoDeUsuario).') '; } else { $reglasDeFiltradoDeUsuario = ''; } /* PREPARAMOS LAS REGLAS DE FILTRADO PARA LAS BUSQUEDAS PROGRAMADAS POR METODO .search() (BÚSQUEDAS PERSONALIDAS DEL USUARIO). */ $reglasDeBusquedaPorProgramacion = array(); for($i = 0; $i < $numeroDeColumnas; $i++) { if (isset($datosDeLlamada['sSearch_'.$i]) && $datosDeLlamada['sSearch_'.$i] !== ""){ $reglasDeBusquedaPorProgramacion[] = $columnasParaRetorno[$i].$datosDeLlamada['sSearch_'.$i]; } } if (!empty($reglasDeBusquedaPorProgramacion)){ $reglasDeBusquedaPorProgramacion = ' ('.implode(" AND ", $reglasDeBusquedaPorProgramacion).') '; } else { $reglasDeBusquedaPorProgramacion = ''; } /* PREPARAMOS LAS REGLAS DE FILTRADO DE RELACIONES ENTRE TABLAS. ESTAS SE PROGRAMAN AQUI A MANO, PORQUE PUEDEN EXISTIR O NO, DEPENDIENDO DE QUE SE USE UNA TABLA O MAS DE UNA. */ $reglasDeFiltradoDeRelaciones = ''; $reglasDeFiltradoDeRelaciones .= " (".$tablasDeBBDD[1].".id = ".$tablasDeBBDD[0].".id_ciudad "; $reglasDeFiltradoDeRelaciones .= "AND ".$tablasDeBBDD[2].".id = ".$tablasDeBBDD[0].".id_cargo) "; /* SE COMPONE TODA LA REGLA DE FILTRADO. EN ESTE CASO INCLUYE LAS CLAÚSULAS DE BÚSQUEDA, Y LAS RELACIONES ENTRE TABLAS. SIGUE SIENDO UN EJEMPLO SIMPLE, PERO MÁS ELABORADO QUE EL ANTERIOR. MÁS ADELANTE VEREMOS OTROS USOS. LO IMPORTANTE AQUI ES QUE, ADEMÁS DE LAS CLAUSULAS DE BÚSQUEDA (VARIABLE $reglasDeFiltradoDeUsuario, QUE PUEDEN EXISTIR O NO) TAMBIÉN HAY UNA CLAÚSULA DE RELACIONES ENTRE LAS TABLAS. SI HAY MÁS DE UNA TABLA SIEMPRE HABRÁ UNA CLAÚSULA DE RELACIONES ($reglasDeFiltradoDeRelaciones). LAS IMPLEMENTAMOS COMO UNA MATRIZ PARA PODER COMPROBAR LAS QUE EXISTEN Y LAS QUE NO, Y LUEGO LAS UNIMOS CON EL OPERADOR AND, SI HAY MÁS DE UNA CLAÚSULA DE FILTRADO. */ $reglasDeFiltrado = array(); if ($reglasDeFiltradoDeUsuario > '') $reglasDeFiltrado[] = $reglasDeFiltradoDeUsuario; if ($reglasDeFiltradoDeRelaciones > '') $reglasDeFiltrado[] = $reglasDeFiltradoDeRelaciones; if ($reglasDeBusquedaPorProgramacion > '') $reglasDeFiltrado[] = $reglasDeBusquedaPorProgramacion; $reglasDeFiltrado = implode(" AND ", $reglasDeFiltrado); //////////////////////////////////////////// FIN DE REGLAS DE FILTRADO /////////////////////////// /////////////////////////// REGLAS DE ORDENACION //////////////////////// /* SE COMPONE LA REGLA DE ORDENACION. */ $reglasDeOrdenacion = array (); if (isset($datosDeLlamada['iSortCol_0'] )) { $columnasDeOrdenacion = intval($datosDeLlamada['iSortingCols']); for($i = 0; $i < $columnasDeOrdenacion; $i ++) { if ($datosDeLlamada['bSortable_'.intval($datosDeLlamada['iSortCol_'.$i])] == 'true') { $reglasDeOrdenacion [] = $columnasParaRetorno[intval($datosDeLlamada['iSortCol_'.$i])].($datosDeLlamada['sSortDir_'.$i] === 'asc'?' asc':' desc'); } } } if (!empty($reglasDeOrdenacion)) { $reglasDeOrdenacion = " ORDER BY ".implode(", ", $reglasDeOrdenacion); } else { $reglasDeOrdenacion = ""; } /* SE COMPONE LA REGLA DE LIMITACION DE REGISTROS. */ $reglaDeLimitacion = ($datosDeLlamada['iDisplayLength'] > 0)?' LIMIT '.$datosDeLlamada['iDisplayStart'].', '.$datosDeLlamada['iDisplayLength'].';':';'; /////////////////////////////////////// FIN DE REGLAS DE ORDENACION //////////////////// /* SE PREPARA LA CONSULTA DE RECUPERACION DEL DATASET SOLICITADO. */ $consulta = "SELECT ".implode(', ', $columnasParaRetorno)." "; $consulta .= "FROM ".implode(', ', $tablasDeBBDD)." "; $consulta .= "WHERE 1 "; if ($reglasDeFiltrado > "") $consulta .= "AND (".$reglasDeFiltrado.") "; $consulta .= $reglasDeOrdenacion; $consulta .= $reglaDeLimitacion; $hacerConsulta = $conexion->prepare($consulta); $hacerConsulta->execute(); $DataSet = $hacerConsulta->fetchAll(PDO::FETCH_ASSOC); $hacerConsulta->closeCursor(); /* SI ES NECESARIO ADAPTAR ALGUN DATO PARA PRESENTACION, SE ADAPTA AQUI. SI ES NECESARIOS AGREGAR ENLACES, REFERENCIAS A IMAGENES, O CUALQUIER OTRA COSA, SE INCLUYE EN ESTA SECCION. EN ESTE CASO, LO ÚNICO QUE VAMOS A HACER ES DARLE FORMATO AL SALARIO ANUAL. */ foreach ($DataSet as $keyDL=>$DL){ $DataSet[$keyDL]['fecha_de_ingreso'] = date("d-m-Y", strtotime($DL['fecha_de_ingreso'])); $DataSet[$keyDL]['salario_bruto_anual'] = number_format($DL['salario_bruto_anual'], 2, ",", ".").' €'; $cadenaDeColumnaFinal = ""; $cadenaDeColumnaFinal .= "<div class='text-center'>"; $cadenaDeColumnaFinal .= "<a href='javascript:operaciones("".$DL["id"]."", "Correo");' title='Correo'>"; $cadenaDeColumnaFinal .= "<i class='fa fa-envelope'></i></a> "; $cadenaDeColumnaFinal .= "<a href='javascript:operaciones("".$DL["id"]."", "Borrar");' title='Borrar'>"; $cadenaDeColumnaFinal .= "<i class='fa fa-trash-o'></i></a> "; $cadenaDeColumnaFinal .= "<a href='javascript:operaciones("".$DL["id"]."", "Borrar");' title='Marcar'>"; $cadenaDeColumnaFinal .= "<i class='fa fa-thumb-tack'></i></a>"; $cadenaDeColumnaFinal .= "</div>"; $DataSet[$keyDL]["id"] = $cadenaDeColumnaFinal; } /* CALCULO DE DATOS INFORMATIVOS DE REGISTROS. */ $numeroDeRegistrosDelDataSet = count($DataSet); /* CALCULO DEL TOTAL DE REGISTROS QUE CUMPLEN LAS REGLAS DE FILTRADO SIN ORDENACION NI LIMITACION. */ $consulta = "SELECT COUNT(".$columnasParaRetorno[0].") "; $consulta .= "FROM ".implode(', ', $tablasDeBBDD)." "; $consulta .= "WHERE 1 "; if ($reglasDeFiltrado > "") $consulta .= "AND (".$reglasDeFiltrado.") "; $hacerConsulta = $conexion->prepare($consulta); $hacerConsulta->execute(); $totalDeRegistrosConFiltrado = $hacerConsulta->fetch(PDO::FETCH_NUM)[0]; $hacerConsulta->closeCursor(); /* TOTAL DE REGISTROS DE LA TABLA PRIMARIA (O UNICA, SI SOLO HAY UNA). */ $consulta = "SELECT COUNT(".$columnasParaRetorno[0].") "; $consulta .= "FROM ".$tablasDeBBDD[0].";"; $hacerConsulta = $conexion->prepare($consulta); $hacerConsulta->execute(); $totalDeRegistrosEnBruto = $hacerConsulta->fetch(PDO::FETCH_NUM)[0]; $hacerConsulta->closeCursor(); // SE PREPARA UNA MATRIZ CON TODOS LOS DATOS NECESARIOS PARA LA SALIDA. $matrizDeSalida = array( "sEcho" => intval($datosDeLlamada['sEcho']), "iTotalRecords" => strval($totalDeRegistrosEnBruto), "iTotalDisplayRecords" => strval($totalDeRegistrosConFiltrado), "aaData" => array () ); foreach ($DataSet as $DL){ $registro = array(); foreach ($DL as $dato) $registro[] = $dato; $matrizDeSalida['aaData'][] = $registro; unset($registro); } $salidaDeDataSet = json_encode ($matrizDeSalida, JSON_HEX_QUOT); /* SE DEVUELVE LA SALIDA */ echo $salidaDeDataSet; ?> |
Cómo puedes ver, el script secundario es prácticamente idéntico al del artículo anterior. La única novedad está en la línea 34
(resaltada en el código). Lo que hace es indicar un campo más (el campo de texto nuevo) en la matriz de campos que van a formar el dataset. Como las matrices empiezan a indexarse por 0
y este es el octavo campo, tiene el índice 7
, que es el que mencionábamos en la línea 112
del script primario.
Prueba este ejercicio en tu ordenador, para que veas cómo funciona (te puedes descargar los scripts y la base de datos en este enlace). Te ayudará a comprender la operativa de esta nueva funcionalidad del plugin.
Pingback: El editor de DataTables (V). Tablas con relaciones m-n (leer) – El desván de Jose