Site icon RibosoMatic

To-Do List (lista de tareas) con jQuery, PHP, MySQL, AJAX (pt. 1)

Inspirandome en TeuxDeux un administrador de tareas sencillo pero eficaz que corre perfectamente sobre el navegador web (vía Ajaxian), se me ocurrió realizar uno con similar funcionalidad. En realidad no he probado esta herramienta, pues hay que registrarse (y no quize demorar) así que me guié del video relacionado:

[vimeo]8080943[/vimeo]

Está es la primera parte, así que no verán algo muy sofisticado pero si funcionalmente básico.

<<VER EL EJEMPLO>>

Empecemos definiendo la estructura de la tabla en MySQL que guardará la información de las tareas del día:

CREATE TABLE IF NOT EXISTS `activity` (
`id` int(11) NOT NULL auto_increment,
`fecha` datetime NOT NULL,
`dia` tinyint(2) NOT NULL,
`nrodiasemana` tinyint(2) NOT NULL,
`mes` tinyint(2) NOT NULL,
`descripcion` varchar(300) NOT NULL,
`completado` tinyint(1) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=0;

Como apreciarán le damos mucha atención a los campos relacionados con la fecha: número del día, número del día dentro de la semana, número del mes y obviamente la fecha en sí en formato largo, aunque no usaremos la parte del tiempo.

En PHP creamos una clase con algunos propiedades y métodos que nos simplificará el código y podremos usar en otros procesos más adelante.

<?php
class todo{

var $dayname = array('Domingo','Lunes','Martes','Miercoles','Jueves','Viernes','Sabado');

var $monthname = array(1=>'Enero',2=>'Febrero',3=>'Marzo',4=>'Abril',5=>'Mayo',6=>'Junio',7=>'Julio',8=>'Agosto',9=>'Septiembre',10=>'Octubre',11=>'Noviembre',12=>'Diciembre');

function todo(){
//constructor
}

function add_dates($date,$ndays){
if (preg_match("/[0-9]{1,2}\/[0-9]{1,2}\/([0-9][0-9]){1,2}/",$date))
list($day,$month,$year)=split("/", $date);


if (preg_match("/[0-9]{1,2}-[0-9]{1,2}-([0-9][0-9]){1,2}/",$date))
list($day,$month,$year)=split("-",$date);

$new = mktime(0,0,0, $month,$day,$year) + $ndays * 24 * 60 * 60;
$newdate=date($new);

return ($newdate);
}

private function conexion() {
if(!($con=@mysql_connect("localhost","root",""))){
echo"Error al conectar a la base de datos";
exit();
}
if (!@mysql_select_db("base_datos",$con)) {
echo "Error al seleccionar la base de datos";
exit();
}
return true;
}

function add_event($field){
if($this->conexion()==true){
return mysql_query("INSERT INTO activity (fecha, dia, nrodiasemana, mes, descripcion, completado) VALUES ('".$field[0]."', ".$field[1].",".$field[2].",".$field[3].",'".$field[4]."',".$field[5].")");
}
}

function show_event($fecha){
if($this->conexion()==true){
return mysql_query("SELECT * FROM activity WHERE fecha='".$fecha."'");
}
}
}
?>

Expliquemos brevemente:

Ahora vamos a los procesos independientes que harán uso de la clase creada. Uno de estos procesos es agregar un nueva tarea a la lista. El archivo addevent.php contiene lo siguiente:

<?php
require("class/todo.class.php");
$objtodo=new todo;

if(isset($_POST['submit'])){
$fecha_texto = $_POST['date']; // fecha en formato texto
if (preg_match("/[0-9]{1,2}-[0-9]{1,2}-([0-9][0-9]){1,2}/",$fecha_texto))
list($month,$day,$year)=split("-",$fecha_texto); // extraer valores para convertir a fecha Unix

$fechaUnix = mktime(0,0,0, $month,$day,$year);

$fecha = date('Y-m-d',$fechaUnix);
$dia = date('d',$fechaUnix);
$nrodiasemana = date('w',$fechaUnix);
$mes = date('m',$fechaUnix);
$descripcion = $_POST['descripcion'];
$completado = 0;

if($objtodo->add_event(array($fecha,$dia,$nrodiasemana,$mes,$descripcion,$completado))==true)
echo 'good';
else
echo 'error';
}
?>

Explicación:

Otro proceso independiente que usaremos es showeventday.php que mostrará ó listará todos las tareas de una fecha específica.

<?php
$fecha_texto = $_POST['date'];

if (preg_match("/[0-9]{1,2}-[0-9]{1,2}-([0-9][0-9]){1,2}/",$fecha_texto))
list($month,$day,$year)=split("-",$fecha_texto); // extraer valores para convertir a fecha Unix

$fechaUnix = mktime(0,0,0, $month,$day,$year);
$fecha = date('Y-m-d',$fechaUnix);

require("class/todo.class.php");
$objtodo=new todo;

$consulta = $objtodo->show_event($fecha);
while( $tareas= mysql_fetch_array($consulta) ){
?>
<span class="activity">
<?php echo $tareas['descripcion'] ?>
</span>
<?php
}
?>

Una breve explicación:

De momento estos dos procesos usaremos. En la segunda parte veremos la modificación y eliminación de tareas, aunque estos dos procesos ya nos dan una idea de cómo poder hacerlo.

Vamos ahora a la parte de JavaScript. Esta lista de tareas hace uso de jQuery, así que este archivo functions.js contiene funciones y proceso que nos ayudan con las peticiones AJAX. Veamos:

$(document).ready(function(){

$("input[name^=newactivity]").keypress(function (e) {
if(e.keyCode == 13){
var descripcion = $(this).attr('value');
// capturar indice de input newactivity
var element_id = $("input[name^=newactivity]").index(this);
//capturar fecha de campo oculto
var date = $("#date\\["+(element_id+1)+"\\]").attr('value');

$.ajax({
url: 'addevent.php',
type: "POST",
data: "submit=&date="+date+"&descripcion="+descripcion,
success: function(datos){
ShowEventDay(date,element_id+1);
$("input[name^=newactivity]").attr("value","");
}
});
$(this).focus();
}
});

});

function ShowEventDay(date,div_id){
$.ajax({
url: 'showeventday.php',
type: "POST",
data: "date="+date,
success: function(datos){
$("#activities"+div_id).html(datos);
}
});
}

Explicamos:

Finalmente, el archivo index.php contiene lo siguiente:

<?php 
require("class/todo.class.php");
$objtodo=new todo;
?>
<!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>Lista de tareas</title>
<link type="text/css" rel="stylesheet" href="main.css" />
<script type="text/javascript" src="js/JQuery.js"></script>
<script type="text/javascript" src="js/functions.js"></script>

</head>

<body>
<div id="main-days">
<?php
$today = date("d-m-Y"); //fecha de hoy
$i=1;
while($i<=7){
$date = $objtodo->add_dates($today, $i-1); //fecha de hoy + 1
$numdayweek = date("w",$date); //numero de dia de la semana
$numday = date("d",$date); // día del mes
$nummonth = date("n",$date); // numero del mes
$year = date("Y",$date); //año
?>
<div class="cols" id="col<?php echo $i?>">
<span class="dayname" <?php if($i==1) echo 'style="color:#006600;"'?> > <?php echo $objtodo->dayname[$numdayweek] ?></span>
<span class="datelong"><?php echo $numday." de ".$objtodo->monthname[$nummonth].", ".$year; ?></span>
<div class="list">
<span class="newactivity">
<input type="text" id="newactivity[<?php echo $i?>]" name="newactivity[<?php echo $i?>]" />
<input type="hidden" id="date[<?php echo $i?>]" name="date[<?php echo $i?>]" value="<?php echo date("m-d-Y",$date) ?>" />
</span>
<div id="activities<?php echo $i?>">
<?php
$consulta = $objtodo->show_event(date("Y-m-d",$date));

while( $tareas= mysql_fetch_array($consulta) ){
?>
<span class="activity">
<?php echo $tareas['descripcion'] ?>
</span>
<?php
}
?>
</div>
</div>
</div>

<?php
$i++;
}
?>
</div>
</body>
</html>

Expliquemos brevemente:

Está aplicación ha sido probada en IE8, Firefox 3.5.6, Opera 9.64 y Google Chrome sin ningún problema. 

Para tener una mejor idea de su funcionamiento puedes descargar los archivos de la aplicación y probarlos en tu servidor web local.

Atentos a la segunda parte del tutorial donde agregamos algunas funcionalidades extra para mejorar esta aplicación.