Calendario dinámico con JavaScript, sin bibliotecas externas

Una vez más aquí. Hoy vengo a dejar un pequeño artículo relacionado con una petición de un usuario. Este me decía que necesitaba crear una calendario dinámico con JavaScript. Cuando este usuario me preguntaba por calendario dinámico, me imagino que se refería a poder ir pasando los meses mediante botones o enlaces. Y esto es lo que vamos a ver en las siguientes líneas.

Según me comentaba el usuario, la idea es hacer un calendario que dinámico que te permita guardar anotaciones en cada uno de los días. Pero esto último ya no lo voy a hacer, aun que se podría hacer fácilmente con PHP.

Como todo el mundo sabe, un calendario no deja de ser es un gráfico que nos va a mostrar el día, las semanas y los meses de un año en particular. Los calendarios son un buen soporte para ayudarnos a recordar eventos importantes. Pero como decía, esta opción de guardar eventos, ya tendrá que hacerlo el usuario que solicita el ejercicio (que la nota no me la voy a llevar yo).

Al final de este ejercicio, obtendremos un calendario dinámico, en el que los usuarios podrán ver la fecha y el día actual. También nos va permitir ver los días del mes presente, pasado o futuro. Todo esto se hace con JavaScript, sin necesidad de utilizar una biblioteca externa para ello.

Calendario dinámico con JavaScript, HTML y CSS

Para esta una aplicación de calendario dinámico usando HTML CSS y JavaScript, vamos a comenzar por crear una carpeta en la que incluir los archivo que van a formar parte del proyecto. Puede poner cualquier nombre a esta carpeta.

Archivo index.html

El siguiente paso va a ser crear un archivo index.html. El nombre del archivo debe ser index y su extensión .html. Aquí será donde crearemos la estructura de nuestro calendario.

<!DOCTYPE html>
<html lang="es">

<head>
  <meta charset="utf-8" />
  <title>Calendario con JavaScript</title>
  <link rel="stylesheet" href="style.css" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <!-- Necesario para las puntas de flecha que cambian de mes -->
  <link rel="stylesheet"
    href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />

</head>

<body>
  <div class="envoltorio"> <!-- envoltorio para el calendario -->
    <div class="titulo">Calendario JS</div>
    <header>
      <p class="fecha-actual"></p> <!-- mostramos el mes y el año actual -->
      <div class="iconos">
        <span id="prev" class="material-symbols-rounded" title="Atrás">chevron_left</span>
        <span id="next" class="material-symbols-rounded" title="Adelante">chevron_right</span>
      </div>
    </header>
    <hr/>
    <div class="calendario">
      <ul class="semana"> <!-- cabecera de la semana -->
        <li>LU</li>
        <li>MA</li>
        <li>MI</li>
        <li>JU</li>
        <li>VI</li>
        <li>SA</li>
        <li class="domingo">DO</li>
      </ul>
      <ul class="dias"></ul><!-- contenedor para mostrar los días -->
    </div>
  </div>
  <script src="script.js" defer></script> <!-- cargamos el script para crear el calendario -->
</body>

</html>

Archivo style.css

Continuaremos creando un archivo para los estilos css. El nombre del archivo debe ser style y su extensión .css. Aquí será donde añadiremos las reglas para darle un aspecto «bonico» a nuestro calendario.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Poppins", sans-serif;
}

body {
  display: flex;
  align-items: center;
  padding: 0 10px;
  justify-content: center;
  min-height: 100vh;
  background: #eeeeee;
}

/*Links*/
a:link,
a:visited,
a:active {
  text-decoration: none;
}

/*Título*/
.titulo {
  display: inline-block;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  padding: 10px;
  border: none;
  font: normal 38px / normal "Warnes", Helvetica, sans-serif;
  color: rgba(255, 255, 255, 1);
  text-decoration: normal;
  text-align: center;
  -o-text-overflow: clip;
  text-overflow: clip;
  white-space: pre;
  text-shadow: 0 0 10px rgb(255, 0, 0), 0 0 20px rgba(255, 0, 0),
    0 0 30px rgba(255, 0, 0), 0 0 40px #727272, 0 0 70px #727272,
    0 0 80px #4e4e4e, 0 0 100px #2b2b2b;
  -webkit-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1);
  -moz-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1);
  -o-transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1);
  transition: all 200ms cubic-bezier(0.42, 0, 0.58, 1);
  text-align: center;
  width: 100%;
  margin-top: 10px;
}

