Обработчик onClose

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

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

Закрытие календаря фиксируется в следующих ситуациях:

  • потеря фокуса полем ввода (в зависимости от конфигурации bound и blur-поведения);
  • клик вне области календаря;
  • повторное открытие/закрытие через API (hide() или переключение состояния);
  • выбор даты, если включена автоматическая скрывающая логика (hideOnSelect: true);
  • вызов picker.hide() из кода.

Сигнатура обработчика

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

Типичная форма объявления:

const picker = new Pikaday({
    field: document.getElementById('datepicker'),
    onClose: function () {
        console.log('Календарь закрыт');
    }
});

Внутри обработчика доступен экземпляр через this:

onClose: function () {
    this.getDate();      // текущая выбранная дата
    this.isVisible();    // состояние видимости
}

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

Контекст this внутри onClose указывает на текущий экземпляр Pikaday. Это позволяет обращаться ко всем публичным методам экземпляра:

  • getDate() — получение выбранной даты;
  • setDate() — изменение выбранной даты;
  • gotoToday() — переход к текущей дате;
  • destroy() — уничтожение экземпляра;
  • show() и hide() — управление видимостью;
  • isVisible() — проверка состояния отображения.

Использование контекста особенно важно при работе с несколькими инстансами календаря на одной странице.

Различие между onClose и onSelect

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

  • onSelect — реакция на изменение значения;
  • onClose — реакция на завершение взаимодействия.

При выборе даты календарь может закрываться автоматически, но это не означает, что onClose всегда совпадает с onSelect. Например, при ручном закрытии без выбора даты onClose сработает, а onSelect — нет.

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

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

При интеграции с формами важно фиксировать момент завершения работы с календарём:

onClose: function () {
    const date = this.getDate();
    if (date) {
        document.getElementById('hiddenField').value = date.toISOString();
    }
}

Валидация после закрытия календаря

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

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

    if (!date) {
        console.warn('Дата не выбрана');
        return;
    }

    validateDateRange(date);
}

Управление интерфейсом формы

onClose удобно использовать для изменения состояния элементов UI:

onClose: function () {
    document.body.classList.remove('calendar-open');
    this._input.blur();
}

Программное закрытие и влияние на onClose

При вызове метода hide() событие onClose также срабатывает, так как библиотека унифицирует поведение независимо от источника закрытия.

const picker = new Pikaday({
    field: document.getElementById('datepicker'),
    onClose: function () {
        console.log('Закрытие календаря');
    }
});

picker.hide();

Даже при программном управлении интерфейсом логика onClose остаётся актуальной для синхронизации состояния приложения.

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

Если календарь уже скрыт, повторный вызов hide() не приводит к повторному срабатыванию onClose. Это предотвращает дублирование логики и повторную обработку событий.

В случае быстрого переключения состояния (например, show()hide() подряд) важно учитывать асинхронность UI-обновлений, чтобы избежать гонок состояния.

Взаимодействие с фокусом и input-элементом

При привязанном поле ввода (field) закрытие календаря часто связано с потерей фокуса. В некоторых конфигурациях это приводит к цепочке событий:

  1. blur input;
  2. закрытие календаря;
  3. вызов onClose.

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

Практика работы с состоянием экземпляра

В сложных интерфейсах часто требуется хранить промежуточное состояние между открытием и закрытием календаря:

let tempState = null;

const picker = new Pikaday({
    field: document.getElementById('datepicker'),

    onOpen: function () {
        tempState = this.getDate();
    },

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

        if (finalDate !== tempState) {
            console.log('Дата была изменена перед закрытием');
        }
    }
});

Такой подход позволяет отслеживать изменения, даже если пользователь не подтвердил выбор явно.

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

  • onClose не предоставляет аргументов;
  • не гарантирует наличие выбранной даты;
  • может срабатывать при программных изменениях состояния;
  • зависит от конфигурации bound и поведения input-элемента;
  • не предназначен для изменения DOM календаря во время выполнения, так как элемент уже скрывается.

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