Los calendarios se han convertido en una parte indispensable de las aplicaciones web modernas, ya que permiten a los usuarios organizar, programar y rastrear eventos de forma sencilla. Ya sea que estés construyendo una herramienta de gestión de proyectos, una aplicación de programación de eventos o una suite de productividad personal, un componente de calendario personalizado puede mejorar enormemente la experiencia del usuario. Aunque existen numerosas bibliotecas de calendarios preconstruidas, crear tu propio componente puede proporcionar la flexibilidad para cumplir con requisitos específicos de diseño y funcionalidad.
En este tutorial, exploraremos cómo construir un componente similar a Google Calendar utilizando JavaScript. Al final de esta guía, tendrás un calendario totalmente funcional con funciones interactivas y un entendimiento más profundo de cómo construir componentes reutilizables para tus aplicaciones web. Ya seas un desarrollador que busca añadir un toque único a tu proyecto o alguien ansioso por aprender el funcionamiento interno de las funcionalidades de calendario, este paso a paso será invaluable. ¡Comencemos!
Resumen
Crearemos un componente de calendario con las siguientes características:
- Eje de Tiempo: Una línea de tiempo vertical de 12 AM a 11 PM.
- Bloques de Eventos: Eventos renderizados dinámicamente con posición y altura adecuadas basadas en sus horas de inicio y fin.
- Manejo de Superposiciones: Los eventos que se superponen en el tiempo aparecerán uno al lado del otro.
Así es como puedes crear este componente paso a paso.
Guía Paso a Paso
1. Configurar el HTML y Estilos Básicos
Comenzamos creando una estructura de HTML mínima para el calendario. El diseño incluye una línea de tiempo y un contenedor para eventos.
<div class="calendar">
<div class="calendar-time">
<ul id="timelist" class="calendar-timelist"></ul>
</div>
<div id="events" class="calendar-events"></div>
</div>
Agrega CSS básico para estilizar el calendario:
.calendar {
display: flex;
width: 500px;
margin: 20px auto;
position: relative;
}
.event {
background: #039be5;
border: 1px solid white;
border-radius: 5px;
position: absolute;
box-sizing: border-box;
color: white;
overflow: hidden;
padding: 3px;
}
.calendar-time {
border-right: 1px solid #ccc;
width: 100px;
}
.calendar-timelist {
list-style: none;
padding: 0;
margin: 0;
text-align: right;
padding-right: 20px;
}
.calendar-timelist li {
height: 60px;
box-sizing: border-box;
width: 100%;
}
.calendar-events {
flex-grow: 1;
position: relative;
}
2. Crear la Clase JavaScript para el Calendario
Define una clase Calendar
para encapsular toda la funcionalidad.
Constructor
El constructor inicializa el calendario al renderizar la línea de tiempo y los eventos:
class Calendar {
constructor(data) {
// Render the timeline on the Y-axis
this.renderTime();
// Render the event blocks
this.renderEvents(data);
}
renderTime() {
let timeHTML = Array.from({ length: 24 }, (_, i) => `<li>${this.to12HourFormat(i)}</li>`).join("");
document.getElementById("timelist").innerHTML = timeHTML;
}
renderEvents(data) {
let groupedEvents = this.groupEvents(data);
let eventData = this.calculateEventStyles(groupedEvents);
let eventHTML = eventData
.map(
(e) =>
`<div class="event" style="top: ${e.top}px; height: ${e.height}px; width: ${e.width}%; left: ${e.left}%; z-index: ${e.zIndex};">
<strong>${e.title}</strong><br>${e.time}
</div>`
)
.join("");
document.getElementById("events").innerHTML = eventHTML;
}
to12HourFormat(hour) {
if (hour === 0) return "12 AM";
if (hour < 12) return `${hour} AM`;
if (hour === 12) return "12 PM";
return `${hour - 12} PM`;
}
}
3. Manejar Superposiciones y Posicionamiento de Eventos
Necesitamos lógica para manejar eventos que se superponen. Esto se logra agrupando y calculando las posiciones adecuadas.
Agrupar Eventos por Hora de Inicio
groupEvents(data) {
let groups = [];
data.forEach((event) => {
let hour = parseInt(event.start.split(":")[0], 10);
if (!groups[hour]) groups[hour] = [];
groups[hour].push(event);
});
return groups;
}
Calcular Estilos de Eventos
Para cada grupo, calcula el estilo del evento top
, height
, width
y left
basado en el tiempo y superposición.
calculateEventStyles(groups) {
let eventData = [];
groups.forEach((group) => {
let columns = [];
group.forEach((event) => {
let { start, end } = event;
let [sh, sm] = start.split(":").map(Number);
let [eh, em] = end.split(":").map(Number);
let top = sh * 60 + sm; // Convert start time to minutes
let height = (eh * 60 + em) - top; // Calculate duration in minutes
let left = columns.findIndex((col) => col.end <= start);
if (left === -1) {
left = columns.length;
columns.push({ end });
} else {
columns[left].end = end;
}
eventData.push({
title: event.name,
time: `${this.to12HourFormat(sh)} - ${this.to12HourFormat(eh)}`,
top,
height,
left: (left * 100) / columns.length,
width: 100 / columns.length,
zIndex: left,
});
});
});
return eventData;
}
4. Datos de Ejemplo e Inicialización
Define tus datos de eventos e inicializa el Calendar
:
const events = [
{ name: "Meeting with Donna", start: "09:00", end: "10:30" },
{ name: "Project Sync", start: "10:00", end: "11:00" },
{ name: "Lunch Break", start: "12:00", end: "13:00" },
{ name: "Client Call", start: "11:30", end: "12:30" },
];
new Calendar(events);
5. Ejemplo de Código Completo
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<title>Calendar Component</title>
</head>
<body>
<div class="calendar">
<div class="calendar-time">
<ul id="timelist" class="calendar-timelist"></ul>
</div>
<div id="events" class="calendar-events"></div>
</div>
<script src="script.js"></script>
</body>
</html>
Conclusión
Este enfoque utiliza JavaScript puro para generar dinámicamente un componente similar a Google Calendar. Al dividir el problema en tiempo de renderizado, agrupación de eventos y cálculo de estilos, puedes construir componentes escalables e interactivos. ¡Puedes experimentar con el código para agregar funciones como eventos arrastrables o estilos adicionales!
Source:
https://dzone.com/articles/building-a-google-calendar-like-component-using-javascript