.titulo:hover {
  text-shadow: 0 0 10px rgb(27, 27, 27), 0 0 20px rgba(27, 27, 27),
    0 0 30px rgba(27, 27, 27), 0 0 40px #000000, 0 0 70px #000000,
    0 0 80px #000000, 0 0 100px #000000;
}

/*Envoltorio del calendario*/
.envoltorio {
  width: 450px;
  background: #fff;
  border-radius: 10px;
  box-shadow: 5px 5px 40px;
}

.envoltorio header {
  display: flex;
  align-items: center;
  padding: 25px 30px 10px;
  justify-content: space-between;
}

/*Iconos*/
header .iconos {
  display: flex;
}

header .iconos span {
  height: 38px;
  width: 38px;
  margin: 0 1px;
  cursor: pointer;
  color: #000000;
  text-align: center;
  line-height: 38px;
  font-size: 2rem;
  user-select: none;
  border-radius: 50%;
  font-weight: bold;
}

.iconos span:last-child {
  margin-right: -10px;
}

header .iconos span:hover {
  background: #f2f2f2;
}

/*Fecha actual*/
header .fecha-actual {
  font-size: 1.45rem;
  font-weight: bold;
}

/*Días*/
.calendario .dias li {
  z-index: 1;
  cursor: pointer;
  position: relative;
  margin-top: 30px;
}

.dias li.inactive {
  color: #aaa;
}

.dias li.active {
  color: #fff;
}

.dias li::before {
  position: absolute;
  content: "";
  left: 50%;
  top: 50%;
  height: 40px;
  width: 40px;
  z-index: -1;
  border-radius: 50%;
  transform: translate(-50%, -50%);
}

.dias li.active::before {
  background: #9b59b6;
}

.dias li:not(.active):hover::before {
  background: #f2f2f2;
}

.domingo {
  color: rgb(255, 0, 0) !important;
}

/*calendario*/
.calendario {
  padding: 20px;
}

.calendario ul {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
  text-align: center;
}

.calendario .dias {
  margin-bottom: 20px;
}

.calendario li {
  color: #333;
  width: calc(100% / 7);
  font-size: 1.07rem;
}

.calendario .semana li {
  font-weight: 500;
  cursor: default;
  background-color: #cecece;
  border-radius: 10%;
  border: 1px solid #000;
}

Archivo script.js

Este es el archivo necesario para dibujar nuestro calendario será el que crearemos con el nombre de script.js. El nombre del archivo debe ser script y su extensión .js. En este archivo será en el que sucederá todo lo necesario para que podamos interactuar con el calendario.

// obtener fecha, año y mes actuales
let date = new Date(),
    currYear = date.getFullYear(),
    currMonth = date.getMonth();

const TagDias = document.querySelector(".dias"),
    fechaActual = document.querySelector(".fecha-actual"),
    prevNextIcon = document.querySelectorAll(".iconos span");

// almacenamos los meses en la matriz
const meses = [
    "Enero",
    "Febrero",
    "Marzo",
    "Abril",
    "Mayo",
    "Junio",
    "Julio",
    "Agosto",
    "Septiembre",
    "Octubre",
    "Noviembre",
    "Diciembre",
];

