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:

  • Definimos dos array $dayname y $monthname que contienen como valores los nombres de los días y meses respectivamente en nuestro idioma.
  • La función add_dates suma ó resta n días a una fecha determinada. Recibe la fecha en formato cadena dia-mes-año y devuelve en formato fecha mes-dia-año.
  • La función conexión, se sobreentiende. Hay que cambiar los valores de base datos, usuario y password por los nuestros.
  • La función add_event, agrega un nuevo registro a la tabla activity donde se registran todas nuestras tareas. Recibe como parámetro un array con los valores a guardar.
  • La función show_event, muestra todas las tareas de una fecha específica.

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:

  • Luego de crear una instancia de la clase, verificamos los valores recibidos por el método POST.
  • Debido a que la variable $_POST[‘date’] está en formato texto, debemos cambiarla a formato fecha propiamente dicho, y mediante mktime la creamos en formato UNIX.
  • Las variables siguientes extraen la parte de interes de la fecha UNIX. También la descripcion de la tarea contenida en la variable $_POST[‘descripcion’].
  • Usamos el método add_event para grabar los valores de las variables descritas. Si devuelve good todo está bien.

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:

  • La variable $_POST[‘date’] contiene la fecha en formato texto y, como en el proceso anterior, hay que pasarlo a formato fecha UNIX.
  • De la fecha UNIX obtenemos la fecha en formato año-mes-día.
  • Creamos una instancia de la clase y usamos el método show_event pasando como parámetro la fecha.
  • Usamos un bucle para desplegar las tareas del día si las hubiera.

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:

  • Creamos una instancia de la clase y también incluimos una referencia a los archivos JavaScript necesarios.
  • La variable $today contiene la fecha del día.
  • El primer bucle que vamos a usar es para crear los 7 días de la semana empezando con la fecha del día, además de la estructura CSS.
  • Hacemos uso del método add_dates para sumarle un d&
    iacute;a a la fecha actual en cada iteracióndel bucle.
  • En cada iteración de bucle se crean:
    • Una columna con un propio identificador.
    • Cada día con su nombre en la cabecera, mediante la propiedad dayname de la clase.
    • Fecha en formato "dia de Mes, Año".
    • Un array de cajas de texto con el nombre e id newactivity[] donde se escribirá las tareas del día.
    • Un array de cajas de texto oculto con el nombre e id date[] que contiene como valor la fecha de día.
    • Un div con su identificador activities… seguido del valor del contador: activities1, activities2, etc.
    • Realizar un segundo bucle para listar las tareas del día especificado.

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.