Examples
On this page you could find a little examples of how Air Datepicker works and on what it capable of.
Basic examples
With default options
new AirDatepicker('#input');
Static calendar
If you want calendar to be always visible it should be initialized on block or inline element or just pass option {inline: true}
new AirDatepicker('#div');
// Or init with {inline: true} on <input> or <div> elements
new AirDatepicker('#input', {
inline: true
})
Select date on initialization
For selecting initial date use option selectedDates
. It accepts array of Dates, strings or numbers. You can read more about this option in documentation section. Lets choose today date.
new AirDatepicker('#el', {
selectedDates: [new Date()]
})
Month selection
For choosing only month without any certain date you could use combination of two options view
and minView
- with first option we setting up current view of calendar and with second we set minimal possible view.
new AirDatepicker('#el', {
view: 'months',
minView: 'months',
dateFormat: 'MMMM yyyy'
})
Mobile devices mode
Air Datepicker has a mode that allows you to open the calendar as a modal window - in this mode it appears in the center of the screen in slightly enlarged sizes to facilitate date selection.
new AirDatepicker('#el', {
isMobile: true,
autoClose: true,
});
Positioning
Position of the calendar is set up by position
option - it can be either a string or a function.
Basic positioning
The basic positioning is set via the string - "'main axis 'secondary axis'"
. For example, let us show calendar at the right of the text field:
new AirDatepicker('#el', {
position: 'right center'
})
Using of Popper.js
If more complex positioning is required, for example, when you need the calendar to jump to the other side of the text field when scrolling, etc., you can use manual positioning - using the function and third-party libraries
In the following example, we will process the position using the Popper.js library. Try to scroll the page further.
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
}
}
]
})
/*
Return function which will be called when `hide()` method is triggered,
it must necessarily call the `done()` function
to complete hiding process
*/
return function completeHide() {
popper.destroy();
done();
}
}
})
Create show\hide animation
Air Datepicker allows you to add your own hide and show animations. You can also do it yourself or use any library for animations.
For the next example, let's take the anime.js library and combine it with 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 of dates
For choosing range of dates use parameter {range: true}
. After selecting both dates you could correct them by dragging active dates.
new AirDatepicker('#input', {
range: true,
multipleDatesSeparator: ' - '
});
Prohibiting range selection
Sometimes there is a need to prohibit the user from selecting a date range if there are disabled cells in it, for this you can use the options onBeforeSelect and onFocus, as well as a small stylization of our range. Try to select a range from July 9 to 15:
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');
// Check if disabled date is in the range
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}) => {
// Dont allow user to select date, if disabled date is in the range
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;
}
Minimum and maximum dates
For manipulation with minimum and maximum possible dates use options minDate
and maxDate
. In combination with update()
function you could implement limited date range that user could choose.
let dpMin, dpMax;
dpMin = new AirDatepicker('#el1', {
onSelect({date}) {
dpMax.update({
minDate: date
})
}
})
dpMax = new AirDatepicker('#el2', {
onSelect({date}) {
dpMin.update({
maxDate: date
})
}
})
Timepicker
Pass {timepicker: true}
to be able to pick time. By default the user's time is set. Start datetime value could be configured with parameter startDate
.
new AirDatepicker('#input', {
timepicker: true,
});
Time format
Time format is set in localization object or in option {timeFormat: '...'}
. To display time in 12-hours format use 'h'
or 'hh'
tokens. To display day period use 'aa'
or 'AA'
new AirDatepicker('#input', {
timepicker: true,
timeFormat: 'hh:mm AA'
});
Minutes and hours settings
Time is configured by several options: minHours, maxHours, minMinutes, maxMinutes
. You could also set step of time slider with hoursStep, minutesStep
.
Let's try to limit time by interval from 8 to 19 hours and set minute step by 5.
new AirDatepicker({
inline: true,
timepicker: true,
minHours: 9,
maxHours: 18,
minutesStep: 5
})
Cells content
Air Datepicker allows you to change cells content anyway you want. Content, classes and status (active/disabled) are controlled by option {onRenderCell: ({date, cellType}) => {})}
.
In the next example let change cells content for dates from array to random emoji, and change active background color for such cells.
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;
}
Formatting title
In Air Datepicker you could change titles in calendar's navigation. You could use both static variant and dynamic - just pass a callback function to corresponding option. You could use both html tags and a special tokens to format date
Static title
new AirDatepicker('#el', {
navTitles: {
days: '<strong>yyyy</strong> <i>MMMM</i>',
months: 'Select month of <strong>yyyy</strong>'
}
})
Dynamic title
new AirDatepicker('#el', {
navTitles: {
days(dp) {
if (dp.selectedDates.length) {
let date = dp.selectedDates[0];
return `<small>
You've chosen ${dp.formatDate(date, 'dd MMMM yyyy')}
</small>`;
}
return 'Choose date';
}
}
})
Adding buttons
To make it easier to select a specific date, or to clear the selected data, you can add buttons to the calendar body. You can add one of the preset buttons or create your own. For more information, see documentation section.
Preinstalled buttons
To add buttons, use the buttons
option - it accepts an array of strings or an array of objects with a description of the button.
new AirDatepicker('#el', {
buttons: ['today', 'clear']
})
Make your own buttons
To create your own buttons, you need to pass a structure describing the content of the button and its behavior. Let's create a button that turns the timepikcer module on and off:
new AirDatepicker('#el', {
buttons: [
{
content(dp) {
return dp.opts.timepicker
? 'Turn OFF timepicker'
: 'Turn ON 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
})
}
}
]
})