Flatpickr предоставляет точку расширения для управления тем, как
отображаются отдельные дни в календарной сетке. Основной инструмент
кастомизации — хук onDayCreate, который вызывается при
создании каждой ячейки дня в DOM.
Каждый элемент календаря генерируется как HTML-узел с набором базовых классов, после чего библиотека передаёт управление в пользовательский обработчик. Это позволяет модифицировать внешний вид, добавлять атрибуты, внедрять HTML-содержимое, подсветку, индикаторы событий и любые дополнительные визуальные слои.
onDayCreate вызывается для каждой даты, отображаемой в
текущем месяце (а также соседних, если включён
showOtherMonths).
Сигнатура:
onDayCreate: function(dObj, dStr, fp, dayElem) {
}
Где:
dObj — объект Date, соответствующий
конкретной ячейкеdStr — строковое представление даты в текущем
форматеfp — экземпляр FlatpickrdayElem — DOM-элемент ячейки дняКлючевой момент заключается в том, что dayElem уже
существует в DOM, но ещё не зафиксирован окончательно в логике
отображения, что позволяет безопасно модифицировать его содержимое и
классы.
Наиболее распространённые операции внутри
onDayCreate:
Пример добавления класса:
onDayCreate: function(dObj, dStr, fp, dayElem) {
if (dObj.getDay() === 0 || dObj.getDay() === 6) {
dayElem.classList.add("is-weekend");
}
}
Логика кастомного рендеринга чаще всего основана на сравнении даты с внешними данными: событиями, расписанием, ограничениями.
Пример подсветки праздничных дней:
const holidays = [
"2026-01-01",
"2026-05-09",
"2026-12-31"
];
function formatDate(date) {
const y = date.getFullYear();
const m = String(date.getMonth() + 1).padStart(2, "0");
const d = String(date.getDate()).padStart(2, "0");
return `${y}-${m}-${d}`;
}
flatpickr("#calendar", {
onDayCreate: function(dObj, dStr, fp, dayElem) {
const dateKey = formatDate(dObj);
if (holidays.includes(dateKey)) {
dayElem.classList.add("is-holiday");
}
}
});
Такой подход позволяет отделить данные от представления и использовать Flatpickr как слой визуализации поверх бизнес-логики.
Одним из наиболее частых сценариев является отображение количества событий или точек активности внутри дня.
Пример с бейджем:
const eventsMap = {
"2026-06-01": 3,
"2026-06-02": 1,
"2026-06-03": 7
};
flatpickr("#calendar", {
onDayCreate: function(dObj, dStr, fp, dayElem) {
const key = dStr;
if (eventsMap[key]) {
const badge = document.createElement("span");
badge.className = "day-badge";
badge.textContent = eventsMap[key];
dayElem.appendChild(badge);
}
}
});
Здесь важно учитывать, что dayElem уже содержит
текстовую ноду с числом дня, и добавление дополнительных элементов может
потребовать CSS-позиционирования (position: relative у
контейнера).
В некоторых сценариях требуется полностью контролировать структуру дня, включая обёртки и вложенные элементы.
onDayCreate: function(dObj, dStr, fp, dayElem) {
const dayNumber = dObj.getDate();
dayElem.innerHTML = "";
const wrapper = document.createElement("div");
wrapper.className = "custom-day";
const number = document.createElement("span");
number.className = "day-number";
number.textContent = dayNumber;
const marker = document.createElement("span");
marker.className = "day-marker";
wrapper.appendChild(number);
wrapper.appendChild(marker);
dayElem.appendChild(wrapper);
}
Такой подход даёт максимальную гибкость, но требует полного контроля над стилями и состояниями (selected, today, disabled).
Flatpickr применяет к ячейкам стандартные классы:
flatpickr-daytodayselecteddisabledprevMonthDay / nextMonthDayПри кастомизации важно учитывать, что эти классы могут конфликтовать с пользовательской разметкой.
Пример условного расширения состояния:
onDayCreate: function(dObj, dStr, fp, dayElem) {
if (dayElem.classList.contains("disabled")) {
dayElem.classList.add("is-blocked");
}
}
Часто данные для рендеринга приходят асинхронно. В этом случае используется предварительная загрузка данных и кэширование.
let availabilityCache = {};
fetch("/api/availability")
.then(r => r.json())
.then(data => {
availabilityCache = data;
});
flatpickr("#calendar", {
onDayCreate: function(dObj, dStr, fp, dayElem) {
const status = availabilityCache[dStr];
if (status === "full") {
dayElem.classList.add("is-full");
} else if (status === "low") {
dayElem.classList.add("is-low");
}
}
});
Ключевой момент — onDayCreate не ожидает завершения
async-операций, поэтому данные должны быть заранее доступны.
Дополнительные метаданные удобно хранить в data-*
атрибутах:
onDayCreate: function(dObj, dStr, fp, dayElem) {
const tooltipText = `Дата: ${dStr}`;
dayElem.setAttribute("data-tooltip", tooltipText);
}
Или интеграция с кастомным tooltip-движком:
dayElem.addEventListener("mouseenter", () => {
showTooltip(dayElem, "Дополнительная информация");
});
Важно учитывать, что обработчики событий создаются для каждого дня, что может влиять на производительность при больших диапазонах.
При использовании пользовательского рендеринга необходимо учитывать внутреннюю переработку DOM при смене месяца. Flatpickr полностью пересоздаёт сетку дней при навигации, поэтому:
Пример корректного подхода:
onDayCreate: function(dObj, dStr, fp, dayElem) {
dayElem.classList.remove("custom-state");
if (dObj.getDate() === 15) {
dayElem.classList.add("custom-state");
}
}
При большом количестве логики в onDayCreate возможны
просадки производительности. Основные рекомендации:
Оптимизированный вариант проверки:
const specialDays = new Set(["2026-06-10", "2026-06-11"]);
onDayCreate: function(dObj, dStr, fp, dayElem) {
if (specialDays.has(dStr)) {
dayElem.classList.add("is-special");
}
}
Кастомизация не должна нарушать логику выбора. Flatpickr опирается на
внутренние события клика по dayElem.
Если полностью заменяется структура DOM, необходимо сохранить возможность клика:
wrapper.addEventListener("click", () => {
fp.setDate(dObj);
});
При этом оригинальный элемент дня может быть визуально скрыт, но логически сохранён.
В некоторых случаях лучше ограничиться CSS-классами, а не модификацией DOM:
onDayCreate: function(dObj, dStr, fp, dayElem) {
if (dObj.getMonth() !== fp.currentMonth) {
dayElem.classList.add("dimmed");
}
}
И затем стилизация:
.dimmed {
opacity: 0.4;
}
Такой подход снижает нагрузку и уменьшает вероятность конфликтов с внутренней логикой библиотеки.
При сложной логике часто объединяются разные типы информации: праздники, события, ограничения, доступность.
onDayCreate: function(dObj, dStr, fp, dayElem) {
const key = dStr;
if (holidaysSet.has(key)) {
dayElem.classList.add("holiday");
}
if (eventsMap[key]) {
const marker = document.createElement("i");
marker.className = "event-dot";
dayElem.appendChild(marker);
}
if (blockedSet.has(key)) {
dayElem.classList.add("blocked");
}
}
Подобная композиция позволяет формировать богатую визуальную модель календаря без изменения ядра Flatpickr, сохраняя предсказуемость поведения компонента.