Creación de los días del calendario

  • Por
Parte en la que crearemos todas las capas de los días de un mes en el calendario y realizamos varias funciones Javascript relacionadas con fechas.
Hasta ahora en el Manual del Calendario jQuery hemos avanzado hasta el punto que nuestro calendario se abre, pero sólo aparecen las letras de los días de la semana. En esta parte de nuestra práctica vamos a generar todos los días del mes actual.

Esta parte, aparte del propio trabajo para generar todas las etiquetas HTML para cada día del mes, implicará trabajar un poco con fechas en Javascript, pues tendremos que realizar algunas funciones, para averiguar cosas como los días de un mes dado, o en qué día de la semana cae determinado día de un mes.

El ejemplo, tal y como quedará con estas modificaciones se puede ver en el siguiente enlace.

Veamos primero las funciones locales al plugin que hemos realizado, recordando que esto de las funciones dentro de plugins sirve para ocultarlas al código de otros scripts o componentes jQuery.

Función para calcular el día de la semana

Hacemos una función Javascript que recibe un día, mes y año y devuelve el número de día de la semana que era, comenzando en 0 para el lunes y acabando en 6 para domingo. Hacemos un tratamiento porque para los españoles, el primer día de la semana en los calendarios se coloca en el lunes.

//función para calcular el número de un día de la semana
function calculaNumeroDiaSemana(dia,mes,ano){
   var objFecha = new Date(ano, mes, dia);
   var numDia = objFecha.getDay();
   if (numDia == 0)
      numDia = 6;
   else
      numDia--;
   return numDia;
}

Función para saber si una fecha es correcta

Una función que recibe un mes, día y año y nos informa si esa combinación hace un día correcto del calendario. Por supuesto, controla cualquier asunto como si el año es bisiesto.

Nota: Esta función la hemos sacado de las librerías php.js (Funciones de PHP en Javascript).

//función para ver si una fecha es correcta
function checkdate ( m, d, y ) {
   // función por http://kevin.vanzonneveld.net
   // extraida de las librerías phpjs.org manual en http://www.desarrolloweb.com/manuales/manual-librerias-phpjs.html
   return m > 0 && m < 13 && y > 0 && y < 32768 && d > 0 && d <= (new Date(y, m, 0)).getDate();
}

Función para saber el último día de un mes y año dados

Una función Javascript que me sirve para saber el número de días máximo de un mes. Utiliza la función anterior checkdate() para poder averiguar ese dato.

//funcion que devuelve el último día de un mes y año dados
function ultimoDia(mes,ano){
   var ultimo_dia=28;
   while (checkdate(mes+1,ultimo_dia + 1,ano)){
      ultimo_dia++;
   }
   return ultimo_dia;
}

Función mostrarCalendario() del plugin jQuery

Hasta el momento, así tenemos la función mostrarCalendario(), una vez que hemos incorporado todo el código parar generar las capas con los días del mes.

//función para mostrar el calendario
function mostrarCalendario(){
   if(!mostrando){
      mostrando = true;
      //es que hay que mostrar el calendario
      //dias de la semana
      var capaDiasSemana = $('<div class="diassemana"></div>');
      var dias = ["l", "m", "x", "j", "v", "s", "d"];
      $(dias).each(function(indice, valor){
         var codigoInsertar = '<span';
         if (indice==0){
            codigoInsertar += ' class="primero"';
         }
         if (indice==6){
            codigoInsertar += ' class="domingo ultimo"';
         }
         codigoInsertar += ">" + valor + '</span>';
         
         capaDiasSemana.append(codigoInsertar);
      });
      
      //muestro los días del mes
      var contadorDias = 1;
      var capaDiasMes = $('<div class="diasmes"></div>')
      //un objeto de la clase date para calculo de fechas
      var objFecha = new Date()
      //mes y año actuales
      var mes = objFecha.getMonth();
      var ano = objFecha.getFullYear();
      //calculo la fecha del primer día de este mes
      var primerDia = calculaNumeroDiaSemana(1, mes, ano);
      //calculo el último día del mes
      var ultimoDiaMes = ultimoDia(mes,ano);
      
      //escribo la primera fila de la semana
      for (var i=0; i<7; i++){
         if (i < primerDia){
            //si el dia de la semana i es menor que el numero del primer dia de la semana no pongo nada en la celda
            var codigoDia = '<span class="diainvalido';
            if (i == 0)
               codigoDia += " primero";
            codigoDia += '"></span>';
         } else {
            var codigoDia = '<span';
            if (i == 0)
               codigoDia += ' class="primero"';
            if (i == 6)
               codigoDia += ' class="ultimo"';
            codigoDia += '>' + contadorDias + '</span>';
            contadorDias++;
         }
         var diaActual = $(codigoDia);
         capaDiasMes.append(diaActual);
      }
      
      //recorro todos los demás días hasta el final del mes
      var diaActualSemana = 1;
      while (contadorDias <= ultimoDiaMes){
         var codigoDia = '<span';
         //si estamos a principio de la semana escribo la clase primero
         if (diaActualSemana % 7 == 1)
            codigoDia += ' class="primero"';
         //si estamos al final de la semana es domingo y ultimo dia
         if (diaActualSemana % 7 == 0)
            codigoDia += ' class="domingo ultimo"';
         codigoDia += '>' + contadorDias + '</span>';
         contadorDias++;
         diaActualSemana++;
         var diaActual = $(codigoDia);
         capaDiasMes.append(diaActual);
      }
      
      //compruebo que celdas me faltan por escribir vacias de la última semana del mes
      for (var i=(diaActualSemana%7); i<=7; i++){
         var codigoDia = '<span class="diainvalido';
         if (i==7)
            codigoDia += ' ultimo'
         codigoDia += '"></span>';
         var diaActual = $(codigoDia);
         capaDiasMes.append(diaActual);
      }
      
      //calendario
      calendario = $('<div class="capacalendario"></div>');
      var calendarioBorde = $('<div class="capacalendarioborde"></div>');
      calendario.append(calendarioBorde);
      calendarioBorde.append(capaDiasSemana);
      calendarioBorde.append(capaDiasMes);
      
      //inserto el calendario en el documento
      $(document.body).append(calendario);
      //lo posiciono con respecto al boton
      calendario.css({
         top: boton.offset().top + "px",
         left: (boton.offset().left + 20) + "px"
      })
      //muestro el calendario
      calendario.show("slow");
      
   }else{
      //es que el calendario ya se estaba mostrando...
      calendario.fadeOut("fast");
      calendario.fadeIn("fast");
      
   }
}

El código ha avanzado bastante y se ha complicado un poquito. Está comentado para que se pueda entender mejor. Luego tendremos que partir todo ese código en algunas funciones. Pero de momento es suficiente.

Nota: Hasta el momento, el calendario siempre muestra el mes y año actual. Si quisiéramos que cambiase el mes que se está mostrando simplemente tendríamos que cambiar la hora de nuestro sistema operativo.

Podemos ver el ejemplo en marcha para verificar cómo ha quedado hasta aquí.

En el próximo artículo complicaremos un poco la cosa, para conseguir que se muestre cualquier mes de cualquier año y se incorpore una pequeña utilidad para la navegación entre meses.