Одним из главных преимуществ Pikaday является полное отсутствие зависимости от пользовательских интерфейсных фреймворков. Библиотека может использоваться в проектах, построенных исключительно на vanilla JavaScript, без подключения React, Vue, Angular или других решений.
Pikaday представляет собой самостоятельный компонент выбора даты, который работает напрямую через DOM API браузера. Для отображения календаря достаточно создать HTML-элемент формы и связать его с экземпляром календаря.
Простейшая структура страницы выглядит следующим образом:
<input type="text" id="datepicker">
После подключения библиотеки создается экземпляр календаря:
const picker = new Pikaday({
field: document.getElementById('datepicker')
});
При фокусировке на поле ввода автоматически отображается календарь, а выбранная дата записывается в input.
Наиболее распространенный способ подключения включает 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-дереве.
В проектах без фреймворков вся работа с календарем осуществляется через стандартные методы браузера.
Получение элемента:
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
});
}
Такой подход широко применяется в конструкторах форм.
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);
};
В результате оба календаря образуют единую систему выбора периода.
После выбора даты можно выполнять асинхронные запросы.
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;
}
Подобная организация позволяет сохранять читаемость кода даже при наличии десятков календарей и сложной логики взаимодействия между ними.
Минимальный размер приложения
Отсутствует необходимость подключать тяжелые фреймворки ради одного календаря.
Прямой доступ к DOM
Все операции выполняются стандартными средствами браузера без промежуточных слоев абстракции.
Высокая производительность
Создание экземпляров происходит быстро, а количество дополнительного кода минимально.
Простота интеграции
Библиотека одинаково хорошо работает в статических страницах, серверно-рендеренных приложениях, CMS, административных панелях и пользовательских интерфейсах без SPA-архитектуры.
Независимость от экосистемы
Pikaday может использоваться практически в любом проекте JavaScript независимо от используемых инструментов сборки и архитектурных решений.