Событие onYearChange

Событие onYearChange в Flatpickr относится к группе календарных callback-функций и вызывается каждый раз, когда изменяется отображаемый год в интерфейсе календаря. Это изменение может происходить как в результате пользовательской навигации (стрелки переключения года, выбор даты за пределами текущего года), так и при программном управлении состоянием календаря через API экземпляра.

onYearChange срабатывает в момент, когда внутреннее состояние календаря фиксирует переход между годами. При этом важно различать:

  • изменение года отображения (view year);
  • изменение выбранной даты (selected date);
  • изменение месяца, которое может косвенно повлечь смену года.

Событие связано именно с изменением отображаемого года, а не обязательно с изменением выбранного значения.

Внутри Flatpickr календарь хранит текущее состояние навигации, включая:

  • текущий отображаемый год (currentYear);
  • текущий отображаемый месяц;
  • выбранные даты.

onYearChange реагирует только на обновление currentYear.


Сигнатура callback-функции

Callback, передаваемый в onYearChange, имеет стандартную форму:

onYearChange: function(selectedDates, dateStr, instance) {
    // логика обработки смены года
}

Параметры:

selectedDates Массив объектов Date, содержащий выбранные даты. Важно: изменение года не гарантирует изменение выбранной даты.

dateStr Строковое представление выбранной даты в формате, заданном через dateFormat. Может оставаться неизменным при смене года, если пользователь не меняет выбор.

instance Экземпляр календаря Flatpickr, содержащий полное состояние компонента и API управления.


Базовое использование события

Типичная регистрация обработчика выглядит следующим образом:

flatpickr("#datepicker", {
    onYearChange: function(selectedDates, dateStr, instance) {
        console.log("Год изменён:", instance.currentYear);
    }
});

В данном примере используется доступ к instance.currentYear, который отражает актуальный отображаемый год после переключения.


Поведение при навигации между годами

Изменение года может происходить несколькими способами:

  • переход через стрелки навигации календаря;
  • выбор даты, находящейся в другом году;
  • программное изменение отображаемой даты;
  • переключение через клавиатуру (если включена поддержка навигации).

Во всех этих случаях onYearChange будет вызван после того, как внутреннее состояние календаря обновит год.


Связь с другими событиями

onYearChange часто используется вместе с другими callback-ами:

  • onMonthChange — изменение месяца;
  • onChange — изменение выбранной даты;
  • onOpen и onClose — открытие и закрытие календаря;
  • onReady — первичная инициализация.

В отличие от них, onYearChange изолированно отслеживает только изменение года, даже если остальные части состояния остаются прежними.


Различие между onYearChange и onMonthChange

Поведение этих событий часто путают, однако их семантика различается строго:

  • onYearChange — фиксирует смену года отображения;
  • onMonthChange — фиксирует смену месяца.

Смена месяца может привести к смене года (например, декабрь → январь), и в этом случае:

  1. сначала фиксируется смена месяца;
  2. затем происходит обновление года;
  3. onYearChange вызывается отдельно.

Использование текущего года в логике приложения

Экземпляр Flatpickr предоставляет доступ к внутреннему состоянию:

onYearChange: function(selectedDates, dateStr, instance) {
    const year = instance.currentYear;

    if (year < 2000) {
        console.log("Выбран устаревший диапазон");
    }
}

currentYear обновляется синхронно с интерфейсом календаря, что позволяет использовать его для динамических ограничений и загрузки данных.


Типичные сценарии применения

1. Динамическая подгрузка данных по году

onYearChange: function(selectedDates, dateStr, instance) {
    fetch(`/api/events?year=${instance.currentYear}`)
        .then(res => res.json())
        .then(data => {
            console.log("События загружены:", data);
        });
}

2. Ограничение логики интерфейса

onYearChange: function(selectedDates, dateStr, instance) {
    document.querySelector("#yearLabel").textContent =
        instance.currentYear;
}

3. Синхронизация с внешними фильтрами

onYearChange: function(selectedDates, dateStr, instance) {
    updateFilters({
        year: instance.currentYear
    });
}

Ограничения и особенности

Минимальный и максимальный год

Если заданы параметры minDate и maxDate, изменение года может быть ограничено. В этом случае:

  • переход за пределы диапазона блокируется;
  • onYearChange может не вызываться, если фактического изменения не произошло.

Отсутствие изменения selectedDates

Смена года не обязательно означает изменение выбранной даты:

  • пользователь может просто пролистывать календарь;
  • selectedDates остаётся прежним;
  • dateStr может не обновляться.

Поведение при множественном выборе

В режимах mode: "multiple" или mode: "range":

  • onYearChange не влияет на структуру массива дат;
  • только навигационная часть календаря обновляется.

Взаимодействие с локализацией

При смене года интерфейс может пересчитывать отображение дат с учётом локали:

  • форматы отображения месяцев;
  • начало недели;
  • текстовые элементы календаря.

Сам onYearChange не зависит от локали напрямую, но может быть использован для обновления локализованных данных.


Потенциальные ошибки при использовании

1. Дублирование запросов

При каждом переключении года событие может вызываться многократно, если пользователь быстро листает календарь:

onYearChange: debounce(function(selectedDates, dateStr, instance) {
    loadData(instance.currentYear);
}, 300);

2. Несоответствие UI и состояния

Если внешнее состояние обновляется асинхронно, возможно рассинхронизирование между:

  • отображаемым годом календаря;
  • внешними фильтрами.

3. Игнорирование текущего состояния instance

Ошибкой является использование внешних переменных вместо instance.currentYear, так как:

  • календарь может быть переинициализирован;
  • несколько экземпляров могут существовать одновременно.

Интеграция в сложные интерфейсы

В SPA-приложениях событие часто используется как триггер для:

  • виртуальной подгрузки календарных данных;
  • фильтрации графиков по годам;
  • обновления URL-параметров без перезагрузки страницы.
onYearChange: function(selectedDates, dateStr, instance) {
    const year = instance.currentYear;

    history.replaceState(null, "", `?year=${year}`);
}

Состояние экземпляра при смене года

При каждом вызове onYearChange обновляются:

  • внутренний календарный view;
  • состояние навигации;
  • активный год отображения.

При этом объект экземпляра остаётся тем же, что позволяет безопасно хранить ссылки на него и использовать в других частях приложения.