Tutorial: Aplicación web con jQuery, PHP, MySQL (Mantenimiento de datos)

En tutoriales anteriores explicabamos como combinar los lenguajes de servidor PHP y el gestor de base de datos MySQL con el objeto XMLHttpRequest (lo que hace posible AJAX) para llamadas asíncronas. Sin embargo hacer uso de manera tradicional de este objeto JavaScript es muy engorroso a la hora de codificar. Justamente la librerías JavaScript actuales han simplificado el trabajo. Es allí donde nos centraremos ahora. Haremos uso de la librería (que ha mi parecer es muy cómoda de usar) jQuery.

 aplicacion web jquery

aplicacion web jquery

Vamos a realizar un pequeño mantenimiento de datos de unos clientes, esto nos permitirá visualizar, agregar, modificar ó eliminar sus datos. Cómo siempre haremos uso de MySQL y PHP pues es la forma de probarlo en mi servidor web. La explicación que daré será de manera general (no entrare en muchos detalles), así que en los comentarios pueden plasmar sus dudas si lo desean. También quiero aclarar que no soy un experto en el uso de jQuery, solo sé algo de lo poco que leí de jQuery in Action, así que quizás en el código vaya a pecar de ignorante. Pero si tiene alguna crítica, espero lo hagan con la actituda adecuada.

Empecemos entonces con la tabla cliente, que tiene la siguiente estructura:

--
-- Estructura de tabla para la tabla `cliente`
--

CREATE TABLE IF NOT EXISTS `cliente` (
`id` tinyint(7) NOT NULL auto_increment,
`nombres` varchar(50) NOT NULL,
`ciudad` varchar(50) NOT NULL,
`sexo` char(1) NOT NULL,
`telefono` varchar(10) NOT NULL,
`fecha_nacimiento` datetime NOT NULL,
KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Vamos a crear dos clases en PHP: 1) para la conexión con el servidor y 2) una clase cliente, con cinco métodos básicos.

conexion.class.php

<?php 
class DBManager{
var $conect;

var $BaseDatos;
var $Servidor;
var $Usuario;
var $Clave;
function DBManager(){
$this->BaseDatos = "base-datos";
$this->Servidor = "localhost";
$this->Usuario = "user";
$this->Clave = "pwd";
}

function conectar() {
if(!($con=@mysql_connect($this->Servidor,$this->Usuario,$this->Clave))){
echo"<h1> [:(] Error al conectar a la base de datos</h1>";
exit();
}
if (!@mysql_select_db($this->BaseDatos,$con)){
echo "<h1> [:(] Error al seleccionar la base de datos</h1>";
exit();
}
$this->conect=$con;
return true;
}
}
?>

cliente.class.php

<?php 
include_once("conexion.class.php");

class Cliente{
//constructor
var $con;
function Cliente(){
$this->con=new DBManager;
}

function insertar($campos){
if($this->con->conectar()==true){
return mysql_query("INSERT INTO cliente (nombres, ciudad, sexo, telefono, fecha_nacimiento) VALUES ('".$campos[0]."', '".$campos[1]."','".$campos[2]."','".$campos[3]."','".$campos[4]."')");
}
}

function actualizar($campos,$id){
if($this->con->conectar()==true){
return mysql_query("UPDATE cliente SET nombres = '".$campos[0]."', ciudad = '".$campos[1]."', sexo = '".$campos[2]."', telefono = '".$campos[3]."', fecha_nacimiento = '".$campos[4]."' WHERE id = ".$id);
}
}

function mostrar_cliente($id){
if($this->con->conectar()==true){
return mysql_query("SELECT * FROM cliente WHERE id=".$id);
}
}

function mostrar_clientes(){
if($this->con->conectar()==true){
return mysql_query("SELECT * FROM cliente ORDER BY id DESC");
}
}

function eliminar($id){
if($this->con->conectar()==true){
return mysql_query("DELETE FROM cliente WHERE id=".$id);
}
}
}
?>

