Механизм ограничения выбора дат в календаре Pikaday строится вокруг
функции disableDayFn, которая позволяет программно
управлять доступностью каждого дня в зависимости от пользовательской
логики. В отличие от статических ограничений вроде minDate
и maxDate, данный подход даёт полный контроль над
календарной сеткой, включая фильтрацию по дням недели, праздникам,
пользовательским расписаниям и комбинированным условиям.
Перед реализацией фильтрации важно учитывать, как в JavaScript представляется день недели:
0 — воскресенье1 — понедельник2 — вторник3 — среда4 — четверг5 — пятница6 — субботаМетод date.getDay() возвращает одно из этих значений,
что делает его базовым инструментом для построения условий
блокировки.
Функция disableDayFn вызывается для каждой даты,
отображаемой в календаре. Если функция возвращает true,
дата становится недоступной для выбора.
Блокировка, например, всех понедельников реализуется следующим образом:
var picker = new Pikaday({
field: document.getElementById('datepicker'),
disableDayFn: function(date) {
return date.getDay() === 1;
}
});
В этом случае календарь сохраняет отображение всех дат, но пользователь не сможет выбрать ни один понедельник.
Часто требуется исключить сразу несколько дней, например выходные. Это реализуется через логическое условие:
var picker = new Pikaday({
field: document.getElementById('datepicker'),
disableDayFn: function(date) {
var day = date.getDay();
return day === 0 || day === 6;
}
});
Такой подход масштабируется на любое количество дней недели и остаётся читаемым даже при усложнении логики.
При росте количества условий удобнее выносить конфигурацию в массив, что делает код более декларативным:
var disabledDays = [0, 6];
var picker = new Pikaday({
field: document.getElementById('datepicker'),
disableDayFn: function(date) {
return disabledDays.indexOf(date.getDay()) !== -1;
}
});
Данный вариант упрощает поддержку, особенно если список блокируемых дней формируется динамически.
В реальных приложениях ограничения часто зависят не только от календарной логики, но и от внешних условий: расписания работы, загрузки системы, типов услуг.
Пример блокировки среды и пятницы:
var picker = new Pikaday({
field: document.getElementById('datepicker'),
disableDayFn: function(date) {
var day = date.getDay();
if (day === 3 || day === 5) {
return true;
}
return false;
}
});
Логика может быть расширена до проверки внешних переменных:
var isMaintenanceDay = true;
var picker = new Pikaday({
field: document.getElementById('datepicker'),
disableDayFn: function(date) {
if (isMaintenanceDay) {
return date.getDay() !== 1; // разрешён только понедельник
}
return false;
}
});
disableDayFn часто используется вместе с
minDate и maxDate. В этом случае сначала
отсекается диапазон, а затем применяется фильтрация по дням недели:
var picker = new Pikaday({
field: document.getElementById('datepicker'),
minDate: new Date(2026, 0, 1),
maxDate: new Date(2026, 11, 31),
disableDayFn: function(date) {
return date.getDay() === 0 || date.getDay() === 6;
}
});
Такой подход позволяет задавать одновременно временные рамки и календарные правила.
Иногда удобнее мыслить не запрещёнными, а разрешёнными днями. Тогда логика строится через явный whitelist:
var allowedDays = [1, 2, 3, 4, 5];
var picker = new Pikaday({
field: document.getElementById('datepicker'),
disableDayFn: function(date) {
return allowedDays.indexOf(date.getDay()) === -1;
}
});
Подход с разрешёнными днями часто используется в системах с фиксированным графиком работы.
Функция disableDayFn работает не только с днями недели,
но и с любыми свойствами объекта Date. Это позволяет
комбинировать фильтрацию:
var picker = new Pikaday({
field: document.getElementById('datepicker'),
disableDayFn: function(date) {
var day = date.getDay();
var dayOfMonth = date.getDate();
if (day === 0 || day === 6) {
return true;
}
if (dayOfMonth === 13) {
return true;
}
return false;
}
});
Таким образом возможно учитывать как недельные циклы, так и календарные особенности месяца.
При усложнении условий целесообразно выносить проверку в отдельную функцию, чтобы не перегружать конфигурацию календаря:
function isDateDisabled(date) {
var day = date.getDay();
var isWeekend = (day === 0 || day === 6);
var isHolidayRule = (day === 2);
return isWeekend || isHolidayRule;
}
var picker = new Pikaday({
field: document.getElementById('datepicker'),
disableDayFn: isDateDisabled
});
Такая структура повышает тестируемость логики и упрощает её переиспользование в разных календарях приложения.
Pikaday позволяет пересоздавать или переинициализировать календарь с новыми правилами, что используется для динамического изменения доступности дней:
var currentRule = 'standard';
function getDisableFn() {
return function(date) {
var day = date.getDay();
if (currentRule === 'standard') {
return day === 0 || day === 6;
}
if (currentRule === 'strict') {
return day !== 1;
}
return false;
};
}
var picker = new Pikaday({
field: document.getElementById('datepicker'),
disableDayFn: getDisableFn()
});
При изменении currentRule можно пересоздать экземпляр
календаря для применения новой логики.
Функция disableDayFn вызывается для каждой отображаемой
ячейки календаря, поэтому:
Пример оптимизированного подхода:
var disabledSet = new Set([0, 6]);
var picker = new Pikaday({
field: document.getElementById('datepicker'),
disableDayFn: function(date) {
return disabledSet.has(date.getDay());
}
});
Использование Set обеспечивает постоянную сложность
проверки и снижает нагрузку при больших календарных диапазонах.
Распространённые проблемы связаны не с Pikaday, а с логикой даты:
getDay() вместо getDate()
при попытке блокировать числа месяца;Date;undefined вместо true/false, что
приводит к непредсказуемому поведению.Корректная реализация всегда возвращает строго булево значение.
При наличии множества условий удобно формировать отдельные правила:
var rules = {
weekends: function(date) {
var d = date.getDay();
return d === 0 || d === 6;
},
wednesdayOnly: function(date) {
return date.getDay() !== 3;
},
noMondays: function(date) {
return date.getDay() === 1;
}
};
var activeRule = rules.weekends;
var picker = new Pikaday({
field: document.getElementById('datepicker'),
disableDayFn: function(date) {
return activeRule(date);
}
});
Такой подход позволяет строить масштабируемую систему календарных ограничений, где логика отделена от инициализации компонента.