Calendar / Datepicker

Calendar is a touch optimized component that provides an easy way to handle dates.

Calendar could be used as inline component or as overlay. Overlay Calendar will be automatically converted to Popover on tablets (iPad).

Calendar App Methods

Let's look at related App methods to work with Calendar:

app.calendar.create(parameters)- create Calendar instance

  • parameters - object. Object with calendar parameters

Method returns created Calendar's instance

app.calendar.destroy(el)- destroy Calendar instance

  • el - HTMLElement or string (with CSS Selector) or object. Calendar element or Calendar instance to destroy.

app.calendar.get(el)- get Calendar instance by HTML element

  • el - HTMLElement or string (with CSS Selector). Calendar element.

Method returns Calendar's instance

app.calendar.close(el)- close Calendar

  • el - HTMLElement or string (with CSS Selector). Calendar element to close.

Method returns Calendar's instance

For example:

var calendar = app.calendar.create({
    inputEl: '#calendar-input'
});

Calendar Parameters

Let's look on list of all available Calendar parameters:

ParameterTypeDefaultDescription
localestring

Calendar locale. Should be a correct locale accepted by Intl.DateTimeFormat. If not specified (by default), it will use browser locale.

For example en-US, ru, en, en-US-u-ca-buddhist, etc.

valuearrayArray with initial selected dates. Each array item represents selected date
disabledDate RangeAdditional disabled dates. Parameter accepts so called Date Range (look below for details)
eventsDate Range

Dates with events. Will be marked with additional "dot" on calendar day. Parameter accepts so called Date Range (look below for details).

If you want to indicate that day has few different events, it is possible to indicate this with multiple different color dots. In this case, you need to pass date range as array where each object will have date and color properties, e.g.

[
  {
    date: new Date(2018, 4, 11),
    color: '#2196f3',
  },
  // same date but different color, one more dot will be added to this day
  {
    date: new Date(2018, 4, 11),
    color: '#4caf50',
  },
]
rangesClassesarrayDate ranges you want to add custom CSS class for additional styling. Look below for accepted format
formatValuefunction (values)Function to format input value, should return new/formatted string value. values is an array where each item represents selected date. Can be used instead of dateFormat parameter to specify custom formatting
monthNamesarrayautoArray with full month names. If auto then it will display month names based on specified locale (or browser locale)
monthNamesShortarrayautoArray with short month names. If auto then it will display month names based on specified locale (or browser locale)
dayNamesarrayautoArray with week day names. If auto then it will display day names based on specified locale (or browser locale)
dayNamesShortarrayautoArray with week day short names. If auto then it will day names based on specified locale (or browser locale)
firstDaynumber1First day of the week. By default 1 - Monday
weekendDaysarray[0, 6]Array with index numeber of weekend days, by default it is Saturday and Sunday
dateFormatstring
object
undefined

If undefined, it will use format based on locale (or browser locale).

It can accept Intl.DateTimeFormat.options.

For example { month: 'long', day: 'numeric' }.

Or you can pass string with special tokens, available expressions:

  • yyyy - 4 digits year
  • yy - 2 digits year
  • mm - 2 digits month number, from 01 to 12
  • m - month number, from 1 to 12
  • MM - full month name
  • M - short month name
  • dd - 2 digits day number, from 01 to 31
  • d - day number, from 1 to 31
  • DD - full week day name
  • D - short week day name

The following additional time expressions available when timePicker enabled:

  • HH - 24-hours format 2 digits hours (00 - 23)
  • H - 24-hours format hours (0 - 23)
  • hh - 12-hours format 2 digits hours (00 - 12)
  • h - 12-hours format hours (0 - 12)
  • :mm - 2 digits minutes (00 - 59)
  • :m - minutes (0 - 59)
  • ss - 2 digits seconds (00 - 59)
  • s - seconds (0 - 59)
  • A - uppercased post or ante meridiem (PM or AM)
  • a - lowercased post or ante meridiem (pm or am)
