AJAX-Календарь для WordPress
Код начинает выполнение после полной загрузки DOM.
2. Основные элементы:
const calendarContainer = document.getElementById("calendar-container");
const calendarMonth = document.getElementById("calendar-month");
const tooltip = document.createElement("div");
tooltip.className = "calendar-tooltip";
document.body.appendChild(tooltip);
calendarContainer: Контейнер для отображения дней месяца. calendarMonth: Элемент, в котором отображается название текущего месяца и года. tooltip: Подсказка, отображающая список записей для конкретной даты. Она создается динамически и добавляется в body. 3. Проверка наличия элементов:
if (!calendarContainer || !calendarMonth) {
console.error("Не найдены элементы календаря: #calendar-container или #calendar-month");
return;
}
Если необходимые элементы отсутствуют, выводится сообщение об ошибке, и выполнение прекращается. 4. Рендеринг календаря:
function renderCalendar(date) {
calendarContainer.innerHTML = "";
Очищается содержимое контейнера календаря перед рендерингом нового месяца. 5. Подготовка данных о текущем месяце:
const year = date.getFullYear();
const month = date.getMonth();
const firstDay = new Date(year, month, 1);
const lastDay = new Date(year, month + 1, 0);
Вычисляются год, месяц, первый день и последний день текущего месяца. 6. Установка названия месяца:
calendarMonth.textContent = date.toLocaleDateString("ru-RU", {
month: "long",
year: "numeric",
});
Название месяца отображается в формате "Месяц Год" на русском языке. 7. Запрос записей для месяца:
fetch(calendarAjax.ajaxUrl, {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: `action=get_posts_for_month&year=${year}&month=${month + 1}`,
})
Отправляется AJAX-запрос на сервер для получения записей, привязанных к датам текущего месяца. calendarAjax.ajaxUrl: URL, задаваемый сервером (например, через wp_localize_script в WordPress). action: Указывает обработчик для серверной логики (здесь get_posts_for_month). Передаются год и месяц. 8. Обработка ответа:
if (data.success && data.data) {
const postsByDate = data.data; // Объект с датами и записями
Если запрос успешен, данные (записи, сгруппированные по датам) сохраняются в объект postsByDate. 9. Рендеринг дней месяца:
for (let day = 1; day <= lastDay.getDate(); day++) {
const dayCell = document.createElement("div");
dayCell.className = "calendar-day";
dayCell.textContent = day;
const fullDate = `${year}-${String(month + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
dayCell.dataset.date = fullDate;
Для каждого дня создается элемент div с классом calendar-day и текстом дня. fullDate: Формат даты (например, 2024-12-01), сохраняется в атрибут data-date. 10. Проверка наличия записей:
if (postsByDate[fullDate]) {
dayCell.classList.add("has-posts");
dayCell.addEventListener("mouseover", () => showTooltip(dayCell, fullDate));
dayCell.addEventListener("mouseleave", hideTooltip);
dayCell.addEventListener("click", () => {
window.location.href = `/date/${fullDate}`;
});
} else {
dayCell.classList.add("no-posts");
}
calendarContainer.appendChild(dayCell);
Если для даты есть записи:
Элементу добавляется класс has-posts.
Устанавливаются обработчики событий:
mouseover: Показывает подсказку.
mouseleave: Скрывает подсказку.
click: Переходит на страницу /date/дата.
Если записей нет, добавляется класс no-posts.
11. Подсказка (tooltip):
function showTooltip(dayCell, date) {
fetch(calendarAjax.ajaxUrl, {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: `action=get_posts_for_date&date=${date}`,
})
.then((response) => response.json())
.then((data) => {
if (data.success && data.data.length > 0) {
tooltip.innerHTML = data.data
.map((post) => `< a href="${post.link}">${post.title}< /a>`)
.join("< br >");
tooltip.style.display = "block";
tooltip.style.top = dayCell.getBoundingClientRect().bottom + window.scrollY + "px";
tooltip.style.left = dayCell.getBoundingClientRect().left + "px";
} else {
tooltip.style.display = "none";
}
});
}
Отправляется запрос для получения записей конкретной даты. Если записи есть, формируется содержимое подсказки в виде ссылок на статьи. Устанавливаются позиции подсказки относительно выбранного дня. 12. Перелистывание месяцев:
document.getElementById("prev-month").addEventListener("click", () => {
currentDate.setMonth(currentDate.getMonth() - 1);
renderCalendar(currentDate);
});
document.getElementById("next-month").addEventListener("click", () => {
currentDate.setMonth(currentDate.getMonth() + 1);
renderCalendar(currentDate);
});
Кнопки prev-month и next-month переключают месяцы, обновляя календарь. 13. Инициализация:
renderCalendar(currentDate);
Календарь рендерится для текущей даты при загрузке страницы. Подробнее смотри на моем youtube канале Ссылка на YouTube
+375 (33) 625-25-67


