Параметр onClose

В библиотеке Pikaday параметр onClose относится к событиям жизненного цикла календаря и вызывается в момент закрытия виджета выбора даты. Он предоставляет точку расширения, через которую можно синхронизировать состояние интерфейса, выполнять валидацию, инициировать побочные эффекты или связывать календарь с внешними компонентами формы.

onClose определяется как функция обратного вызова:

onClose: function() {
}

Функция вызывается каждый раз, когда календарь перестаёт быть видимым. Закрытие может происходить по следующим причинам:

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

Важно учитывать, что onClose не связан напрямую с выбором даты. Он срабатывает именно на событие скрытия UI, независимо от того, была ли изменена дата.

Контекст выполнения

В момент вызова onClose контекст this внутри функции указывает на экземпляр Pikaday. Это позволяет получать доступ к состоянию календаря:

var picker = new Pikaday({
    field: document.getElementById('date'),
    onClose: function() {
        console.log(this.getDate());
    }
});

Методы экземпляра, доступные в этом контексте:

  • getDate() — текущая выбранная дата;
  • getMoment() — объект moment.js, если используется интеграция;
  • getMaxDate() и getMinDate() — границы диапазона;
  • isVisible() — состояние отображения.

Использование контекста позволяет строить логики, завязанные на финальное состояние календаря после закрытия.

Типовые сценарии использования

Синхронизация с внешними UI-компонентами

Часто onClose применяется для обновления интерфейса формы после завершения работы календаря:

onClose: function() {
    document.getElementById('status').textContent = 'Календарь закрыт';
}

Это позволяет фиксировать момент завершения взаимодействия.

Валидация выбранного значения

Закрытие календаря является удобной точкой для финальной проверки корректности выбранной даты:

onClose: function() {
    const date = this.getDate();

    if (date && date.getFullYear() < 2000) {
        alert('Дата вне допустимого диапазона');
        this.setDate(null);
    }
}

Здесь логика выполняется один раз после завершения выбора, а не на каждом изменении.

Автоматическая отправка формы

onClose часто используется для триггера отправки данных:

onClose: function() {
    const form = document.getElementById('form');

    if (this.getDate()) {
        form.submit();
    }
}

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

Отличие от onSelect

Ключевое различие между onClose и onSelect заключается в моменте вызова:

  • onSelect вызывается при выборе даты;
  • onClose вызывается при закрытии календаря.
onSelect: function(date) {
    console.log('Выбрана дата:', date);
},

onClose: function() {
    console.log('Календарь закрыт');
}

Эти два события часто используются совместно, но решают разные задачи: первое фиксирует изменение данных, второе — завершение взаимодействия.

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

При вызове метода hide() календаря onClose также активируется:

picker.hide();

Это означает, что любые программные сценарии закрытия считаются эквивалентными пользовательскому закрытию. Следовательно, логика внутри onClose должна быть устойчивой к отсутствию пользовательского ввода в момент вызова.

Взаимодействие с blur и focus

onClose может пересекаться по времени с потерей фокуса поля ввода. Однако важно различать:

  • потеря фокуса (blur) относится к DOM-элементу;
  • onClose относится к состоянию календаря.

В некоторых конфигурациях blur может инициировать закрытие календаря, что косвенно приводит к вызову onClose.

field.addEventListener('blur', function() {
    console.log('Поле потеряло фокус');
});

При этом порядок вызовов зависит от внутренней реализации и может варьироваться.

Особенности повторных вызовов

При некоторых сценариях onClose может вызываться несколько раз подряд, например:

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

Поэтому внутри обработчика не рекомендуется хранить критичное состояние без проверок:

onClose: function() {
    if (this._alreadyClosed) return;

    this._alreadyClosed = true;
    console.log('Закрытие обработано один раз');
}

Работа с асинхронными операциями

При использовании асинхронных действий внутри onClose важно учитывать, что календарь уже считается завершившим взаимодействие:

onClose: function() {
    const value = this.getDate();

    setTimeout(() => {
        console.log('Отложенная обработка:', value);
    }, 0);
}

Это позволяет безопасно отделять UI-событие от фоновой обработки данных.

Ограничения и практические нюансы

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

Построение логики только на onClose приводит к потере информации о факте выбора значения, поэтому он чаще выступает завершающим этапом цепочки взаимодействий.

Связь с жизненным циклом календаря

В контексте жизненного цикла Pikaday обработчик onClose завершает активную фазу взаимодействия пользователя с календарём. Он логически следует после:

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

И фиксирует переход к состоянию «неактивен / скрыт», что делает его удобной точкой интеграции с внешними системами управления формами и интерфейсами.