Los procesos básicos de un mantenimiento de datos los he separado en cada archivo: consulta.php, nuevo.php, actualizar.php, eliminar.php.

consulta.php

Este archivo se encarga de mostrar todos los clientes de la tabla, contienen un enlace a nuevo.php para agregar un nuevo cliente, además contiene dos enlaces para modificar y eliminar que enlazarán a los archivos actualizar.php y eliminar.php respectivamente, con sus variables GET (Ej. actualizar.php?id=40). También colocamos algo de JavaScript para estos dos enlaces.

<?php
require('clases/cliente.class.php');
$objCliente=new Cliente;
$consulta=$objCliente->mostrar_clientes();
?>
<script type="text/javascript">
$(document).ready(function(){
// mostrar formulario de actualizar datos
$("table tr .modi a").click(function(){
$('#tabla').hide();
$("#formulario").show();
$.ajax({
url: this.href,
type: "GET",
success: function(datos){
$("#formulario").html(datos);
}
});
return false;
});

// llamar a formulario nuevo
$("#nuevo a").click(function(){
$("#formulario").show();
$("#tabla").hide();
$.ajax({
type: "GET",
url: 'nuevo.php',
success: function(datos){
$("#formulario").html(datos);
}
});
return false;
});
});

</script>
<span id="nuevo"><a href="nuevo.php"><img src="img/add.png" alt="Agregar dato" /></a></span>
<table>
<tr>
<th>Nombres</th>
<th>Ciudad</th>
<th>Sexo</th>
<th>Telefono</th>
<th>Fecha Nacimiento</th>
<th></th>
<th></th>
</tr>
<?php
if($consulta) {
while( $cliente = mysql_fetch_array($consulta) ){
?>

<tr id="fila-<?php echo $cliente['id'] ?>">
<td><?php echo $cliente['nombres'] ?></td>
<td><?php echo $cliente['ciudad'] ?></td>
<td><?php echo $cliente['sexo'] ?></td>
<td><?php echo $cliente['telefono'] ?></td>
<td><?php echo $cliente['fecha_nacimiento'] ?></td>
<td><span class="modi"><a href="actualizar.php?id=<?php echo $cliente['id'] ?>"><img src="img/database_edit.png" title="Editar" alt="Editar" /></a></span></td>
<td><span class="dele"><a onClick="EliminarDato(<?php echo $cliente['id'] ?>); return false" href="eliminar.php?id=<?php echo $cliente['id'] ?>"><img src="img/delete.png" title="Eliminar" alt="Eliminar" /></a></span></td>
</tr>
<?php
}
}
?>
</table>

nuevo.php

Este archivo muestra un formulario donde escribiremos los datos del nuevo cliente, pero también actual cómo un proceso para agregar el cliente a la base de datos. Es por eso que primero evalua si existen definidas alguna variable POST. Si es así llama a la clase cliente y hace uso del método insertar. En la parte del formulario, en el evento onsubmit, llamamos a la función en JavaScript: GrabarDatos().

