Использование с vanilla JavaScript

Одним из главных преимуществ Pikaday является полное отсутствие зависимости от пользовательских интерфейсных фреймворков. Библиотека может использоваться в проектах, построенных исключительно на vanilla JavaScript, без подключения React, Vue, Angular или других решений.

Pikaday представляет собой самостоятельный компонент выбора даты, который работает напрямую через DOM API браузера. Для отображения календаря достаточно создать HTML-элемент формы и связать его с экземпляром календаря.

Простейшая структура страницы выглядит следующим образом:

<input type="text" id="datepicker">

После подключения библиотеки создается экземпляр календаря:

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

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


Подключение библиотеки в чистом JavaScript

Наиболее распространенный способ подключения включает CSS-файл и JavaScript-файл библиотеки.

<link rel="stylesheet" href="pikaday.css">

<script src="pikaday.js"></script>

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

document.addEventListener('DOMContentLoaded', () => {
    const picker = new Pikaday({
        field: document.querySelector('#datepicker')
    });
});

Использование события DOMContentLoaded гарантирует, что необходимые элементы уже присутствуют в DOM-дереве.


Работа через стандартный DOM API

В проектах без фреймворков вся работа с календарем осуществляется через стандартные методы браузера.

Получение элемента:

const input = document.getElementById('date');

Создание календаря:

const picker = new Pikaday({
    field: input
});

Изменение даты:

picker.setDate(new Date());

Получение выбранной даты:

const selectedDate = picker.getDate();

console.log(selectedDate);

Очистка значения:

picker.setDate(null);

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


Создание нескольких календарей

Vanilla JavaScript позволяет легко создавать несколько экземпляров на одной странице.

HTML:

<input id="startDate">
<input id="endDate">

Jav * aScript:

const startPicker = new Pikaday({
    field: document.getElementById('startDate')
});

const endPicker = new Pikaday({
    field: document.getElementById('endDate')
});

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

Для большого количества полей удобно использовать цикл.

<input class="date-field">
<input class="date-field">
<input class="date-field">
const fields = document.querySelectorAll('.date-field');

fields.forEach(field => {
    new Pikaday({
        field: field
    });
});

Такой подход особенно полезен при динамическом формировании форм.


Использование событий браузера

Pikaday отлично сочетается со стандартной системой событий DOM.

Отслеживание изменения поля:

const input = document.getElementById('date');

input.addEventListener('change', event => {
    console.log(event.target.value);
});

Отслеживание выбора даты через сам Pikaday:

const picker = new Pikaday({
    field: input,

    onSelect(date) {
        console.log(date);
    }
});

Событие onSelect вызывается сразу после выбора даты пользователем.


Управление календарем через кнопки

В vanilla JavaScript часто используется программное управление интерфейсом.

Показ календаря:

document
    .getElementById('show')
    .addEventListener('click', () => {
        picker.show();
    });

Скрытие календаря:

document
    .getElementById('hide')
    .addEventListener('click', () => {
        picker.hide();
    });

Установка текущей даты:

document
    .getElementById('today')
    .addEventListener('click', () => {
        picker.setDate(new Date());
    });

Полная очистка:

document
    .getElementById('clear')
    .addEventListener('click', () => {
        picker.setDate(null);
    });

Подобные элементы управления часто используются в CRM-системах и административных интерфейсах.


Работа с динамически созданными элементами

В чистом JavaScript элементы нередко добавляются после загрузки страницы.

Например:

const input = document.createElement('input');

document.body.appendChild(input);

После вставки в DOM можно создать календарь:

new Pikaday({
    field: input
});

Также возможно создавать календарь непосредственно во время генерации элемента:

function createDateField() {
    const input = document.createElement('input');

    document.body.appendChild(input);

    new Pikaday({
        field: input
    });
}

Такой подход широко применяется в конструкторах форм.


Интеграция с HTML-формами

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

HTML:

<form id="orderForm">

    <input
        id="deliveryDate"
        name="deliveryDate">

    <button type="submit">
        Отправить
    </button>

</form>

Jav * aScript:

new Pikaday({
    field: document.getElementById('deliveryDate')
});

При отправке формы дата автоматически попадет в объект запроса.

Получение значения через Jav * aScript:

document
    .getElementById('orderForm')
    .addEventListener('submit', event => {

        event.preventDefault();

        const data = new FormData(event.target);

        console.log(
            data.get('deliveryDate')
        );
    });

Использование пользовательских обработчиков

Часто после выбора даты требуется выполнить дополнительную бизнес-логику.

Например:

new Pikaday({
    field: input,

    onSelect(date) {

        updatePrice(date);

        validateDate(date);

        saveDraft(date);
    }
});

Каждая функция отвечает за собственную задачу:

function updatePrice(date) {
    console.log('Обновление стоимости');
}

function validateDate(date) {
    console.log('Проверка даты');
}

function saveDraft(date) {
    console.log('Автосохранение');
}

Такое разделение делает код более поддерживаемым.


Использование модульной структуры

В современных проектах на vanilla JavaScript часто применяется разделение логики по модулям.

Модуль календаря:

export function createDatePicker(selector) {

    return new Pikaday({
        field: document.querySelector(selector)
    });

}

Основной файл:

import { createDatePicker }
from './datepicker.js';

const picker = createDatePicker('#date');

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


Связь нескольких календарей

Типичный пример — выбор периода.

<input id="from">
<input id="to">
const fromPicker = new Pikaday({
    field: document.getElementById('from')
});

const toPicker = new Pikaday({
    field: document.getElementById('to')
});

Синхронизация диапазона:

fromPicker.config.onSel ect = function(date) {

    toPicker.setMinDate(date);

};

Теперь конечная дата не сможет быть раньше начальной.

Дополнительная проверка:

toPicker.config.onSel ect = function(date) {

    fromPicker.setMaxDate(date);

};

В результате оба календаря образуют единую систему выбора периода.


Работа с AJAX-запросами

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

new Pikaday({
    field: input,

    async onSelect(date) {

        const response = await fetch(
            '/api/date-info',
            {
                method: 'POST',
                body: JSON.stringify({
                    date: date
                })
            }
        );

        const result = await response.json();

        console.log(result);
    }
});

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


Удаление экземпляра календаря

При динамическом изменении интерфейса может возникнуть необходимость уничтожить календарь.

picker.destroy();

После вызова метода:

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

Пример:

const container =
    document.getElementById('wrapper');

container.remove();

picker.destroy();

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


Организация кода в крупных проектах

По мере роста приложения рекомендуется отделять работу с календарем от бизнес-логики.

Пример структуры:

src/

├── calendar/
│   ├── createPicker.js
│   ├── events.js
│   └── validation.js
│
├── api/
│   └── requests.js
│
└── app.js

Создание календаря:

import { attachEvents }
from './events.js';

export function createPicker(field) {

    const picker = new Pikaday({
        field
    });

    attachEvents(picker);

    return picker;
}

Подобная организация позволяет сохранять читаемость кода даже при наличии десятков календарей и сложной логики взаимодействия между ними.


Преимущества использования Pikaday с vanilla JavaScript

Минимальный размер приложения

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

Прямой доступ к DOM

Все операции выполняются стандартными средствами браузера без промежуточных слоев абстракции.

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

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

Простота интеграции

Библиотека одинаково хорошо работает в статических страницах, серверно-рендеренных приложениях, CMS, административных панелях и пользовательских интерфейсах без SPA-архитектуры.

Независимость от экосистемы

Pikaday может использоваться практически в любом проекте JavaScript независимо от используемых инструментов сборки и архитектурных решений.