أصبحت التقويمات جزءًا لا يتجزأ من تطبيقات الويب الحديثة حيث تمكّن المستخدمين من تنظيم وجدولة وتتبع الفعاليات بسلاسة. سواء كنت تبني أداة لإدارة المشاريع أو تطبيق جدولة الفعاليات أو مجموعة إنتاجية شخصية، يمكن أن يعزز مكون التقويم المخصص تجربة المستخدم بشكل كبير. بينما توجد العديد من مكتبات التقويم الجاهزة، يمكن أن يوفر إنشاء مكون خاص بك المرونة لتلبية متطلبات التصميم والوظائف المحددة.
في هذا الدليل، سنستكشف كيفية بناء مكون مشابه لتقويم جوجل باستخدام JavaScript. بنهاية هذا الدليل، سيكون لديك تقويم وظيفي بالكامل مع ميزات تفاعلية وفهم أعمق لكيفية بناء مكونات قابلة لإعادة الاستخدام لتطبيقات الويب الخاصة بك. سواء كنت مطورًا تسعى لإضافة لمسة فريدة لمشروعك أو شخصًا حريصًا على تعلم كيفية عمل وظائف التقويم، ستكون هذه الخطوات خطوة بخطوة لا تقدر بثمن. لنبدأ!
نظرة عامة
سنقوم بإنشاء مكون تقويم بالميزات التالية:
- محور الزمن: خط زمني عمودي من الساعة 12 صباحًا حتى 11 مساءً.
- كتل الأحداث: أحداث يتم عرضها ديناميكيًا مع وضع وارتفاع مناسبين بناءً على أوقات بدايتها وانتهائها.
- معالجة التداخل: ستظهر الأحداث المتداخلة في الوقت جنبًا إلى جنب.
إليك كيفية إنشاء هذا المكون خطوة بخطوة.
دليل خطوة بخطوة
1. إعداد HTML والأساليب الأساسية
نبدأ بإنشاء هيكل HTML بسيط للتقويم. يتضمن التخطيط خط زمن وحاوية للأحداث.
<div class="calendar">
<div class="calendar-time">
<ul id="timelist" class="calendar-timelist"></ul>
</div>
<div id="events" class="calendar-events"></div>
</div>
أضف CSS الأساسية لتنسيق التقويم:
.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. إنشاء فئة JavaScript للتقويم
حدد فئة Calendar
لتجميع جميع الوظائف.
الباني
يقوم الباني بتهيئة التقويم من خلال عرض الخط الزمني والأحداث:
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. معالجة تداخل الأحداث وتحديد المواقع
نحتاج إلى منطق للتعامل مع الأحداث المتداخلة. يتم ذلك من خلال تجميع وحساب المواقع المناسبة.
تجميع الأحداث حسب ساعة البدء
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;
}
حساب أنماط الأحداث
لكل مجموعة، احسب top
وheight
وwidth
وleft
للحدث بناءً على الوقت والتداخل.
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. بيانات مثال وتهيئة
حدد بيانات الحدث الخاصة بك وتهيئة 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. مثال كامل على الكود
<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>
خاتمة
هذا النهج يستخدم JavaScript العادي لإنشاء مكون يشبه تقويم Google ديناميكيًا. من خلال تقسيم المشكلة إلى عرض الوقت، وتجميع الأحداث، وحساب الأنماط، يمكنك بناء مكونات تفاعلية قابلة للتوسيع. يمكنك تجربة الكود لإضافة ميزات مثل الأحداث القابلة للسحب أو تخصيص إضافي!
Source:
https://dzone.com/articles/building-a-google-calendar-like-component-using-javascript