multiplebooleanfalseEnable to allows select multiple dates/values
rangePickerbooleanfalseEnable to enable range picker. Not compatible with multiple
rangePickerMinDaysnumber1Minimum days that need to be selected when rangePicker enabled
rangePickerMaxDaysnumber0Maximum days allowed to be selected when rangePicker enabled. 0 means no maximum
directionstring'horizontal'Months layout direction, could be 'horizontal' or 'vertical'
minDateDatenullMinimum allowed date
maxDateDatenullMaximum allowed date
touchMovebooleantrueIf enabled then calendar months slides follow finger during touch move
animatebooleantrueEnables transition between months
closeOnSelectbooleanfalseEnable and calendar will be closed when user pick a date
weekHeaderbooleantrueEnable week header with short name week days
monthSelectorbooleantrueEnable month selector in toolbar
monthPickerbooleantrueEnables month picker to select a month when clicked on a month selector in toolbar
yearSelectorbooleantrueEnable year picker in toolbar
yearPickerbooleantrueEnables year picker to select a year when clicked on a year selector in toolbar
yearPickerMinnumberMinimum available year for year picker, by default is today minus 100 years
yearPickerMaxnumberMaximum available year for year picker, by default is today plus 100 years
timePickerbooleanfalseEnables time picker.
timePickerFormatobject{hour: 'numeric', minute: 'numeric'}

Time format displayed in time selector. It accepts Intl.DateTimeFormat.options

AM/PM format depends on selected specified locale, or on browser locale if not specified

timePickerPlaceholderstringSelect timeText to display in time selector placeholder.
Container/opener-specific parameters
containerElstring
HTMLElement
String with CSS selector or HTMLElement where to place generated Calendar HTML. Use only for inline calendar
openInstringautoCan be auto, popover (to open calendar in popover), sheet (to open in sheet modal) or customModal (to open in custom Calendar modal overlay). In case of auto will open in sheet modal on small screens and in popover on large screens.
sheetPushbooleanfalseEnables Calendar sheet to push view/s behind on open
sheetSwipeToClosebooleanundefinedEnables ability to close Calendar sheet with swipe. When not specified it inherits app's Sheet swipeToClose parameter
inputElstring or HTMLElementString with CSS selector or HTMLElement with related input element
scrollToInputbooleantrueScroll viewport (page-content) to input when calendar opened
inputReadOnlybooleantrueSets "readonly" attribute on specified input
cssClassstringAdditional CSS class name to be set on calendar element
closeByOutsideClickbooleantrueIf enabled, picker will be closed by clicking outside of picker or related input element
toolbarbooleantrueEnables calendar toolbar
toolbarCloseTextstringDoneText for Done/Close toolbar button
headerbooleanfalseEnables calendar header
headerPlaceholderstringSelect dateDefault calendar header placeholder text
routableModalsbooleanfalseWill add opened calendar to router history which gives ability to close calendar by going back in router history and set current route to the calendar modal
urlstringdate/Calendar modal URL that will be set as a current route
viewobjectView where to set routing when routableModals enabled. Defaults to parent view of inputEl or main view if not found parent view
backdropbooleanEnables Calendar backdrop (dark semi transparent layer behind). By default only it is enabled when Calendar opened in Popover.
closeByBackdropClickbooleantrueWhen enabled, Calendar will be closed on backdrop click
Render Functions
renderWeekHeaderfunctionFunction to render week header. Must return week header HTML string
renderMonthsfunction(date)Function to render months wrapper. Must return months container full HTML string
renderMonthfunction(date, offset)Function to render single month. Must return single month HTML string
renderMonthSelectorfunctionFunction to render month selector. Must return month selector HTML string
renderYearSelectorfunctionFunction to render year selector. Must return year selector HTML string
renderHeaderfunctionFunction to render calendar header. Must return calendar header HTML string
renderToolbarfunctionFunction to render toolbar. Must return toolbar HTML string
renderfunctionFunction to render whole calendar. Must return calendar full HTML string
Events
onobject

