Примеры
На этой странице собраны небольшие примеры того, как работает и на что способен Air Datepicker.
Базовые примеры
С опциями по умолчанию
new AirDatepicker('#input');
Статичный календарь
Для того, чтобы календарь был постоянно видимый, нужно его проинициализировать не на текстовом поле, или передать параметр {inline: true}
new AirDatepicker('#div');
// Or init with {inline: true} on <input> or <div> elements
new AirDatepicker('#input', {
inline: true
})
Выбор даты при инициализации
Для выбора даты используйте опцию selectedDates
. На принимает массив дат, строк или чисел. Подробнее можно ознакомится в разделе документации. Давайте выберем сегодняшнюю дату.
new AirDatepicker('#el', {
selectedDates: [new Date()]
})
Выбор месяца
Для возможности выбора только месяца без конкретного числа, можно использовать комбинацию из опций view
и minView
- с помощью первой мы устанавливаем текущее представление календаря, а с помощью второй задаем минимально возможное представление.
new AirDatepicker('#el', {
view: 'months',
minView: 'months',
dateFormat: 'MMMM yyyy'
})
Режим для мобильных устройств
У Air Datepicker есть режим, который позволяет открывать календарь как модальное окно - в этом режиме он появляется по центру экрана в немного увеличенных размерах для облегчения выбора даты.
new AirDatepicker('#el', {
isMobile: true,
autoClose: true,
});
Позиционирование
Позиция календаря задается с помощью параметра position
- он может быть как строкой так и функцией.
Простое позиционирование
Базовое позиционирование задается через строку - "'основная ось 'второстепенная ось'"
. Например, покажем календарь справа от текстового поля:
new AirDatepicker('#el', {
position: 'right center'
})
Использование Popper.js
Если требуется более сложное позиционирование, например когда нужно чтобы календарь перепрыгивал на другу сторону текстового поля при скролле и т.п. можно использовать ручное позиционирование - с помощью функции и сторонних библиотек
В следующем примере обработаем позицию с помощью библиотеки Popper.js. Попробуйте проскролить страницу дальше.
import AirDatepicker from 'air-datepicker';
import {createPopper} from '@popperjs/core';
new AirDatepicker('#el', {
container: '#scroll-container',
visible: true,
position({$datepicker, $target, $pointer, done}) {
let popper = createPopper($target, $datepicker, {
placement: 'top',
modifiers: [
{
name: 'flip',
options: {
padding: {
top: 64
}
}
},
{
name: 'offset',
options: {
offset: [0, 20]
}
},
{
name: 'arrow',
options: {
element: $pointer
}
}
]
})
/*
Возвращаем функцию, которая вызывается при срабатывании `hide()`,
она обязательно должна вызвать функцию `done()`
для завершения процесса скрытия календаря
*/
return function completeHide() {
popper.destroy();
done();
}
}
})
Создание анимации появления и скрытия
Air Datepicker позволяет добавить свои анимации появления и скрытия. Вы также можете сделать это своими руками или же использовать любую библиотеку для анимаций.
Для следующего примера возьмем библиотеку anime.js и объединим ее с Popper.js
import AirDatepicker from 'air-datepicker';
import {createPopper} from '@popperjs/core';
import anime from 'animejs';
new AirDatepicker('#el', {
position({$datepicker, $target, $pointer, isViewChange, done}) {
let popper = createPopper($target, $datepicker, {
placement: 'bottom',
onFirstUpdate: state => {
!isViewChange && anime.remove($datepicker);
$datepicker.style.transformOrigin = 'center top';
!isViewChange && anime({
targets: $datepicker,
opacity: [0, 1],
rotateX: [-90, 0],
easing: 'spring(1.3, 80, 5, 0)',
})
},
modifiers: [
{
name: 'offset',
options: {
offset: [0, 10]
}
},
{
name: 'arrow',
options: {
element: $pointer,
}
},
{
name: 'computeStyles',
options: {
gpuAcceleration: false,
},
},
]
});
return () => {
anime({
targets: $datepicker,
opacity: 0,
rotateX: -90,
duration: 300,
easing: 'easeOutCubic'
}).finished.then(() => {
popper.destroy();
done();
})
}
}}
)
Диапазон дат
Для того, чтобы выбрать диапазон дат, передайте параметр {range: true}
. После выбора обеих дат, можно скорректировать выбор просто перетаскивая активные даты.
new AirDatepicker('#input', {
range: true,
multipleDatesSeparator: ' - '
});
Запрет на выбор диапазона
Иногда есть необходимость запретить пользователю выбирать диапазон дат, если в нем есть недопустимые ячейки, для этого можно воспользоваться опциями onBeforeSelect и onFocus, а также небольшой стилизацией нашего диапазона. Попробуйте выбрать диапазон от 10 Июля до 16:
import AirDatepicker from 'air-datepicker';
import isWithinInterval from 'date-fns/isWithinInterval';
import isEqual from 'date-fns/isEqual';
const disabledDate = new Date('2023-07-13T00:00:00');
// Проверяем, находится ли недопустимая дата в диапазоне
const isDisabledDateIsInRange = ({date, datepicker}) => {
const selectedDate = datepicker.selectedDates[0];
if (selectedDate && datepicker.selectedDates.length === 1) {
const sortedDates = [selectedDate, date].toSorted((a, b) => {
if (a.getTime() > b.getTime()) {
return 1;
}
return -1;
})
return (isWithinInterval(disabledDate, {
start: sortedDates[0],
end: sortedDates[1]
}))
}
}
new AirDatepicker('#el', {
startDate: '2023-07-19',
range: true,
onBeforeSelect: ({date, datepicker}) => {
// Не даем выбрать дату, если недопустимая дата в диапазоне
return !isDisabledDateIsInRange({date, datepicker});
},
onFocus: ({date, datepicker}) => {
if (isDisabledDateIsInRange({date, datepicker}) || isEqual(date, disabledDate)) {
datepicker.$datepicker.classList.add('-disabled-range-')
} else {
datepicker.$datepicker.classList.remove('-disabled-range-')
}
}
onRenderCell: ({date}) => {
if (date.toLocaleDateString() === disabledDate.toLocaleDateString()) {
return {
disabled: true
}
}
}}
});
.air-datepicker.-disabled-range- {
--adp-cell-background-color-in-range: #eeeeee;
--adp-cell-background-color-selected: #d0d0d0;
}
Минимальная и максимальные даты
Для манипуляции с минимально возможной и максимально возможной датой используйте опции minDate
и maxDate
. В сочетании с функцией update()
можно реализовать выбор дат только в ограниченном диапазоне.
let dpMin, dpMax;
dpMin = new AirDatepicker('#el1', {
onSelect({date}) {
dpMax.update({
minDate: date
})
}
})
dpMax = new AirDatepicker('#el2', {
onSelect({date}) {
dpMin.update({
maxDate: date
})
}
})
Выбор времени
Передайте {timepicker: true}
для выбора времени. По умолчанию устанавливается текущее время пользователя. Стартовое значение даты и времени можно регулировать с помощью параметра startDate
.
new AirDatepicker('#input', {
timepicker: true,
});
Формат времени
Формат времени задается в объекте локализации или в опции {timeFormat: '...'}
. Для отображения времени в 12-ти часовом варианте, используйте символы 'h'
или 'hh'
. Чтобы отобразить период дня добавьте 'aa'
или 'AA'
.
new AirDatepicker('#input', {
timepicker: true,
timeFormat: 'hh:mm AA'
});
Настройка часов и минут
Время регулируется несколькими опциями, это minHours, maxHours, minMinutes, maxMinutes
. Также можно настраивать шаг шкалы выбора времени с помощью hoursStep, minutesStep
.
Давайте попробуем ограничивать выбор часов с 8 до 19 и добавить шаг выбора минут в значение 5.
new AirDatepicker({
inline: true,
timepicker: true,
minHours: 9,
maxHours: 18,
minutesStep: 5
})
Содержимое ячеек
Air Datepicker позволяет изменять содержимое ячеек как угодно. Содержание, классы и статус (активный/не доступный для выбора) регулируются с помощью опции {onRenderCell: ({date, cellType}) => {})}
.
В следующем примере заменим содержимое ячеек из списка дат на произвольную эмоджи, плюс поменяем активный цвет фона таких ячеек
let today = new Date();
new AirDatepicker('#inline-div', {
// Handle render process
onRenderCell({date, cellType}) {
let dates = [1, 5, 7, 10, 15, 20, 25],
emoji = ['💕', '😃', '🍙', '🍣', '🍻', '🎉', '🥁'],
isDay = cellType === 'day',
_date = date.getDate(),
shouldChangeContent = isDay && dates.includes(_date),
randomEmoji = emoji[Math.floor(Math.random() * emoji.length)];
return {
html: shouldChangeContent ? randomEmoji : undefined,
classes: shouldChangeContent ? '-emoji-cell-' : undefined,
attrs: {
title: shouldChangeContent ? randomEmoji : ''
}
}
},
// Select 10th day of the month
selectedDates: new Date(today.getFullYear(), today.getMonth(), 10)
});
.-emoji-cell- {
--adp-cell-background-color-selected: #ffb8ff;
--adp-cell-background-color-selected-hover: #fda5fd;
}
Изменение заголовков
В Air Datepicker есть возможность изменять подписи в навигации календаря. Можно использовать как статические варианты, так и динамические - передав функцию в соответствующую опцию. Вы можете использовать как html тэги, так и специальные токены для форматирования их в дату.
Статичный заголовок
new AirDatepicker('#el', {
navTitles: {
days: '<strong>yyyy</strong> <i>MMMM</i>',
months: 'Select month of <strong>yyyy</strong>'
}
})
Динамический заголовок
new AirDatepicker('#el', {
navTitles: {
days(dp) {
if (dp.selectedDates.length) {
let date = dp.selectedDates[0];
return `<small>
Вы выбрали ${dp.formatDate(date, 'dd MMMM yyyy')}
</small>`;
}
return 'Выберите дату';
}
}
})
Добавление кнопок
Для удобства выбора конкретной даты, или для очистки выбранных данных можно добавить кнопки в тело календаря. Вы можете добавить одну из предустановленных кнопок или же создать свою. Подробнее можно почитать в в разделе документации.
Предустановленные кнопки
Для добавления кнопок воспользуйтесь опцией buttons
- она принимает массив строк или массив объектов с описанием кнопки.
new AirDatepicker('#el', {
buttons: ['today', 'clear']
})
Создание своих кнопок
Для создания своих кнопок нужно передать структуру, описывающую контент кнопки и ее поведение. Давайте создадим кнопку, которая включает и выключает модуль выбора времени:
new AirDatepicker('#el', {
buttons: [
{
content(dp) {
return dp.opts.timepicker
? 'Выключить выбор времени'
: 'Включить выбор времени'
},
onClick(dp) {
let viewDate = dp.viewDate;
let today = new Date();
// Since timepicker takes initial time from 'viewDate', set up time here,
// otherwise time will be equal to 00:00 if user navigated through datepicker
viewDate.setHours(today.getHours());
viewDate.setMinutes(today.getMinutes());
dp.update({
timepicker: !dp.opts.timepicker,
viewDate
})
}
}
]
})