I have a created a calendar with js, css and html. I have managed to add one day events and longer lasting events - all seems fine when events are not overlapping, but when events are overlapping, the overlapping part is fine, but if there are two events one from 10-18 and another from 16-22, then days 16-18 are fine and the two events are not on top of each other but days 18-22 are not affected the same way days 16-18 are.
const holidayInputs = document.querySelectorAll('.holidayInputs'); const holidays = []; holidayInputs.forEach(input => { const value = input.value; const [date, name] = value.split('.'); holidays.push({ hdate: date, holiday: name }); }); const events = [ { title: "As puhkab", startDate: "03-12-2024", endDate: "03-20-2024", }, { title: "Ak puhkab", startDate: "03-04-2024", endDate: "03-14-2024", }, { title: "AC puhkab", startDate: "03-26-2024", endDate: "03-31-2024", } // Add more events as needed ]; const calendar = document.querySelector("#calendar"); const monthBanner = document.querySelector("#month"); let navigation = 0; const weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]; function loadCalendar() { const dt = new Date(); if (navigation != 0) { dt.setMonth(new Date().getMonth() + navigation); } const day = dt.getDate(); const month = dt.getMonth(); const year = dt.getFullYear(); monthBanner.innerText = `${dt.toLocaleDateString("en-us", { month: "long", })} ${year}`; calendar.innerHTML = ""; const daysInMonth = new Date(year, month + 1, 0).getDate(); const firstDayofMonth = new Date(year, month, 1); const dateText = firstDayofMonth.toLocaleDateString("en-us", { weekday: "long", year: "numeric", month: "numeric", day: "numeric", }); const dayString = dateText.split(", ")[0]; const emptyDays = weekdays.indexOf(dayString); const shownEventsDates = new Set(); for (let i = 1; i 0 && currentIndex e.hdate == dateText); if (i - emptyDays === day && navigation == 0) { dayBox.id = "currentDay"; } // Push holidays into the calendar - can be recreated with birthdays if (holidayOfTheDay) { const eventDiv = document.createElement("div"); eventDiv.classList.add("event"); eventDiv.classList.add("holiday"); eventDiv.innerText = holidayOfTheDay.holiday; dayBox.appendChild(eventDiv); dayBox.addEventListener("click", () => { showModal(dateText); }); } // Check if there are events for this day and it hasn't been shown already const eventsForDay = events.filter(event => { const eventStartDate = new Date(event.startDate); const eventEndDate = new Date(event.endDate); const isWithinMonth = eventStartDate.getMonth() == month || eventEndDate.getMonth() == month; const isWithinEventRange = currentDate >= eventStartDate && currentDate 0) { // Create a container for day events const dayEventContainer = document.createElement("div"); dayEventContainer.classList.add("day-events"); dayBox.appendChild(dayEventContainer); // Sort events by start time eventsForDay.sort((a, b) => new Date(a.startDate) - new Date(b.startDate)); // Keep track of processed events within each week const processedEventsByWeek = new Map(); eventsForDay.forEach((event, index) => { // Get event Start and end dates const eventStart = new Date(event.startDate); const eventEnd = new Date(event.endDate); let marginTop = 0; let overlappingEvents = []; const weekNumber = Math.floor((currentDate.getDate() - 1 + emptyDays) / 7); if (!processedEventsByWeek.has(weekNumber)) { processedEventsByWeek.set(weekNumber, new Set()); } for (let week = 0; week processedEventStart) { overlappingEvents.push(processedEvent); } } } } // Calculate maximum marginTop for the entire duration of the event if (overlappingEvents.length > 0) { marginTop = overlappingEvents.length * 20; } /*// Ensure there's an entry for this week if (!processedEventsByWeek.has(weekNumber)) { processedEventsByWeek.set(weekNumber, new Set()); } // Check if the event overlaps with any previously processed event in this week let marginTop = 0; for (const processedEvent of processedEventsByWeek.get(weekNumber)) { const processedEventEnd = new Date(processedEvent.endDate); // If there's an overlap, adjust marginTop and break if ( eventStart 0) { eventDiv.style.marginTop = `${marginTop}px`; } // Set the right offset for event start let eventStartOffset = Math.max(0, eventStart.getDay() * dayWidth); const dayEventDiv = document.createElement("div"); dayEventDiv.classList.add("day-event"); dayEventDiv.style.left = eventStartOffset + "px" if (eventEnd.getDate() == currentDate.getDate() || dayOfWeek == 6) { dayEventDiv.style.width = 95 + "px"; } else { dayEventDiv.style.width = dayWidth + "px"; } eventDiv.appendChild(dayEventDiv); dayEventContainer.appendChild(eventDiv); shownEventsDates.add(dateText); // Record that this event has been shown }); dayBox.addEventListener("click", () => { showModal(dateText); }); } } else { dayBox.classList.add("plain"); } calendar.append(dayBox); } } function buttons() { const btnBack = document.querySelector("#btnBack"); const btnNext = document.querySelector("#btnNext"); btnBack.addEventListener("click", () => { navigation--; loadCalendar(); }); btnNext.addEventListener("click", () => { navigation++; loadCalendar(); }); } const modal = document.querySelector("#modal"); const modalClose = document.querySelector(".modal-close"); function showModal(dateText) { clicked = dateText; modal.style.display = "flex"; // modaali sisu loogika
I have tried changing the logic how the margin top is given, but i cannot think of a good way for this to be implemented on the whole event duration.
Источник: https://stackoverflow.com/questions/781 ... ositioning
Мобильная версия