Object with events handlers. For example:

var calendar = app.calendar.create({
  ...
  on: {
    opened: function () {
      console.log('Calendar opened')
    }
  }
})

Note that all following parameters can be used in global app parameters under calendar property to set defaults for all calendars. For example:

var app = new Framework7({
  calendar: {
    url: 'calendar/',
    dateFormat: 'dd.mm.yyyy',
  }
});

Date Range

Some of Calendar parameters (disabled, events and rangesClasses) accept so called Date Range. It is a simple way to specify and cover all possible dates combination.

It can be array with dates, for example:

var calendar = app.calendar.create({
    ...
    // Disabled 10th November 2015 and 11th November 2015:
    disabled: [new Date(2015, 10, 10), new Date(2015, 10, 11)],
    ...
});

It can be custom function where you need to return true or false

var calendar = app.calendar.create({
    ...
    //Disabled all dates in November 2015
    disabled: function (date) {
        if (date.getFullYear() === 2015 && date.getMonth() === 10) {
            return true;
        }
        else {
            return false;
        }
    },
    ...
});

Or object with from and to properties

var calendar = app.calendar.create({
    ...
    //Disable all dates between 1st October 2015 and 31 December 2015
    disabled: {
        from: new Date(2015, 9, 1),
        to: new Date(2015, 11, 31)
    },
    ...
});

Or object with just from or to properties

var calendar = app.calendar.create({
    ...
    //Disable everyting since December 2015
    disabled: {
        from: new Date(2015, 11, 1)
    },
    ...
});

Or object with date property:

var calendar = app.calendar.create({
    ...
    // Disabled 1th December 2015
    disabled: {
        date: new Date(2015, 11, 1)
    },
    ...
});

Or array with mixed dates and objects:

var calendar = app.calendar.create({
    ...
    events: [
        new Date(2015, 9, 1),
        new Date(2015, 9, 5),
        {
            from: new Date(2015, 9, 10),
            to: new Date(2015, 9, 15)
        },
        {
            from: new Date(2015, 9, 20),
            to: new Date(2015, 9, 31)
        },
        {
            date: new Date(2015, 11, 1),
            color: '#ff0000'
        },
        // same date but one more color dot will be added
        {
            date: new Date(2015, 11, 1),
            color: '#00ff00'
        },
    ],
    ...
});

rangesClasses

rangesClasses parameter accepts array of objects with Date Range and class names for this range:

var calendar = app.calendar.create({
    ...
    //Add classes for november and october
    rangesClasses: [
        //Add "day-october' class for all october dates
        {
            // string CSS class name for this range in "cssClass" property
            cssClass: 'day-october', //string CSS class
            // Date Range in "range" property
            range: function (date) {
                return date.getMonth() === 9
            }
        },
        //Add "day-holiday" class for 1-10th January 2016
        {
            cssClass: 'day-holiday',
            range: {
                from: new Date(2016, 0, 1),
                to: new Date(2016, 0, 10)
            }
        }
    ],
    ...
});

Calendar Methods & Properties

After we initialize Calendar we have its initialized instance in variable (like calendar variable in examples above) with helpful methods and properties:

