ABM CON DATATABLE (AJAX)
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:
  1. VALIDACIÓN DE TODOS LOS INPUT.
  2. LIMPIEZA DE ' ' Y " " EN LOS ENVÍOS, JSON, Y SQL.
  3. 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.
  4. 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
	}
?>
						
					
© IQSystems 2023