<?php
require('functions.php');
if(isset($_POST['submit'])){
require('clases/cliente.class.php');

$nombres = htmlspecialchars(trim($_POST['nombres']));
$ciudad = htmlspecialchars(trim($_POST['ciudad']));
$sexo = htmlspecialchars(trim($_POST['alternativas']));
$telefono = htmlspecialchars(trim($_POST['telefono']));
$fecha_nacimiento = htmlspecialchars(trim($_POST['fecha_nacimiento']));

$objCliente=new Cliente;
if ( $objCliente->insertar(array($nombres,$ciudad,$sexo,$telefono,$fecha_nacimiento)) == true){
echo 'Datos guardados';
}else{
echo 'Se produjo un error. Intente nuevamente';
}
}else{
?>
<form id="frmClienteNuevo" name="frmClienteNuevo" method="post" action="nuevo.php" onsubmit="GrabarDatos(); return false">
<p><label>Nombres<br />
<input class="text" type="text" name="nombres" id="nombres" />
</label>
</p>
<p>
<label>Ciudad<br />
<input class="text" type="text" name="ciudad" id="ciudad" />
</label>
</p>
<p>
<label>
<input type="radio" name="alternativas" id="masculino" value="M" />
Masculino</label>
<label>
<input type="radio" name="alternativas" id="femenino" value="F" />
Femenino</label>
</p>
<p>
<label>Telefono<br />
<input class="text" type="text" name="telefono" id="telefono" />
</label>
</p>
<p>
<label>Fecha Nacimiento <a onclick="show_calendar()" style="cursor: pointer;">
<small>(calendario)</small>
</a><br />
<input readonly="readonly" class="text" type="text" name="fecha_nacimiento" id="fecha_nacimiento" value="<?php echo date("Y-m-j")?>" />
<div id="calendario" style="display:none;"><?php calendar_html() ?></div>
</label>
</p>
<p>
<input type="submit" name="submit" id="button" value="Enviar" />
<label></label>
<input type="button" class="cancelar" name="cancelar" id="cancelar" value="Cancelar" onclick="Cancelar()" />
</p>
</form>
<?php
}
?>

actualizar.php

Este archivo, similar a nuevo.php, muestra un formulario con los datos del cliente seleccionado, pero también actual cómo un proceso para modificar los datos del cliente. Es por eso que primero evalua si existen definidas alguna variable POST. Si es así llama a la clase cliente y hace uso del método actualizar. En la parte del formulario, en el evento onsubmit, llamamos a la función en JavaScript: ActualizarDatos().

<?php
require('functions.php');
if(isset($_POST['submit'])){
require('clases/cliente.class.php');
$objCliente=new Cliente;

$cliente_id = htmlspecialchars(trim($_POST['cliente_id']));
$nombres = htmlspecialchars(trim($_POST['nombres']));
$ciudad = htmlspecialchars(trim($_POST['ciudad']));
$sexo = htmlspecialchars(trim($_POST['alternativas']));
$telefono = htmlspecialchars(trim($_POST['telefono']));
$fecha_nacimiento = htmlspecialchars(trim($_POST['fecha_nacimiento']));

if ( $objCliente->actualizar(array($nombres,$ciudad,$sexo,$telefono,$fecha_nacimiento),$cliente_id) == true){
echo 'Datos guardados';
}else{
echo 'Se produjo un error. Intente nuevamente';
}
}else{
if(isset($_GET['id'])){

require('clases/cliente.class.php');
$objCliente=new Cliente;
$consulta = $objCliente->mostrar_cliente($_GET['id']);
$cliente = mysql_fetch_array($consulta);
?>
<form id="frmClienteActualizar" name="frmClienteActualizar" method="post" action="actualizar.php" onsubmit="ActualizarDatos(); return false">
<input type="hidden" name="cliente_id" id="cliente_id" value="<?php echo $cliente['id']?>" />
<p>
<label>Nombres<br />
<input class="text" type="text" name="nombres" id="nombres" value="<?php echo $cliente['nombres']?>" />
</label>
</p>
<p>
<label>Ciudad<br />
<input class="text" type="text" name="ciudad" id="ciudad" value="<?php echo $cliente['ciudad']?>" />
</label>
</p>
<p>
<label>
<input type="radio" name="alternativas" id="masculino" value="M" <?php if($cliente['sexo']=="M") echo "checked=\"checked\""?> />
Masculino</label>
<label>
<input type="radio" name="alternativas" id="femenino" value="F" <?php if($cliente['sexo']=="F") echo "checked=\"checked\""?> />
Femenino</label>
</p>
<p>
<label>Telefono<br />
<input class="text" type="text" name="telefono" id="telefono" value="<?php echo $cliente['telefono']?>" />
</label>
</p>
<p>
<label>Fecha Nacimiento <a onclick="show_calendar()" style="cursor: pointer;"><small>(calendario)</small></a><br />
<input readonly="readonly" class="text" type="text" name="fecha_nacimiento" id="fecha_nacimiento" value="<?php echo $cliente['fecha_nacimiento'] ?>" />
<div id="calendario" style="display:none;"><?php calendar_html() ?></div>
</label>
</p>
<p>
<input type="submit" name="submit" id="button" value="Enviar" />
<label></label>
<input type="button" name="cancelar" id="cancelar" value="Cancelar" onclick="Cancelar()" />
</p>
</form>
<?php
}
}
?>