Properties
calendar.appLink to global app instance
calendar.containerElCalendar wrapping container HTML element (when inline calendar is in use)
calendar.$containerElDom7 instance with calendar wrapping container HTML element (when inline calendar is in use)
calendar.elCalendar HTML element
calendar.$elDom7 instance with calendar HTML element
calendar.inputElCalendar input HTML element (passed in inputEl parameter)
calendar.$inputElDom7 instance with calendar input HTML element (passed in inputEl parameter)
calendar.valueArray where each item represents selected date
calendar.currentMonthCalendar view current month. Number, from 0 to 11
calendar.currentYearCalendar view current year. Number, for example 2020
calendar.openedtrue if Calendar is currently opened
calendar.inlinetrue when inline calendar is in use
calendar.colsArray with specified Calendar columns. Each column also has its own methods and properties (look below)
calendar.urlCalendar URL (that was passed in url parameter)
calendar.viewCalendar View (that was passed in view parameter) or found parent view
calendar.paramsObject with initialization parameters
calendar.allowTouchMoveSet this flag to false to prevent touch move interactions after initialization
Methods
calendar.setValue(values)Set new selected dates. values is array where each item represents selected date
calendar.getValue()Returns current calendar value
calendar.addValue()Adds value to the values array. Useful in case if multiple selection is enabled (with multiple: true parameter)
calendar.update()Rerenders calendar. Useful in case you added/changed values dynamically and need to update calendar layout
calendar.nextMonth(duration)Calendar transition to next month for specified duration in ms
calendar.prevMonth(duration)Calendar transition to previous month for specified duration in ms
calendar.nextYear()Calendar transition to next year
calendar.prevYear()Calendar transition to previous year
calendar.setYearMonth(year, month, duration)Calendar transition to specified year, month for specified duration in ms
calendar.open()Open Calendar
calendar.close()Close Calendar
calendar.destroy()Destroy Calendar instance and remove all events
calendar.on(event, handler)Add event handler
calendar.once(event, handler)Add event handler that will be removed after it was fired
calendar.off(event, handler)Remove event handler
calendar.off(event)Remove all handlers for specified event
calendar.emit(event, ...args)Fire event on instance

Calendar Events

Calendar will fire the following DOM events on calendar element and events on app and calendar instance:

DOM Events

EventTargetDescription
calendar:openCalendar Element<div class="calendar">Event will be triggered when Calendar starts its opening animation
calendar:openedCalendar Element<div class="calendar">Event will be triggered after Calendar completes its opening animation
calendar:closeCalendar Element<div class="calendar">Event will be triggered when Calendar starts its closing animation
calendar:closedCalendar Element<div class="calendar">Event will be triggered after Calendar completes its closing animation

App and Calendar Instance Events

Calendar instance emits events on both self instance and app instance. App instance events has same names prefixed with calendar.

EventTargetArgumentsDescription
dayClickcalendar(calendar, dayEl, year, month, day)Event will be triggered after click on calendar day element
calendarDayClickapp
changecalendar(calendar, value)Event will be triggered when calendar value changes
calendarChangeapp
monthAddcalendar(calendar, monthEl)Event will be triggered when new month HTML layout has been added. Useful if you need to postprocess added html elements
calendarMonthAddapp
monthYearChangeStartcalendar(calendar, year, month)Event will be triggered in the begining of transition to next month
calendarMonthYearChangeStartapp
monthYearChangeEndcalendar(calendar, year, month)Event will be triggered after transition to next month
calendarMonthYearChangeEndapp
initcalendar(calendar)Event will be triggered when calendar initialized
calendarInitapp
opencalendar(calendar)Event will be triggered when Calendar starts its opening animation. As an argument event handler receives calendar instance
calendarOpenapp
openedcalendar(calendar)Event will be triggered after Calendar completes its opening animation. As an argument event handler receives calendar instance
calendarOpenedapp
closecalendar(calendar)Event will be triggered when Calendar starts its closing animation. As an argument event handler receives calendar instance
calendarCloseapp
closedcalendar(calendar)Event will be triggered after Calendar completes its closing animation. As an argument event handler receives calendar instance
calendarClosedapp
beforeDestroycalendar(calendar)Event will be triggered right before Calendar instance will be destroyed. As an argument event handler receives calendar instance
calendarBeforeDestroyapp

CSS Variables

Below is the list of related CSS variables (CSS custom properties).

Note that commented variables are not specified by default and their values is what they fallback to in this case.

