В календарях выбора даты часто требуется исключить возможность выбора
выходных дней, чтобы ограничить ввод пользователями только рабочими
датами. В библиотеке Pikaday подобное поведение реализуется через
механизм фильтрации дней, основанный на функции
disableDayFn, позволяющей динамически управлять
доступностью каждой даты при отрисовке календаря.
Внутри календаря каждый день проходит проверку перед отображением. Для этого используется callback-функция, которая получает объект даты и возвращает булево значение:
true — день отключён и недоступен для выбораfalse — день доступен для взаимодействияВыходные дни в стандартной неделе определяются как суббота и воскресенье, что соответствует значениям:
06Следовательно, логика блокировки строится вокруг проверки этих
значений через метод getDay() объекта
Date.
Основной способ исключения выходных дней заключается в использовании
опции disableDayFn.
const picker = new Pikaday({
field: document.getElementById('date'),
disableDayFn: function(date) {
const day = date.getDay();
if (day === 0 || day === 6) {
return true;
}
return false;
}
});
В этом примере календарь будет автоматически помечать субботу и воскресенье как недоступные для выбора. Визуально такие дни обычно получают отдельный CSS-класс, задающий серый цвет и отключение событий клика.
При отсутствии дополнительных условий функция может быть упрощена до одного выражения:
disableDayFn: date => date.getDay() === 0 || date.getDay() === 6
Такая запись используется в проектах, где важно минимизировать объём кода при сохранении читаемости логики.
Блокировка выходных часто применяется вместе с другими правилами ограничения дат, например:
minDate)maxDate)Комбинированная логика реализуется внутри одной функции
disableDayFn.
const holidays = [
new Date(2026, 0, 1),
new Date(2026, 4, 9)
];
function isSameDate(a, b) {
return a.getFullYear() === b.getFullYear() &&
a.getMonth() === b.getMonth() &&
a.getDate() === b.getDate();
}
const picker = new Pikaday({
field: document.getElementById('date'),
disableDayFn: function(date) {
const day = date.getDay();
if (day === 0 || day === 6) {
return true;
}
for (let i = 0; i < holidays.length; i++) {
if (isSameDate(date, holidays[i])) {
return true;
}
}
return false;
}
});
В этом варианте логика расширяется до исключения не только выходных, но и фиксированных праздничных дат.
Объект Date в JavaScript может вести себя по-разному в
зависимости от локальной временной зоны окружения. При использовании
getDay() учитывается локальное время, что может влиять на
корректность определения дня недели при работе с UTC-датами.
Если требуется строгая работа в UTC, необходимо использовать методы:
getUTCDay()getUTCFullYear()getUTCMonth()getUTCDate()Пример адаптации под UTC:
disableDayFn: function(date) {
const day = date.getUTCDay();
return day === 0 || day === 6;
}
Такой подход исключает влияние локальных смещений и обеспечивает стабильное поведение при серверной генерации дат.
При возврате true из disableDayFn календарь
изменяет поведение ячейки дня:
Важно учитывать, что визуальное представление отключённых дней
полностью зависит от CSS темы календаря. В стандартной реализации
Pikaday используется класс is-disabled, который может быть
переопределён.
Для улучшения пользовательского восприятия часто требуется явное оформление выходных дней, даже если они просто заблокированы.
Пример CSS:
.is-disabled {
opacity: 0.4;
cursor: not-allowed;
}
.is-weekend {
color: #d9534f;
}
Добавление отдельной метки «выходной день» возможно через расширение
рендера, если требуется различать типы недоступных дат. Для этого можно
комбинировать disableDayFn с логикой вычисления класса
через кастомный render.
В ряде интерфейсов требуется включать или отключать блокировку выходных в зависимости от состояния формы или роли пользователя.
let blockWeekends = true;
const picker = new Pikaday({
field: document.getElementById('date'),
disableDayFn: function(date) {
if (blockWeekends) {
const day = date.getDay();
if (day === 0 || day === 6) {
return true;
}
}
return false;
}
});
// изменение поведения в рантайме
blockWeekends = false;
picker.draw();
Такой подход позволяет изменять поведение календаря без пересоздания экземпляра.
Распространённые ошибки при реализации:
getDay вместо getUTCDay в
UTC-ориентированных приложенияхКорректная архитектура предполагает, что вся логика доступности дат
централизована в disableDayFn.
Функция disableDayFn вызывается для каждой отображаемой
ячейки календаря. При больших диапазонах дат или сложной логике
(например, запросах к API) это может привести к снижению
производительности.
Оптимизация достигается через:
Set для O(1) проверкиconst disabledDays = new Set([
'2026-01-01',
'2026-05-09'
]);
function format(date) {
return date.toISOString().slice(0, 10);
}
disableDayFn: function(date) {
const day = date.getDay();
if (day === 0 || day === 6) {
return true;
}
return disabledDays.has(format(date));
}
Такой подход снижает нагрузку при рендеринге и повышает отзывчивость интерфейса.
При использовании режима выбора диапазона (start/end date) блокировка выходных влияет на возможность формирования непрерывного интервала. Если внутри диапазона встречаются запрещённые даты, пользовательский сценарий может прерываться или требовать выбора альтернативного пути.
Это поведение необходимо учитывать при проектировании бизнес-логики, особенно в системах бронирования и планирования, где выходные могут быть частично доступны или полностью исключены.