Библиотека Pikaday поддерживает режим отображения сразу нескольких месяцев в одном календарном интерфейсе, что особенно важно при работе с диапазонами дат, планированием событий и сценариями, где требуется быстрый обзор соседних периодов без переключения навигации.
Основной механизм, отвечающий за мульти-месячный режим, задаётся
параметром конфигурации numberOfMonths. Именно он
определяет, сколько календарных сеток будет отрисовано одновременно в
одном экземпляре виджета.
const picker = new Pikaday({
field: document.getElementById('date'),
numberOfMonths: 3
});
При значении 3 интерфейс календаря формирует три
независимых, но синхронизированных блока месяцев, расположенных
горизонтально. Каждый блок отображает собственную сетку дней, однако
навигационные действия (перелистывание вперёд или назад) применяются ко
всем месяцам одновременно, сохраняя их относительное смещение.
При активации numberOfMonths > 1 Pikaday использует
единый внутренний объект состояния текущего месяца
(currentMonth и currentYear) как базовую точку
отсчёта. Дополнительные месяцы вычисляются смещением:
+1 месяц+2 месяцаТакой подход исключает рассинхронизацию дат и обеспечивает стабильную навигацию.
Визуально каждый месяц является отдельным DOM-блоком, но логически они объединены общими обработчиками событий и состоянием выбора дат.
При стандартной конфигурации кнопки навигации изменяют текущий месяц на ±1. В мульти-месячном режиме это поведение становится более важным, поскольку смещение применяется ко всей группе календарей.
Пример: если отображается 3 месяца (март, апрель, май), то при переходе вперёд набор станет (апрель, май, июнь).
Важно учитывать, что шаг навигации всегда равен одному месяцу, а не количеству отображаемых месяцев. Это поведение сохраняет предсказуемость интерфейса.
Отрисовка нескольких месяцев создаёт горизонтальную структуру, где
каждый календарь помещается в контейнер .pika-lendar.
Pikaday автоматически группирует их в общий wrapper
.pika-multiple-months.
Базовая CSS-модель предполагает inline-block или flex-раскладку.
Пример адаптации под flex:
.pika-multiple-months {
display: flex;
gap: 16px;
}
.pika-lendar {
width: 280px;
}
При таком подходе календари выравниваются по горизонтали, а
расстояние между ними контролируется через gap.
Мульти-месячный режим требует учёта ограниченного пространства на
мобильных устройствах. При фиксированном значении
numberOfMonths: 2 или 3 интерфейс может
выходить за пределы экрана.
Типичная стратегия адаптации — динамическое изменение количества отображаемых месяцев:
function getMonthsCount() {
return window.innerWidth < 600 ? 1 : 2;
}
const picker = new Pikaday({
field: document.getElementById('date'),
numberOfMonths: getMonthsCount()
});
Дополнительно возможно обновление параметра при ресайзе окна с пересозданием экземпляра календаря или через переинициализацию рендера.
Все месяцы в одном экземпляре Pikaday работают с единым состоянием
выбранной даты (selectedDate). Это означает, что выбор даты
в любом из отображаемых месяцев влияет на общий state.
При использовании диапазонных сценариев (start/end date) мульти-месячный режим становится особенно полезным, так как позволяет визуально охватывать несколько месяцев без переключения.
Пример интеграции диапазона:
let startDate = null;
let endDate = null;
const picker = new Pikaday({
field: document.getElementById('range'),
numberOfMonths: 2,
onSelect: function () {
const selected = this.getDate();
if (!startDate || (startDate && endDate)) {
startDate = selected;
endDate = null;
} else {
endDate = selected;
}
}
});
Параметры minDate и maxDate действуют
глобально и применяются ко всем отображаемым месяцам. Это означает, что
ограничения не зависят от текущего видимого блока календаря.
const picker = new Pikaday({
field: document.getElementById('date'),
numberOfMonths: 3,
minDate: new Date(2026, 0, 1),
maxDate: new Date(2026, 11, 31)
});
Недоступные даты автоматически получают CSS-класс
is-disabled, независимо от того, в каком из месяцев они
отображаются.
Увеличение numberOfMonths напрямую влияет на количество
создаваемых DOM-элементов. Каждый дополнительный месяц добавляет:
При значениях выше 3–4 возможно снижение
производительности в старых браузерах из-за увеличенного количества
событий и перерасчётов layout.
Оптимизация обычно достигается ограничением количества месяцев и использованием ленивой инициализации (создание календаря только при открытии поля).
В мульти-месячном режиме каждый блок имеет собственный заголовок с
названием месяца. Pikaday позволяет управлять форматом через
i18n и кастомные функции отображения.
const picker = new Pikaday({
field: document.getElementById('date'),
numberOfMonths: 2,
i18n: {
previousMonth: 'Предыдущий месяц',
nextMonth: 'Следующий месяц',
months: [
'Январь','Февраль','Март','Апрель','Май','Июнь',
'Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'
]
}
});
Каждый из месяцев отображает свой заголовок, но структура навигации остаётся общей.
Если отображается несколько месяцев подряд, переход через декабрь автоматически переносит последующие календари на следующий год без дополнительных настроек. Например:
Это происходит за счёт встроенной нормализации даты в JavaScript
Date, используемой внутри Pikaday.
Мульти-месячное отображение часто применяется совместно с логикой range picker. В таком случае важны два аспекта:
При двух месяцах пользователь может выбирать начальную и конечную дату без смены страницы календаря, что снижает количество взаимодействий.
При использовании bound: false и ручного
позиционирования календаря через CSS или JavaScript мульти-месячный
режим требует дополнительного контроля ширины контейнера.
const picker = new Pikaday({
field: document.getElementById('date'),
numberOfMonths: 3,
bound: false,
container: document.getElementById('calendar-container')
});
Контейнер должен явно учитывать суммарную ширину всех месяцев, иначе возможны переносы блоков на новую строку.
Клавиатурное управление (стрелки, PageUp, PageDown) работает в рамках общего календарного состояния. При этом фокус остаётся в пределах активной ячейки, но при достижении границ текущего месяца может автоматически переходить в соседний отображаемый месяц.
Это поведение особенно заметно при
numberOfMonths > 1, где логическая сетка становится
непрерывной по горизонтали.
При использовании нескольких месяцев важно учитывать согласованность стилей:
.pika-lendarЛюбые расхождения в CSS могут привести к визуальному «разъезжанию» календарей, особенно при разных локализациях, где длина названий месяцев отличается.