:root {
  --f7-calendar-height: 340px;
  --f7-calendar-sheet-landscape-height: 220px;
  --f7-calendar-popover-width: 320px;
  --f7-calendar-popover-height: 320px;
  --f7-calendar-modal-height: 420px;
  --f7-calendar-modal-max-width: 380px;
  /*
  --f7-calendar-header-bg-color: var(--f7-bars-bg-color);
  --f7-calendar-header-link-color: var(--f7-bars-link-color);
  --f7-calendar-header-text-color: var(--f7-bars-text-color);
  --f7-calendar-footer-bg-color: var(--f7-bars-bg-color);
  --f7-calendar-footer-border-color: var(--f7-bars-border-color);
  --f7-calendar-footer-link-color: var(--f7-bars-link-color);
  --f7-calendar-footer-text-color: var(--f7-bars-text-color);
  */
  --f7-calendar-week-header-bg-color: transparent;
  --f7-calendar-footer-padding: 0 8px;
  --f7-calendar-week-header-font-size: 11px;
  /*
  --f7-calendar-selected-bg-color:  var(--f7-theme-color);
  */
  --f7-calendar-disabled-text-color: #d4d4d4;
  --f7-calendar-event-dot-size: 4px;
  /*
  --f7-calendar-event-bg-color: var(--f7-theme-color);
  */
  /*
  --f7-calendar-picker-selected-text-color: var(--f7-theme-color);
  */
  --f7-calendar-time-selector-height: 28px;
  --f7-calendar-picker-pressed-bg-color: rgba(0, 0, 0, 0.1);
  --f7-calendar-picker-hover-bg-color: rgba(0, 0, 0, 0.03);
  --f7-calendar-time-selector-bg-color: rgba(0, 0, 0, 0.05);
}
:root .dark,
:root.dark {
  --f7-calendar-picker-pressed-bg-color: rgba(255, 255, 255, 0.08);
  --f7-calendar-picker-hover-bg-color: rgba(255, 255, 255, 0.03);
  --f7-calendar-time-selector-bg-color: rgba(255, 255, 255, 0.1);
}
.ios {
  --f7-calendar-selected-text-color: #fff;
  --f7-calendar-header-height: 44px;
  --f7-calendar-header-font-size: 17px;
  --f7-calendar-header-font-weight: 600;
  --f7-calendar-header-padding: 0 8px;
  --f7-calendar-footer-height: 44px;
  --f7-calendar-footer-font-size: 17px;
  --f7-calendar-week-header-height: 18px;
  --f7-calendar-day-font-size: 15px;
  --f7-calendar-day-size: 30px;
  --f7-calendar-picker-font-size: 17px;
  --f7-calendar-time-selector-font-size: 17px;
  --f7-calendar-modal-border-radius: 4px;
  --f7-calendar-modal-box-shadow: 0px 11px 15px -7px rgba(0, 0, 0, 0.2),
                                  0px 24px 38px 3px rgba(0, 0, 0, 0.14),
                                  0px 9px 46px 8px rgba(0, 0, 0, 0.12);
  --f7-calendar-prev-next-text-color: #c8c8c8;
  --f7-calendar-sheet-border-color: #929499;
  --f7-calendar-sheet-bg-color: #fff;
  --f7-calendar-week-header-text-color: #5e5e5e;
  --f7-calendar-modal-bg-color: #fff;
  --f7-calendar-day-text-color: #000;
  --f7-calendar-today-text-color: #000;
  --f7-calendar-today-bg-color: #e3e3e3;
}
.ios .dark,
.ios.dark {
  --f7-calendar-prev-next-text-color: #5e5e5e;
  --f7-calendar-sheet-border-color: var(--f7-bars-border-color);
  --f7-calendar-sheet-bg-color: #121212;
  --f7-calendar-week-header-text-color: #aaa;
  --f7-calendar-modal-bg-color: #121212;
  --f7-calendar-day-text-color: #fff;
  --f7-calendar-today-text-color: #fff;
  --f7-calendar-today-bg-color: #333;
}
.md {
  --f7-calendar-sheet-border-color: transparent;
  --f7-calendar-header-height: 64px;
  --f7-calendar-header-font-size: 24px;
  --f7-calendar-header-font-weight: 400;
  --f7-calendar-header-padding: 0 24px;
  --f7-calendar-footer-height: 56px;
  --f7-calendar-footer-font-size: 14px;
  --f7-calendar-week-header-height: 24px;
  --f7-calendar-day-font-size: 14px;
  --f7-calendar-today-bg-color: none;
  --f7-calendar-day-size: 32px;
  --f7-calendar-picker-font-size: 14px;
  --f7-calendar-time-selector-font-size: 14px;
  --f7-calendar-modal-border-radius: 28px;
  --f7-calendar-modal-box-shadow: none;
}
.md,
.md .dark,
.md [class*='color-'] {
  --f7-calendar-sheet-bg-color: var(--f7-md-surface-1);
  --f7-calendar-selected-text-color: var(--f7-md-on-primary);
  --f7-calendar-week-header-text-color: var(--f7-md-on-surface-variant);
  --f7-calendar-day-text-color: var(--f7-md-on-surface);
  --f7-calendar-prev-next-text-color: rgba(var(--f7-md-on-surface-variant-rgb), 0.55);
  --f7-calendar-today-text-color: var(--f7-theme-color);
  --f7-calendar-modal-bg-color: var(--f7-md-surface-1);
}

