Para usar la datatable es necesario primero incluir los scripts y css (opción no adaptativa):
- 'jquery-x.xx.x.min.js'
- 'bootstrap.min.js'
- 'datatables.min.js'
- 'bootstrap.min.css'
- 'datatables.min.css' (opción no adaptativa)
O bien para la versión adaptativa:
- 'jquery-x.xx.x.min.js'
- 'bootstrap.min.js'
- 'datatables.min.js'
- 'dataTables.responsive.min.js'
- 'bootstrap.min.css'
- 'jquery.dataTables.min.css'
Cabe destacar que estos son los nombres para la versión 1.10.18 de datatables, versiones
posteriores difieren levemente en los nombres, pero conviene usar todos los archivos del
último distintos lanzamientos. y no mezclar
PARA QUE ESTE CÓDIGO SEA OPERATIVO DEBE AGREGARSE:
- VALIDACIÓN DE TODOS LOS INPUT.
- LIMPIEZA DE ' ' Y " " EN LOS ENVÍOS, JSON, Y SQL.
- BLOQUEAR BOTONES "EDITAR" Y "NUEVO REGISTRO" UNA VEZ CLICADOS PARA QUE NO SE CAMBIEN LOS
VALORES DE LOS INPUT HASTA TERMINAR LA FUNCIÓN SUCCESS.
- POR ESTÉTICA LOS DOS FORMS HACERLOS MODALES O APARECER/DESAPARECER SEGÚN CONVENGA.
Con
<script src='../scripts/xxxxxxx.min.js'> y
<LINK href='../scripts/datatables.min.css'
type=text/css rel=StyleSheet> por ejemplo.
Además crear la carpeta
DataTables-1.10.18 si estamos en esa versión, subcarpeta images y
copiar las imágenes de las flechitas.
Luego en el body ponemos una tabla, con id (en este caso
mitabla) y obligatoriamente de la clase display, por ejemplo:
<table id="mitabla" class="display"> y dentro solo la cabecera con
thead
las columnas con
th (ver código html).
Ahora por jquery inicializamos la tabla con una función donde determino primero el aspecto
general en:
$.extend( $.fn.dataTable.defaults, {........} ); con opciones como:
- searching: true,
- ordering: true,
- columnDefs: [{targets: 0,className: 'dt-body-center'}]
(Los detalles en el código)
Ahora cargamos los valores desde la base de datos por AJAX (ver el link "Ver código script PHP-AJAX" abajo
para el código PHP de devolución. Por seguridad todas las llamadas a la base de datos van por Procedures
que se cargan con los .sql
var tabla = $('#mitabla').DataTable({.......} ); Acá
hay dos secciones obligatorias:
- ajax: { }, con la llamada al script que devuelve el JSON
data en url:(detalles en AJAX )
-
La sección columns: [{ data: 'xxx1' },{ data: 'xxx2' }...]); con un subitem
por columna definida en el thead.
Si el atributo es data xxx , éste debe ser el nombre de cada índice en el JSON (Es cómodo entonces en el
script PHP volcar la salida de SQL a un vector con
$test[] = $registro; json_encode($test);)
lo cual hace que el índice coincida con el nombre del campo de la tabla en la base de datos.
Si debemos colocar imágenes o íconos entonces corresponde
{"render": function ()
{return "<img class='borrar' src='img/borrar.gif' style='cursor:pointer' />"}},
por ejemplo coloca una imagen para borrar el registro al clicar.
Si hay que combinar los datos con html
{data: "direccion",render: function (data) { return '<div >'+ data +'</div>';}},
Ahora si es necesario se le agregan funcionalidades, ver en VER TODO EL CODIGO
el código completo acá solo se comenta:
Seleccionar registro con cambio de color
Si la linea clicada esta seleccionada
$(this).hasClass('selected') se deselecciona con:
removeClass('selected'), si no se deselecciona la seleccionada y se selecciona la actual.
Botón borrar en las filas
-
La linea var cid=$(this).parents("tr").find("td").html(); busca la primer
columna (td) dentro de la filaactual (parents("tr")) y como allí esta el id de la tabla
de la base de datos se lo paso en data del AJAX.
-
El resto en un if (confirm('Confirmar borrado de registro: ' + cid)) {}
porque la operación no puede deshacerse.
-
Con var fila = tabla.row($(this).parents("tr")); guardo la fila que estoy
borrando, lo guardo aquí, porque dentro de success se pierde el valor (this).
-
En success (si PHP borró)fila.remove().draw(false); que borra la linea el draw(false)
hace que se redibuje en la página actual si hay paginación.
Botón editar en la tabla (carga los valores a editar)
El código es como sigue:
- Con var data1 = new Array(); declaramos un array genérico.
- La $(this).parents("tr").find("td").each(function(){})carga en el array el
contenido de cada celda del registro clicado con data1[i] =$(this).html();
- Usamos estos valores para copiar al form donde editar con
$('#id1').val(data1[0]); hasta el $('#fecha1').val(data1[4]);
- Ponemos el cursor en el primer input con $("#id1").first().focus();
- Finalmente pasamos el mensaje, a destacar que capturamos el id de la linea a editar con:
$(this).parents("tr").find("td").html() que toma el contenido del primer <td>
después del <tr>.
Botón editar registro (graba los valores editados)
El código:
-
Con var id = $('#id1').val(); y las lineas sucesivas, recupero los nuevos
valores que se puso en el form cargado con botón editar.
- La var envio se arma:'id=' + id + '&nombre=' + nombre + ... y así armamos el
post para el ajax.
- Mandamos el AJAX
-
En success tabla.$('tr.selected').find("td").each(function(){ });
busca el registro seleccionado (que es el que estamos editando).
- Finalmente el switch nos permite cambiar solo las celdas de 2° (index 1) a 5° (index 4) con
$(this).html(nombre campo);.
Botón nuevo registro (graba los valores nuevos)
Este código es similar a editar, la diferencia está en el success:
-
Con tabla.row.add({agregamos una fila, con los valores del array siguiente.
- id"id":datos, en datos PHP devuelve el id del registro insertado
(ver script PHP)
- El resto se copia de los valores del form (igual que editar
-
Finalmente la función: .draw(); que dibuja la fila.
1) Script JAVASCRIPT AJAX
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="../scripts/jquery-3.6.4.min.js"></script>
<script src="../scripts/bootstrap.min.js"></script>
<script src="../scripts/datatables.min.js"></script>
<script src="../scripts/dataTables.responsive.min.js" > </script>
<LINK href="../css/estilos.css" type=text/css rel=StyleSheet>
<LINK href="../scripts/jquery.dataTables.min.css" type=text/css rel=StyleSheet>
<title>DATATABLE, MANEJO</title>
<script>
$(document).ready( function () {
// defaults para todas las tablas
$.extend( $.fn.dataTable.defaults, {
searching: true,
ordering: true,
columnDefs: [
{
targets: 0,
className: 'dt-body-center'
},
{
targets: 6,
orderable: false
},
{
targets: 5,
orderable: false
}
]
} );
// inicializo tabla
var tabla = $('#mitabla').DataTable({
ajax: {
url: 'tec-php-datatable-procesar.php?accion=cargar',
dataSrc:''
},
columns: [
{ data: 'id' },
{ data: 'nombre' },
{ data: 'direccion' },
{ data: 'mail' },
{ data: 'fecha_nac' },
{"render": function () {
return "<img class='borrar' src='borrar.gif' style='cursor:pointer' />"
}},
{"render": function () {
return '<button type="button" id="bteditar" class="editar edit-modal btn btn-warning botonEditar"><span class="fa fa-edit"></span><span class="hidden-xs"> Editar</span></button>';
}}
]
});
//selecciono registro le cambio color
$('#mitabla tbody').on( 'click', 'tr', function () {
if ( $(this).hasClass('selected') ) {
$(this).removeClass('selected');
}
else {
tabla.$('tr.selected').removeClass('selected');
$(this).addClass('selected');
}
} );
//boton editar en la tabla (carga los valores a editar)
$('#mitabla tbody').on( 'click', 'button#bteditar', function () {
var data1 = new Array();
i=0;
$(this).parents("tr").find("td").each(function(){ //barremos los valores de cada celda y van al array data1
data1[i] =$(this).html();
i++;
});
$('#id1').val(data1[0]);
$('#nombre1').val(data1[1]);
$('#direccion1').val(data1[2]);
$('#email1').val(data1[3]);
$('#fecha1').val(data1[4]);
$("#id1").first().focus();
//$('#mensaje').html('Editando registro :' + $(this).parents("tr").find("td").html());
$('#mensaje').html('Editando registro :' + data1[0]);
} );
// boton editar registro (graba los valores editados)
$('#botoneditar').on( 'click', function () {
//recupero los valores editados
var id = $('#id1').val();
var nombre = $('#nombre1').val();
var direccion = $('#direccion1').val();
var email = $('#email1').val();
var fecha = $('#fecha1').val();
var envio = 'id=' + id + '&nombre=' + nombre + '&direccion=' + direccion + '&email=' + email + '&fecha=' + fecha;
$.ajax({ // edito el item en base de datos
type: "POST",
url: "tec-php-datatable-procesar.php?accion=editar",
data: envio,
dataType:'json',
success: function(data) {
if(data.indexOf('Error') != 0){
$('#mensaje').html('Se editó el registro: ' + id);
i=0;
tabla.$('tr.selected').find("td").each(function(){ //va pasando por tods las celdas
switch (i) {
case 1:
$(this).html(nombre);
break;
case 2:
$(this).html(direccion);
break;
case 3:
$(this).html(email);
break;
case 4:
$(this).html(fecha);
break;
}
i++;
});
}else{
$('#mensaje').html("No se pudo editar el registro:" + id);
}
},
error: function(request,error) {
$("#mensaje").html("error inesperado");
}
}); //fin ajax
});
// boton borrar
$('#mitabla tbody').on( 'click', 'img', function () {
var cid = $(this).parents("tr").find("td").html();
if (confirm('Confirmar borrado de registro: ' + cid)) {
var fila = tabla.row($(this).parents("tr")); //lo guardo aquí, dentro de success se pierde (this)
$.ajax({ // borro el item en base de datos
type: "POST",
url: "tec-php-datatable-procesar.php?accion=borrar",
data: 'cid=' + cid,
success: function(datos) {
if(datos.indexOf('Exito') == 0){
fila.remove().draw(false);
$('#mensaje').html('Borrado registro =' + cid);
}else{
$('#mensaje').html(datos);
}
},
error: function(request,error) {
$("#mensaje").html(request.responseText); //QUITAR ERROR DETALLADO
}
}); //fin ajax
}else{
$('#mensaje').html('Se canceló el borrado del registro:' + cid);
}
});
// boton nuevo registro
$('#agregar').on( 'click', function () {
//recupero los valores editados
//var id = $('#id').val();
var nombre = $('#nombre').val();
var direccion = $('#direccion').val();
var email = $('#email').val();
var fecha = $('#fecha').val();
var envio = 'nombre=' + nombre + '&direccion=' + direccion + '&email=' + email + '&fecha=' + fecha;
$.ajax({ // edito el item en base de datos
type: "POST",
url: "tec-php-datatable-procesar.php?accion=agregar",
data: envio,
success: function(datos) {
if(datos.indexOf('Error') != 0){
$('#mensaje').html('Se agregó el registro : ' + datos);
tabla.row.add({
"id":datos, //devuelto de PHP INSERT
"nombre":$('#nombre').val(),
"direccion":$('#direccion').val(),
"mail":$('#email').val(),
"fecha_nac":$('#fecha').val()
} ).draw();
}else{
$('#mensaje').html("No se pudo agregar el registro");
}
},
error: function(request,error) {
$("#mensaje").html(request.responseText); //QUITAR ERROR DETALLADO
}
}); //fin ajax
});
});
</script>
2) HTML
<head>
<style>
.titulo {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
color: #000;
text-align: center;
padding-left: 0px;
}
.recuadro{
width:95%;
margin: 0 auto;
margin-left:20px;
margin-right:20px;
margin-bottom: 20px;
padding:20px;
text-align:center;
border:#CCC solid 1px;
}
.colorhead{
color:#0033FF;
}
</style>
</head>
<body>
<div style="padding-top:20px;"> <!-- contenedor-->
<div class="recuadro">
<div style="margin-bottom:20px; margin-left:10px; ">
<div style="float:left; margin-right:10px; ">
<input name="id" id="id" type="input" style="width:40px;">
</div>
<div style="float:left; margin-right:10px; ">
<input name="nombre" id="nombre" type="input" style="width:100px;">
</div>
<div style="float:left; margin-right:10px; ">
<input name="direccion" id="direccion" type="input" style="width:100px;">
</div>
<div style="float:left; margin-right:10px; ">
<input name="email" id="email" type="input" style="width:100px;">
</div>
<div style="float:left; margin-right:10px; ">
<input name="fecha" id="fecha" type="input" style="width:100px;">
</div>
<div style="float:left;">
<input name="agregar registro" id="agregar" value="agregar registro" type="button">
</div>
<div style=" clear:both;"></div>
</div>
<!-- editar-->
<div id="editar" style="margin-bottom:20px; margin-left:10px; ">
<div style="float:left; margin-right:10px; ">
<input name="id1" id="id1" type="input" style="width:40px;">
</div>
<div style="float:left; margin-right:10px; ">
<input name="nombre1" id="nombre1" type="input" style="width:100px;">
</div>
<div style="float:left; margin-right:10px; ">
<input name="direccion1" id="direccion1" type="input" style="width:100px;">
</div>
<div style="float:left; margin-right:10px; ">
<input name="email1" id="email1" type="input" style="width:100px;">
</div>
<div style="float:left; margin-right:10px; ">
<input name="fecha1" id="fecha1" type="input" style="width:100px;">
</div>
<input name="ido" id="id0" type="hidden">
<div style="float:left;">
<input name="editar registro" id="botoneditar" value="editar registro" type="button">
</div>
<div style="float:left; margin-left:10px;" id="mensaje"> </div>
<div style=" clear:both;"></div>
</div>
</div> <!-- fin recuadro -->
<div class="recuadro">
<table id="mitabla" class="display">
<thead>
<tr>
<th>id</th>
<th>NOMBRE</th>
<th>DIRECCION</th>
<th>EMAIL</th>
<th>NACIMIENTO</th>
<th><input name="borrar" id="borrar" value="borrar" type="button"></th>
<th>edit</th>
</tr>
</thead>
</table>
</div><!-- fin contenedor tabla -->
</div> <!-- fin contenedor -->
</body>
3) Script PHP
<?php
include("conexion.php"); // abre la conexión a la base de datos
global $conn; //lo usamos en conexion, lo declaramos acá para no llamar siempre a $GLOBALS[]
$accion= $_GET["accion"];
Switch ($accion){
case "cargar":
$test= array();
if(conectar()){
$sqltxt = "SELECT id,nombre,direccion,mail,fecha_nac FROM clientes1";
$sqldevolucion = mysqli_query($conn,$sqltxt);
if (!mysqli_num_rows($sqldevolucion)) {
echo("Error, no se devuelven registros");
} else {
while ($r = mysqli_fetch_array($sqldevolucion, MYSQLI_ASSOC)){
$test[] = $r; // agrego a test[] cada registro como sub-array
} // fin while
echo json_encode($test); // lo paso a json y lo exporto
mysqli_free_result($sqldevolucion); //devuelvo recurso a memoria
mysqli_close($conn); // cierro conexion
}
}else{
echo(mysqli_error($conn));
} //fin if conectar
break;
// fin de CARGAR
case "editar":
$id= $_POST["id"];
$nombre= $_POST["nombre"];
$direccion= $_POST["direccion"];
$email= $_POST["email"];
$fecha_nac= $_POST["fecha"];
if(conectar()){
$sqltxt = "UPDATE clientes1 SET nombre = '".$nombre."', direccion = '".$direccion."', mail = '".$email."', fecha_nac = '".$fecha_nac."' WHERE id=" . $id;
$sqldevolucion = mysqli_query($conn,$sqltxt);
if($sqldevolucion){ //true si se produjo el update
echo json_encode("Exito");
}else{
echo json_encode("Error");
}
mysqli_close($conn); // cierro conexion
}else{
echo "No se puede abrir la base de datos";
} //fin if conectar
break;
case "agregar":
$nombre= $_POST["nombre"];
$direccion= $_POST["direccion"];
$email= $_POST["email"];
$fecha_nac= $_POST["fecha"];
if(conectar()){
$sqltxt = "INSERT INTO clientes1 (nombre,direccion,mail,fecha_nac) VALUES ('".$nombre."','".$direccion."','".$email."','".$fecha_nac."')";
$sqldevolucion = mysqli_query($conn,$sqltxt);
if($sqldevolucion){ //true si se produjo el insert
$sqltxt= "SELECT id FROM clientes1 ORDER BY id DESC LIMIT 1"; //busco el último id (el que acabamos de agregar)
$sqldevolucion1 = mysqli_query($conn,$sqltxt);
$r = mysqli_fetch_array($sqldevolucion1, MYSQLI_ASSOC);
echo $r["id"]; //lo devuelvo al AJAX
}else{
echo json_encode("Error");
}
mysqli_close($conn); // cierro conexion
}else{
echo "No se puede abrir la base de datos";
} //fin if conectar
break;
case "borrar":
$cid= $_POST["cid"];
if(conectar()){
$sqltxt = "DELETE FROM clientes1 WHERE id=" . $cid;
$sqldevolucion = mysqli_query($conn,$sqltxt);
mysqli_close($conn); // cierro conexion
echo "Exito";
}else{
echo "No se puede abrir la base de datos";
} //fin if conectar
break;
// fin de BORRAR
}
?>