Параметр disableDayFn в библиотеке Pikaday представляет
собой функцию высшего порядка, предназначенную для динамического
управления доступностью конкретных календарных дней. В отличие от
статических ограничений вроде minDate или
maxDate, данный параметр позволяет реализовать произвольную
бизнес-логику блокировки дат на основе пользовательской функции.
Сигнатура функции имеет следующий вид:
disableDayFn: (date) => boolean
Аргумент date — это объект типа Date,
передаваемый библиотекой при рендеринге каждого дня календаря.
Возвращаемое значение строго интерпретируется как логический флаг:
true — день будет отключён (недоступен для выбора)false — день остаётся доступнымПри построении каждого месяца календаря происходит последовательный обход всех отображаемых дат. Для каждой даты выполняется проверка:
minDate и
maxDatedisableWeekends,
disableDayFn и другие флаги)disableDayFn, если он заданЕсли хотя бы одно условие возвращает блокировку, день становится неактивным в интерфейсе.
Важно учитывать, что disableDayFn вызывается для
каждой отрисовываемой даты, поэтому производительность функции
критична при больших диапазонах календаря или сложной логике.
Наиболее простая реализация позволяет отключать конкретные дни недели или отдельные даты.
new Pikaday({
field: document.getElementById('input'),
disableDayFn: function(date) {
return date.getDay() === 0; // отключение воскресений
}
});
В данном случае логика эквивалентна disableWeekends, но
реализована вручную, что позволяет гибко расширять условия.
disableDayFn часто применяется для блокировки
нестандартных календарных правил, например исключения праздников или
периодов обслуживания.
const disabledDates = [
new Date(2026, 0, 1),
new Date(2026, 11, 31)
];
new Pikaday({
field: document.getElementById('input'),
disableDayFn: function(date) {
return disabledDates.some(d =>
d.getFullYear() === date.getFullYear() &&
d.getMonth() === date.getMonth() &&
d.getDate() === date.getDate()
);
}
});
Здесь происходит сравнение только календарных компонентов даты, без
учета времени, поскольку объект Date может содержать часы,
минуты и секунды, влияющие на прямое сравнение.
В системе ограничений календаря disableDayFn не
заменяет, а дополняет другие параметры. Типичная схема приоритета
выглядит следующим образом:
minDate / maxDate — задают жесткий
диапазонdisableWeekends — отключает фиксированные шаблоны
днейdisableDayFn — добавляет пользовательскую
бизнес-логикуДаже если disableDayFn возвращает false,
дата останется недоступной, если она выходит за границы
minDate или maxDate.
При работе с Date в JavaScript необходимо учитывать
локальное смещение времени. В контексте календаря Pikaday используются
локальные даты, поэтому:
date.getFullYear()
date.getMonth()
date.getDate()
являются предпочтительными методами извлечения компонентов.
Использование toISOString() внутри
disableDayFn может привести к смещению даты на один день
из-за UTC-формата.
Так как disableDayFn вызывается для каждой ячейки
календаря, даже небольшие оптимизации могут значительно повлиять на
скорость отрисовки:
.find,
.filter, .some на больших спискахОптимизированный вариант:
const blocked = new Set([
new Date(2026, 0, 1).setHours(0, 0, 0, 0),
new Date(2026, 11, 31).setHours(0, 0, 0, 0)
]);
new Pikaday({
field: document.getElementById('input'),
disableDayFn: function(date) {
return blocked.has(date.setHours(0, 0, 0, 0));
}
});
Такой подход снижает вычислительную нагрузку при больших календарях.
disableDayFn: function(date) {
const day = date.getDay();
return day !== 1 && day !== 3 && day !== 5; // только пн, ср, пт
}
Например, запрет записи на будущие даты дальше 30 дней:
disableDayFn: function(date) {
const now = new Date();
const limit = new Date();
limit.setDate(now.getDate() + 30);
return date > limit;
}
let serverBlockedDays = [];
fetch('/api/blocked-days')
.then(res => res.json())
.then(data => {
serverBlockedDays = data.map(d => new Date(d));
});
new Pikaday({
field: document.getElementById('input'),
disableDayFn: function(date) {
return serverBlockedDays.some(d =>
d.toDateString() === date.toDateString()
);
}
});
Дни, отключённые через disableDayFn, визуально
отображаются как неактивные элементы календаря. Они:
onSelectis-disabledВажно учитывать, что внешний стиль не влияет на логику — только возвращаемое значение функции определяет доступность.
Часто встречающиеся проблемы при использовании
disableDayFn:
Date через === вместо
сравнения компонентовdisableDayFn,
приводящее к нестабильному рендеруВ сложных сценариях disableDayFn становится частью
композиции правил:
function isWeekend(date) {
return date.getDay() === 0 || date.getDay() === 6;
}
function isHoliday(date, holidays) {
return holidays.includes(date.toDateString());
}
new Pikaday({
field: document.getElementById('input'),
disableDayFn: function(date) {
return isWeekend(date) || isHoliday(date, holidays);
}
});
Такой подход упрощает сопровождение и позволяет переиспользовать логику вне календаря.
Если список запрещённых дат изменяется динамически, календарь не
всегда автоматически перерисовывает состояние. В таких случаях требуется
принудительное обновление экземпляра календаря через пересоздание или
методы обновления (в зависимости от интеграции). Это связано с тем, что
функция disableDayFn не отслеживает реактивные зависимости,
а вызывается только в момент отрисовки.