В Flatpickr события строятся вокруг экземпляра календаря и его жизненного цикла. Основные коллбеки передаются в конфигурации при инициализации и привязываются к конкретному экземпляру, а не к DOM-элементу напрямую. Это ключевой момент, из которого вытекает большинство проблем при интеграциях.
События в Flatpickr делятся на два типа:
onChange,
onOpen, onClose, onReady и
др.)Flatpickr не является «обёрткой над input change», он заменяет поведение поля ввода собственным состоянием. Поэтому стандартные браузерные события и внутренние события библиотеки могут расходиться по времени и смыслу.
Одна из частых проблем возникает при повторной инициализации календаря на одном и том же элементе.
При повторном вызове flatpickr(element, config)
предыдущие обработчики не всегда корректно очищаются, особенно если
ссылка на экземпляр не сохраняется и не вызывается
destroy().
Типичный эффект:
onChange вызывается дублированноПроблема усиливается при динамическом рендеринге (SPA, React, Vue), где компонент может инициализироваться несколько раз без корректного teardown.
Правильная модель поведения всегда требует хранения ссылки:
const fp = flatpickr("#date", {
onChange: () => {}
});
// при пересоздании
fp.destroy();
Flatpickr передаёт контекст экземпляра в this, но только
при использовании обычных функций.
Проблема возникает при использовании стрелочных функций:
onChange: (selectedDates) => {
console.log(this); // undefined или внешний контекст
}
Правильное поведение:
onChange: function(selectedDates) {
console.log(this); // экземпляр flatpickr
}
Это критично, поскольку через this доступна внутренняя
модель:
this.selectedDatesthis.currentMonththis.setDate()this.inputНарушение контекста приводит к тому, что код начинает работать «вслепую» без доступа к состоянию календаря.
Метод setDate() часто вызывает цепочку событий, которая
воспринимается как ошибка.
Поведение зависит от параметров:
triggerChange = true — события вызываютсяtriggerChange = false — события подавляютсяПроблема возникает при циклических обновлениях:
fp.setDate("2026-01-01");
fp.setDate("2026-01-02");
Каждый вызов может триггерить onChange, что приводит
к:
Типичный защитный паттерн — разделение «внутреннего» и «пользовательского» обновления:
fp.setDate(date, false);
При использовании Flatpickr в React/Vue/Angular возникает проблема повторной подписки.
Причина — жизненный цикл компонента:
В результате:
onChange срабатывает N разКлючевой источник проблемы — отсутствие destroy() при
unmount.
Flatpickr управляет значением input вручную, поэтому нативные события
input и change могут не соответствовать
реальному состоянию календаря.
Распространённый сценарий ошибки:
input.addEventListener("change", () => {
// ожидание актуальной даты
});
Но Flatpickr обновляет значение:
В результате нативное событие может сработать:
onChangeonCloseFlatpickr имеет внутренний порядок событий, который не всегда очевиден:
onReadyonOpenonMonthChangeonYearChangeonValueUpdateonChangeonCloseПроблема возникает, когда логика завязана на «предполагаемый порядок», например:
onChange всегда будет последнимonClose всегда следует после
onChangeВ реальности порядок может меняться при:
Flatpickr не всегда синхронно обновляет внутренние поля и input. Это приводит к состояниям гонки:
onChange: function() {
console.log(this.input.value);
}
Иногда значение input.value ещё не обновлено в момент
вызова события.
Это особенно заметно при:
Результат — «устаревшие» значения в обработчиках.
Flatpickr допускает несколько способов навешивания событий:
onChange)instance.config.onChange.push()Проблема в том, что второй способ добавляет обработчики, а не заменяет их:
fp.config.onChange.push(fn);
В результате:
Особенно опасно в динамических интерфейсах, где код выполняется несколько раз.
Метод destroy() не всегда гарантирует полное удаление
всех внешних ссылок, если:
fpТипичный эффект:
onChange продолжает срабатыватьПричина — утечки через внешние ссылки, а не через сам Flatpickr.
На мобильных устройствах Flatpickr часто переключается в альтернативный режим ввода.
Это влияет на события:
onOpen может не сработать при программном вызовеonClose зависит от системной клавиатурыonChange может срабатывать только при blurВ результате логика, завязанная на события, ведёт себя по-разному на десктопе и мобильных устройствах.
В режимах range и multiple события
становятся более «шумными»:
onChange вызывается при каждом кликеselectedDates изменяется постепенноПроблема возникает, когда обработчик ожидает финальное значение:
onChange: function(dates) {
// предполагается, что диапазон уже завершён
}
Но в режиме range финальная точка определяется только при втором выборе даты, а события уже были вызваны несколько раз.
Flatpickr не всегда блокирует всплытие событий DOM-элемента. Это приводит к конфликтам с родительскими обработчиками:
Часто требуется дополнительная изоляция:
click на контейнереstopPropagation в кастомных плагинахПри изменении DOM или CSS во время работы календаря (например, смена темы или скрытие блоков) могут происходить побочные эффекты:
onOpen вызывается повторноonClose срабатывает без действия пользователяЭто связано с тем, что Flatpickr реагирует на изменения layout и пересчитывает popper-позиционирование, что косвенно влияет на жизненный цикл событий.