Библиотека Flatpickr изначально проектировалась как легковесный и гибкий инструмент для работы с датами, где ключевой архитектурный принцип — независимость каждого экземпляра календаря. Это означает, что на одной странице может существовать любое количество инстансов, каждый из которых изолирован по состоянию, конфигурации и DOM-привязке. Такая модель особенно важна для динамических интерфейсов, форм с повторяющимися блоками и сложных SPA-приложений.
Каждый вызов flatpickr() создаёт отдельный экземпляр,
связанный с конкретным DOM-элементом. При этом библиотека не требует
глобального регистра экземпляров и не использует централизованное
состояние.
flatpickr("#date1");
flatpickr("#date2");
flatpickr("#date3");
В данном случае создаются три независимых календаря, каждый из которых управляет только своим input-элементом.
Ключевая особенность заключается в том, что:
Чаще всего множественная инициализация выполняется через
querySelectorAll, что позволяет обработать набор элементов
одним вызовом логики.
document.querySelectorAll(".date-input").forEach((el) => {
flatpickr(el, {
dateFormat: "Y-m-d"
});
});
Такой подход используется при работе с формами, где одинаковые поля даты повторяются в списках, таблицах или карточках.
Особенности поведения:
Несмотря на массовую инициализацию, каждый элемент может получать уникальные настройки на основе атрибутов или данных DOM.
document.querySelectorAll(".date-input").forEach((el) => {
flatpickr(el, {
dateFormat: el.dataset.format || "Y-m-d",
minDate: el.dataset.min || null,
maxDate: el.dataset.max || null
});
});
Такой подход часто применяется в формах, где ограничения зависят от контекста:
При необходимости управления уже созданными календарями (например, программное изменение даты или уничтожение инстанса) требуется сохранять ссылки на объекты.
const instances = [];
document.querySelectorAll(".date-input").forEach((el) => {
const instance = flatpickr(el, {
enableTime: true
});
instances.push(instance);
});
Каждый экземпляр предоставляет API:
setDate()clear()destroy()open()close()Это позволяет централизованно управлять всеми календарями.
В интерфейсах, где DOM изменяется после загрузки страницы, новые элементы также могут быть инициализированы отдельно.
function initDatePicker(el) {
return flatpickr(el, {
dateFormat: "Y-m-d"
});
}
const container = document.querySelector("#container");
function addField() {
const input = document.createElement("input");
input.className = "date-input";
container.appendChild(input);
initDatePicker(input);
}
Каждый новый input получает собственный экземпляр без повторной инициализации остальных элементов.
При повторном запуске инициализации на одном и том же элементе может возникнуть проблема создания нескольких экземпляров. Flatpickr хранит ссылку на инстанс внутри DOM-узла, но при неправильной логике повторная инициализация возможна.
Типичный способ защиты:
document.querySelectorAll(".date-input").forEach((el) => {
if (el._flatpickr) return;
flatpickr(el);
});
Свойство _flatpickr содержит текущий экземпляр, если он
уже был создан.
Множественная инициализация особенно полезна при комбинировании различных режимов работы календаря.
flatpickr("#start-date", {
dateFormat: "Y-m-d"
});
flatpickr("#end-date", {
enableTime: true,
dateFormat: "Y-m-d H:i"
});
flatpickr("#birthday", {
maxDate: "today",
disableMobile: true
});
Каждый календарь работает в своём режиме, несмотря на одинаковую библиотеку.
Внутренне каждый инстанс хранит:
Это означает, что:
Каждый экземпляр генерирует собственные события, что позволяет отслеживать изменения независимо.
document.querySelectorAll(".date-input").forEach((el) => {
flatpickr(el, {
onChange: (selectedDates, dateStr) => {
console.log(el.id, dateStr);
}
});
});
При этом важно учитывать, что callback получает контекст конкретного инстанса, а не глобального состояния.
При большом числе календарей на странице (десятки или сотни) основная нагрузка возникает не на JavaScript-логике, а на DOM:
Практическая особенность Flatpickr:
При удалении элементов из DOM желательно корректно уничтожать связанные инстансы.
instances.forEach((instance) => {
instance.destroy();
});
После вызова destroy():
Множественная инициализация часто используется в:
Пример:
document.querySelectorAll("table .date-cell input").forEach((el) => {
flatpickr(el, {
allowInput: true
});
});
Каждая строка таблицы получает собственный независимый календарь, что критично для корректной обработки данных.
Хотя Flatpickr создаёт независимые инстансы, иногда используется делегирование для упрощения логики инициализации.
document.addEventListener("focusin", (e) => {
if (e.target.matches(".date-input") && !e.target._flatpickr) {
flatpickr(e.target);
}
});
Такой подход полезен для динамически генерируемого DOM без необходимости повторной ручной инициализации.
Поведение Flatpickr при множественной инициализации можно свести к следующим принципам:
_flatpickr.Такая модель делает библиотеку предсказуемой в сложных интерфейсах с большим количеством форм и динамических элементов.