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();
        }    
    }
})
When using Popper.js, Air Datepicker will automatically rotate the pointer in the right direction! 😎

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
                })
            }
        }
    ]
})