Examples

calendar.html
<template>
  <div class="page">
    <div class="navbar">
      <div class="navbar-bg"></div>
      <div class="navbar-inner sliding">
        <div class="title">Calendar</div>
      </div>
    </div>
    <div class="page-content">
      <div class="block">
        <p>Calendar is a touch optimized component that provides an easy way to handle dates.</p>
        <p>Calendar could be used as inline component or as overlay. Overlay Calendar will be automatically converted to
          Popover on tablets (iPad).</p>
      </div>
      <div class="block-title">Default setup</div>
      <div class="list list-strong-ios list-outline-ios">
        <ul>
          <li>
            <div class="item-content item-input">
              <div class="item-inner">
                <div class="item-input-wrap">
                  <input type="text" placeholder="Your birth date" readonly="readonly" id="demo-calendar-default" />
                </div>
              </div>
            </div>
          </li>
        </ul>
      </div>
      <div class="block-title">Custom date format</div>
      <div class="list list-strong-ios list-outline-ios">
        <ul>
          <li>
            <div class="item-content item-input">
              <div class="item-inner">
                <div class="item-input-wrap">
                  <input type="text" placeholder="Select date" readonly="readonly" id="demo-calendar-date-format" />
                </div>
              </div>
            </div>
          </li>
        </ul>
      </div>
      <div class="block-title">Date + Time</div>
      <div class="list list-strong-ios list-outline-ios">
        <ul>
          <li>
            <div class="item-content item-input">
              <div class="item-inner">
                <div class="item-input-wrap">
                  <input type="text" placeholder="Select date and time" readonly="readonly"
                    id="demo-calendar-date-time" />
                </div>
              </div>
            </div>
          </li>
        </ul>
      </div>
      <div class="block-title">Multiple Values</div>
      <div class="list list-strong-ios list-outline-ios">
        <ul>
          <li>
            <div class="item-content item-input">
              <div class="item-inner">
                <div class="item-input-wrap">
                  <input type="text" placeholder="Select multiple dates" readonly="readonly"
                    id="demo-calendar-multiple" />
                </div>
              </div>
            </div>
          </li>
        </ul>
      </div>
      <div class="block-title">Range Picker</div>
      <div class="list list-strong-ios list-outline-ios">
        <ul>
          <li>
            <div class="item-content item-input">
              <div class="item-inner">
                <div class="item-input-wrap">
                  <input type="text" placeholder="Select date range" readonly="readonly" id="demo-calendar-range" />
                </div>
              </div>
            </div>
          </li>
        </ul>
      </div>
      <div class="block-title">Open in Modal</div>
      <div class="list list-strong-ios list-outline-ios">
        <ul>
          <li>
            <div class="item-content item-input">
              <div class="item-inner">
                <div class="item-input-wrap">
                  <input type="text" placeholder="Select date" readonly="readonly" id="demo-calendar-modal" />
                </div>
              </div>
            </div>
          </li>
        </ul>
      </div>
      <div class="block-title">Calendar Page</div>
      <div class="list list-strong list-outline-ios">
        <ul>
          <li>
            <a href="/calendar-page/" class="item-content item-link">
              <div class="item-inner">
                <div class="item-title">Open Calendar Page</div>
              </div>
            </a>
          </li>
        </ul>
      </div>
      <div class="block-title">Inline with custom toolbar</div>
      <div class="block block-strong no-padding">
        <div id="demo-calendar-inline-container"></div>
      </div>
    </div>
  </div>
