Flatpickr строится вокруг идеи лёгкого и расширяемого календаря, который можно привязать к любому input-элементу и превратить его в полноценный инструмент выбора дат. В контексте событийного календаря ключевая задача — не только выбор даты, но и реакция на действия пользователя, а также визуальное и логическое связывание дат с данными событий.
Базовая инициализация выполняется через вызов flatpickr,
которому передаётся DOM-элемент и конфигурация:
flatpickr("#calendar", {
enableTime: true,
dateFormat: "Y-m-d H:i",
});
В сценарии событийного календаря конфигурация расширяется за счёт обработки событий и динамической модификации дат:
flatpickr("#calendar", {
enableTime: true,
dateFormat: "Y-m-d H:i",
onChange: function(selectedDates, dateStr, instance) {
console.log("Выбрана дата:", dateStr);
}
});
Ключевое отличие календаря событий заключается в том, что сам календарь становится интерфейсом к данным: каждая дата может соответствовать событию, записи или состоянию системы.
Flatpickr предоставляет набор хуков, которые позволяют управлять жизненным циклом календаря. Эти события формируют основу для построения календаря событийного типа.
Срабатывает после полной инициализации календаря. Используется для первичной загрузки событий и разметки дат.
onReady: function(selectedDates, dateStr, instance) {
loadEvents(instance);
}
На этом этапе удобно выполнять асинхронную загрузку данных и связывать их с датами.
Основной обработчик взаимодействия пользователя с календарём. Срабатывает при выборе даты или диапазона.
onChange: function(selectedDates, dateStr, instance) {
const events = getEventsForDate(selectedDates[0]);
renderEventPanel(events);
}
Этот хук часто используется для обновления интерфейса событий: списка встреч, задач или бронирований.
Эти события позволяют управлять состоянием интерфейса при открытии и закрытии календаря.
onOpen: function(selectedDates, dateStr, instance) {
instance.calendarContainer.classList.add("calendar-open");
}
onClose: function(selectedDates, dateStr, instance) {
instance.calendarContainer.classList.remove("calendar-open");
}
В календарях событий эти хуки часто используются для синхронизации состояния с сервером или локальным хранилищем.
При навигации по календарю возникает необходимость подгружать события заранее.
onMonthChange: function(selectedDates, dateStr, instance) {
preloadEvents(instance.currentYear, instance.currentMonth);
}
onYearChange: function(selectedDates, dateStr, instance) {
preloadEvents(instance.currentYear);
}
Такой подход позволяет реализовать ленивую загрузку событий и уменьшить нагрузку при больших диапазонах дат.
Один из наиболее мощных инструментов для построения календаря событий. Позволяет модифицировать каждый день при его создании.
onDayCreate: function(dObj, dStr, fp, dayElem) {
const date = dayElem.dateObj;
const events = getEventsForDate(date);
if (events.length > 0) {
dayElem.classList.add("has-events");
}
}
Этот хук используется для визуальной индикации событий: точек, бейджей, цветовых маркеров.
В основе календаря событий лежит структура данных, которая связывает даты с событиями. Обычно используется один из двух подходов:
const events = {
"2026-06-01": [
{ title: "Встреча", type: "meeting" },
{ title: "Дедлайн", type: "deadline" }
],
"2026-06-02": [
{ title: "Созвон", type: "call" }
]
};
Такой формат обеспечивает быстрый доступ по ключу даты.
const events = [
{ date: "2026-06-01", title: "Встреча" },
{ date: "2026-06-01", title: "Дедлайн" },
{ date: "2026-06-02", title: "Созвон" }
];
Этот подход удобен при работе с API и фильтрацией, но требует дополнительной обработки.
Flatpickr по умолчанию не отображает события, поэтому визуализация реализуется через классы и кастомные элементы.
onDayCreate: function(dObj, dStr, fp, dayElem) {
const key = fp.formatDate(dayElem.dateObj, "Y-m-d");
if (events[key]) {
dayElem.classList.add("event-day");
}
}
CSS:
.event-day {
position: relative;
}
.event-day::after {
content: "";
width: 6px;
height: 6px;
background: red;
border-radius: 50%;
position: absolute;
bottom: 4px;
left: 50%;
transform: translateX(-50%);
}
При наличии нескольких событий на одну дату можно использовать счётчики:
if (events[key]) {
dayElem.setAttribute("data-count", events[key].length);
}
.event-day::after {
content: attr(data-count);
font-size: 10px;
position: absolute;
top: 2px;
right: 2px;
}
При работе с большими календарями данные не загружаются заранее, а подгружаются по мере навигации.
function preloadEvents(year, month) {
fetch(`/api/events?year=${year}&month=${month}`)
.then(res => res.json())
.then(data => {
mergeEvents(data);
});
}
События подгружаются в onMonthChange, что позволяет
оптимизировать производительность.
Календарь используется как интерфейс выбора доступных дат:
flatpickr("#booking", {
minDate: "today",
disable: unavailableDates,
onChange: function(selectedDates) {
checkAvailability(selectedDates[0]);
}
});
Недоступные даты блокируются через disable.
При использовании календаря как планировщика задачи связываются с конкретным временем:
enableTime: true,
time_24hr: true,
onChange: function(dates) {
scheduleTask(dates[0]);
}
Flatpickr поддерживает выбор диапазона дат:
flatpickr("#range", {
mode: "range",
onChange: function(dates) {
if (dates.length === 2) {
loadEventsBetween(dates[0], dates[1]);
}
}
});
Диапазон часто используется для аналитических календарей и отчетов.
Для календаря событий важно синхронизировать состояние между UI и данными.
function updateCalendar(instance) {
instance.redraw();
}
Метод redraw() перерисовывает календарь, применяя новые
классы и состояния.
instance.setDate("2026-06-10");
Используется для перехода к дате события из внешнего списка.
instance.clear();
Позволяет сбросить состояние календаря при смене контекста.
При большом количестве событий основная нагрузка приходится на
рендеринг и обработчики onDayCreate.
Оптимизация включает:
const eventMap = new Map();
function setEvents(events) {
eventMap.clear();
events.forEach(e => {
const key = e.date;
if (!eventMap.has(key)) eventMap.set(key, []);
eventMap.get(key).push(e);
});
}
disable: [
function(date) {
return date.getDay() === 0;
}
]
Используется для исключения выходных или праздничных дней.
onDayCreate: function(dObj, dStr, fp, dayElem) {
const date = dayElem.dateObj;
const isPast = date < new Date();
if (isPast) {
dayElem.classList.add("past-date");
}
}
Календарь событий редко существует изолированно. Он синхронизируется со списками, таблицами и карточками.
onChange: function(selectedDates) {
const list = getEventsForDate(selectedDates[0]);
renderList(list);
}
При изменении даты обновляется связанный компонент интерфейса, что превращает календарь в центральный элемент навигации по данным.
При необходимости календарь может использоваться как слой отображения поверх сложной бизнес-логики:
Каждый из этих сценариев требует собственной модели событий, но Flatpickr остаётся точкой взаимодействия с датой и временем, а не хранилищем логики.