eliminar.php

Este archivo, como su nombre lo indica, se encarga de borrar los datos del cliente especificado.

<?php
require('clases/cliente.class.php');

$cliente_id=$_GET['id'];
$objCliente=new Cliente;
if( $objCliente->eliminar($cliente_id) == true){
echo "Registro eliminado correctamente";
}else{
echo "Ocurrio un error";
}
?>

Ahora veamos las funciones en JavaScript relacionadas con los procesos PHP que acabamos de explicar de manera general.

jQuery.functions.js

Las cuatro funciones ActualizarDatos(), ConsultaDatos(), EliminaDato() y GrabarDatos(), hacen llamadas AJAX, mediante la función $.ajax({...}) que nos proporciona jQuery. Cada función hace una llamada a los procesos en PHP respectivamente.

	function ActualizarDatos(){
var cliente_id = $('#cliente_id').attr('value');
var nombres = $('#nombres').attr('value');
var ciudad = $('#ciudad').attr('value');
var alternativas = $("input[@name='alternativas']:checked").attr("value");
var telefono = $("#telefono").attr("value");
var fecha_nacimiento = $("#fecha_nacimiento").attr("value");

$.ajax({
url: 'actualizar.php',
type: "POST",
data: "submit=&nombres="+nombres+"&ciudad="+ciudad+"&alternativas="+alternativas+"&telefono="+telefono+"&fecha_nacimiento="+fecha_nacimiento+"&cliente_id="+cliente_id,
success: function(datos){
alert(datos);
ConsultaDatos();
$("#formulario").hide();
$("#tabla").show();
}
});
return false;
}

function ConsultaDatos(){
$.ajax({
url: 'consulta.php',
cache: false,
type: "GET",
success: function(datos){
$("#tabla").html(datos);
}
});
}

function EliminarDato(cliente_id){
var msg = confirm("Desea eliminar este dato?")
if ( msg ) {
$.ajax({
url: 'eliminar.php',
type: "GET",
data: "id="+cliente_id,
success: function(datos){
alert(datos);
$("#fila-"+cliente_id).remove();
}
});
}
return false;
}

function GrabarDatos(){
var nombres = $('#nombres').attr('value');
var ciudad = $('#ciudad').attr('value');
var alternativas = $("input[@name='alternativas']:checked").attr("value");
var telefono = $("#telefono").attr("value");
var fecha_nacimiento = $("#fecha_nacimiento").attr("value");

$.ajax({
url: 'nuevo.php',
type: "POST",
data: "submit=&nombres="+nombres+"&ciudad="+ciudad+"&alternativas="+alternativas+"&telefono="+telefono+"&fecha_nacimiento="+fecha_nacimiento,
success: function(datos){
ConsultaDatos();
alert(datos);
$("#formulario").hide();
$("#tabla").show();
}
});
return false;
}
//esta funcion es para el boton cancelar del form
function Cancelar(){
$("#formulario").hide();
$("#tabla").show();
return false;
}

index.php

Finalmente todo esto aparecerá en nuestro archivo principal index.php, que tendrá la siguiente estructura:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Mantenimiento de Clientes</title>
<script src="js/jquery-1.3.1.min.js" type="text/javascript"></script>
<script src="js/jquery.functions.js" type="text/javascript"></script>
<link type="text/css" rel="stylesheet" href="css/estilo.css" />
</head>

<body>
<div id="contenedor">
<div id="formulario" style="display:none;">
</div>
<div id="tabla">
<?php include('consulta.php') ?>
</div>
</div>
<span style="text-align:center;width:300px;margin:auto;display:block;margin-top:20px;">RibosoMatic.com</span>
</body>
</html>