</template>
<script>
  export default (props, { $f7, $, $on }) => {
    let calendarDefault
    let calendarDateFormat;
    let calendarDateTime;
    let calendarMultiple;
    let calendarRange;
    let calendarModal;
    let calendarInline;
    $on('pageInit', () => {
      // Default
      calendarDefault = $f7.calendar.create({
        inputEl: '#demo-calendar-default',
      });

      // With custom date format
      calendarDateFormat = $f7.calendar.create({
        inputEl: '#demo-calendar-date-format',
        dateFormat: { weekday: 'long', month: 'long', day: '2-digit', year: 'numeric' },
      });

      // Date + Time
      calendarDateTime = $f7.calendar.create({
        inputEl: '#demo-calendar-date-time',
        timePicker: true,
        dateFormat: { month: 'numeric', day: 'numeric', year: 'numeric', hour: 'numeric', minute: 'numeric' },
      });

      // With multiple values
      calendarMultiple = $f7.calendar.create({
        inputEl: '#demo-calendar-multiple',
        dateFormat: { month: 'short', day: 'numeric' },
        multiple: true
      });
      // Range Picker
      calendarRange = $f7.calendar.create({
        inputEl: '#demo-calendar-range',
        rangePicker: true
      });
      // Custom modal
      calendarModal = $f7.calendar.create({
        inputEl: '#demo-calendar-modal',
        openIn: 'customModal',
        header: true,
        footer: true,
      });
      // Inline with custom toolbar
      var monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
      calendarInline = $f7.calendar.create({
        containerEl: '#demo-calendar-inline-container',
        value: [new Date()],
        renderToolbar: function () {
          return '<div class="toolbar calendar-custom-toolbar no-shadow">' +
            '<div class="toolbar-inner">' +
            '<div class="left">' +
            '<a  class="link icon-only"><i class="icon icon-back"></i></a>' +
            '</div>' +
            '<div class="center"></div>' +
            '<div class="right">' +
            '<a  class="link icon-only"><i class="icon icon-forward"></i></a>' +
            '</div>' +
            '</div>' +
            '</div>';
        },
        on: {
          init: function (c) {
            $('.calendar-custom-toolbar .center').text(monthNames[c.currentMonth] + ', ' + c.currentYear);
            $('.calendar-custom-toolbar .left .link').on('click', function () {
              calendarInline.prevMonth();
            });
            $('.calendar-custom-toolbar .right .link').on('click', function () {
              calendarInline.nextMonth();
            });
          },
          monthYearChangeStart: function (c) {
            $('.calendar-custom-toolbar .center').text(monthNames[c.currentMonth] + ', ' + c.currentYear);
          }
        }
      });
    });
    $on('pageBeforeRemove', () => {
      calendarDefault.destroy();
      calendarDateFormat.destroy();
      calendarDateTime.destroy();
      calendarMultiple.destroy();
      calendarRange.destroy();
      calendarModal.destroy();
      calendarInline.destroy();
    });

    return $render;
  };
</script>