const renderCalendar = () => {
    let primerDiaMes = new Date(currYear, currMonth, 0).getDay(), // obtenemos el primer día del mes. El 0 hace que el primer día de la semana sea lunes
        ultimaFechaMes = new Date(currYear, currMonth + 1, 0).getDate(), // obtenemos la última fecha del mes
        ultimoDiaMes = new Date(currYear, currMonth, ultimaFechaMes).getDay(), // obtenemos el último día del mes
        ultimaFechaMesPasado = new Date(currYear, currMonth, 0).getDate(); // obtenemos la última fecha del mes anterior
    let liTag = "";

    for (let i = primerDiaMes; i > 0; i--) {
        // creamos los li del mes anterior. Para mostrar los últimos días
        liTag += `<li class="inactive">${ultimaFechaMesPasado - i + 1}</li>`;
    }

    for (let i = 1; i <= ultimaFechaMes; i++) {   

        // creamos el li de todos los días del mes actual
        // añadimos la clase como activa al li si el día, mes y año actuales coinciden. Se incluye en el día actual 
        let esHoy =
            i === date.getDate() &&
                currMonth === new Date().getMonth() &&
                currYear === new Date().getFullYear()
                ? "active"
                : "";

        liTag += `<li class="${esHoy}"><a href="javascript:popUp('ventana.html')">${i}</a></li>`;
         
    }

    for (let i = ultimoDiaMes; i < 7; i++) {
        // creamos el li del próximo mes. Se muestran los primeros días del mes
        liTag += `<li class="inactive">${i - ultimoDiaMes + 1}</li>`;
    }
    fechaActual.innerText = `${meses[currMonth]} ${currYear}`; // pasando el mes y el año actuales como texto de fecha actual. Se muestra en la parte superior del calendario
    TagDias.innerHTML = liTag;
};
renderCalendar();

prevNextIcon.forEach((icon) => {
    // iconos anterior y siguiente
    icon.addEventListener("click", () => {
        // añadimos evento de clic en ambos íconos
        // si el icono en el que se hizo clic es el icono anterior, disminuimos el mes actual en 1; de lo contrario, se incrementa en 1
        currMonth = icon.id === "prev" ? currMonth - 1 : currMonth + 1;

        if (currMonth < 0 || currMonth > 11) {
            // si el mes actual es menor que 0 o mayor que 11
            // creamos una nueva fecha del año y mes actual, para pasarla como valor de fecha
            date = new Date(currYear, currMonth);
            currYear = date.getFullYear(); // actualizamos el año actual con nueva fecha año
            currMonth = date.getMonth(); // actualizamos el mes actual con el nuevo mes de fecha
        } else {
            date = new Date(); // pasar la fecha actual como valor de fecha
        }
        renderCalendar(); // llamamos a la función renderCalendar
    });
});

// función para abrir el popup al hacer clic sobre un día
function popUp(URL) {
    window.open(URL, 'Día', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=1,width=300,height=300,left=390,top=50');
}

Archivo ventana.html

Este archivo solo contiene un poco de html para mostrar un mensaje. Este archivo será que se abrirá cuando hagamos clic sobre alguno de los días del calendario. Aquí sería donde se podría crear un sistema para guardar nuestros eventos en una base de datos. Solo es cosa de dedicarle un poco de tiempo.

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Ventana</title>
    <script src="script.js"></script>
</head>
<body>
    
<p>Aquí se podría añadir un formulario para guardar cosas que hacer cada día a una base de datos.</p>
</body>
</html>

Y una vez que tengamos cada uno de los códigos aquí mostrados, dentro de su correspondiente archivo, solo queda guardarlos. Después para ejecutar el calendario, basta con hacer doble clic en el archivo index.html, y esperar que se abra en el navegador web.

Con esto hemos creado con éxito una aplicación de calendario dinámico con JavaScript, HTML y CSS. Para ver en funcionamiento este calendario, basta con visitar el siguiente enlace.

Post relacionados

Tarjeta con efecto 3D, crea la tuya con HTML y un poco de CSS

Aceele Hub USB 3.0 con 4 puertos y 1.2m de cable

Generador de degradados. Crea el tuyo con JavaScript

2 Comentarios

PedroVMV 18 enero, 2023 - 12:48 PM
Gracias por el código. Lo de la conexión a la BD se puede hacer con JavaScript?
entreunosyceros 18 enero, 2023 - 1:08 PM
Hola. Supongo que si, pero me parece que lo más sencillo sería hacer la conexión a la base de datos con PHP. Pero bueno, eso ya es cuestión de lo que a cada uno le vaya mejor. Espero que te resulte útil. Salu2 y gracias por el comentario.
Añadir comentario