Hemos explicado el funcionamiento en general que tiene nuestra aplicación web, sin entrar en tantos detalles. Si tienes alguna duda escribe un comentario. Puedes descargar el demo con algunos arreglos, como CSS y un calendario en el formulario.

Update: 01.03.10

  • Corregido problema con caché en IE 8.

Descargar código fuente

Comentarios Comentarios formato RSS

  1. avatar dhamasito 2010-03-04 21:17:26 64 gracias esta muy bonito y muy funcional.
  2. avatar Luis Antonio 2010-03-04 11:46:20 63 Excelente aporte y gracias por solucionar el problemita del IE, saludos.
  3. avatar jesusvld 2010-03-01 21:49:10 62 Ok! El problema tiene que ver con los datos en cache del archivo consulta.php. Firefox carga por lo general las modificaciones recientes de una pagina web. Pero parece que IE7 y IE8 carga los datos guardados en cache. Es por eso que cuando le dan en guardar o actualizar muestra los datos de consulta.php que mostró cuando accedieron inicialmente a la aplicacion.

    Es se corrige consultando la documentación de jQuery sobre la configuración de peticiones Ajax: http://api.jquery.com/jQuery.ajax/

    Lo que hay que hacer es modificar el archivo jquery.functions.js en la funcion ConsultaDatos, y escribir la opción del objeto ajax: cache, en false.

    De esta forma se fuerza a la pagina requerida (en este caso consulta.php) no almacenarse en la cache del navegador.

    Finalmente quedaria asi:

    function ConsultaDatos(){
    $.ajax({
    url: 'consulta.php',
    cache: false,
    type: "GET",
    success: function(datos){
    $("#tabla").html(datos);
    }
    });
    }

    En tal caso tengo que corregir el articulo y el comprimido.


    Saludos y mil disculpas por contestar muy tarde.
  4. avatar Luis Antonio 2010-03-01 12:44:16 61 Woow! todo muy bien explicado y esta genial, es de gran ayuda, pero he leido que en mozilla funciona perfectamente y en IE no, nadie ha dado una respuesta por que no funciona, espero alguien sepa y conteste esta interrogante.

    Saludos.
  5. avatar Joan 2010-03-01 01:20:16 60 Esto esta de lujo, gracias por el aporte.

    Pero alguien a podido resolver xq no actualiza los datos despues de un insertar o actualizar???

    saludos y gracias.
  6. avatar samuel 2010-02-15 14:08:41 59 bueno lo probe me parece exelente este ejemplo...
  7. avatar Miguel Angel 2010-02-03 20:56:37 58 Muy bueno, pero seria bueno solucionaras el error de no mostrar la actualizacion o el agregar los datos de una persona en IE
  8. avatar LordNext 2010-01-30 12:31:13 57 Otra consulta. Se pueden guarda, y mostrar los datos de los campos respetando mayusculas y minusculas?

    Saludos.
  9. avatar jose 2010-01-21 02:45:42 56 Si pudiese paginar, filtrar y ordenar columnas como el plugin datatable de JQUERY sería fantastico. Por lo que he leido algunos de este foro lo han conseguido con el ejemplo webapp.zip ¿alguien nos ayuda?
    Gracias
  10. avatar LordNext 2010-01-12 09:45:33 55 Modifique el codigo para adaptarlo a un sistema de gestion de promociones.

    Mi problema es que, a los dos ultimos campos quiero habilitarles el calendario. Ya que serian la fecha de inicio y de finalizacion de las promociones.
    Para ello, duplique los campos en actualizacion y nuevo. Y duplique las funciones en functions y jquery.functions.js . Tanto a las funciones duplicadas como a las variables les agregue un 2 para diferenciarlas, asi tambien como a los div, etc.
    Mi problema es que ahora no me funcionan los calendarios, al hacer click en un dia especifico en el calendario 2, me guarda la modificacion en el calendario 1, pero con otra fecha.

    espero puedan darme una mano.

Dejar un comentario