日历 / 日期选择器

日期选择器是一个触摸优化的组件,提供了一种方便处理日期的方式。

日期选择器可以用作内联组件或作为覆盖层。覆盖层的日期选择器在平板电脑(iPad)上会自动转换为弹出层。

日期选择器应用方法

让我们看看与日期选择器相关的应用方法:

app.calendar.create(参数)- 创建日期选择器实例

  • 参数 - 对象. 带有日期选择器参数的对象

方法返回创建的日期选择器实例

app.calendar.destroy(el)- 销毁日期选择器实例

  • el - HTMLElement字符串(使用 CSS 选择器) 或对象. 要销毁的日期选择器元素或日期选择器实例。

app.calendar.get(el)- 通过HTML元素获取日期选择器实例

  • el - HTMLElement字符串(使用CSS选择器)。日期选择器元素。

方法返回日期选择器实例

app.calendar.close(el)- 关闭日期选择器

  • el - HTMLElement字符串(使用CSS选择器)。要关闭的日期选择器元素。

方法返回日期选择器实例

例如:

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

日历参数

让我们看看所有可用日期选择器参数的列表:

参数类型默认描述
locale字符串

日期选择器区域设置。应该是浏览器接受的正确区域设置。Intl.DateTimeFormat. 如果未指定(默认情况下),它将使用浏览器区域设置。

例如en-US, ru, en, en-US-u-ca-buddhist,等等。

数组初始选中日期的数组。每个数组项代表一个选中日期
禁用日期范围额外禁用的日期。参数接受所谓的日期范围(详细内容见下文)
事件日期范围

带有事件的日期。将在日历日期上用额外的“点”标记。参数接受所谓的日期范围(详细内容见下文)。

如果您想表示某一天有多个不同的事件,可以通过多个不同颜色的点来表示。在这种情况下,您需要将日期范围作为数组传递,其中每个对象将具有datecolor属性,例如

[
  {
    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',
  },
]
范围类数组您想要为附加样式添加自定义CSS类的日期范围。接受的格式如下
formatValuefunction (values)用于格式化输入值的函数,应返回新的/格式化的字符串值。values是一个数组,其中每个项代表一个选中日期。可用于指定自定义格式dateFormat参数
monthNames数组auto全月名称的数组。如果auto则它将根据指定的locale(或浏览器区域设置)显示天名称
monthNamesShort数组auto短月名称的数组。如果auto则它将根据指定的locale(或浏览器区域设置)显示天名称
dayNames数组auto一周天名称的数组。如果auto则它将根据指定的locale(或浏览器区域设置)显示天名称
dayNamesShort数组auto一周天短名称的数组。如果auto则它将根据指定的locale(或浏览器区域设置)显示天名称
firstDay数字1一周的第一天。默认为1 - 星期一
weekendDays数组[0, 6]周末天索引数字的数组,默认为周六和周日
dateFormat字符串
对象
undefined

如果未定义,它将使用基于locale(或浏览器区域设置)的格式。

它可以接受Intl.DateTimeFormat.options.

例如{ month: 'long', day: 'numeric' }.

或者您可以传递带有特殊标记的字符串,可用的表达式:

  • yyyy- 4位年份
  • yy- 2位年份
  • mm- 2位月份数字,从01到12
  • m- 月份数字,从1到12
  • MM- 全月名称
  • M- 短月名称
  • dd- 2位天数,从01到31
  • d- 天数,从1到31
  • DD- 全周天名称
  • D- 短周天名称

当启用时,以下附加时间表达式可用:timePicker- 24小时格式2位小时(00 - 23)

  • HH- 24小时格式小时(0 - 23)
  • H - 24-hours format hours (0 - 23)
  • hh- 12小时格式2位小时(00 - 12)
  • h- 12小时格式小时(0 - 12)
  • :mm- 2位分钟(00 - 59)
  • :m- 分钟(0 - 59)
  • ss- 2位秒(00 - 59)
  • s- 秒(0 - 59)
  • A- 大写的后或前中午(PM或AM)
  • a- 小写的后或前中午(pm或am)
multiple布尔值false允许选择多个日期/值
rangePicker布尔值false启用范围选择器。与multiple
rangePickerMinDays数字1选择时需要的最小天数rangePicker启用
rangePickerMaxDays数字0启用时允许选择的最大天数rangePicker意味着没有最大值0'horizontal'
方向字符串'horizontal'月份布局方向,可以是'horizontal'或'vertical'
minDate日期null允许的最小日期
maxDate日期null允许的最大日期
touchMove布尔值true如果启用,则日期选择器月份在触摸移动时跟随手指滑动
animate布尔值true启用月份之间的过渡
closeOnSelect布尔值false启用并选择日期时日期选择器将关闭
weekHeader布尔值true启用带有短周天名称的周标题
monthSelector布尔值true在工具栏中启用月份选择器
monthPicker布尔值true启用月份选择器,当点击工具栏中的月份选择器时可以选择月份
yearSelector布尔值true在工具栏中启用年份选择器
yearPicker布尔值true启用年份选择器,当点击工具栏中的年份选择器时可以选择年份
yearPickerMin数字年份选择器的最小可用年份,默认为今天减去100年
yearPickerMax数字年份选择器的最大可用年份,默认为今天加上100年
timePicker布尔值false启用时间选择器。
timePickerFormat对象{hour: 'numeric', minute: 'numeric'}

时间选择器中显示的时间格式。它接受Intl.DateTimeFormat.options

AM/PM依赖于指定的locale,如果未指定,则依赖于浏览器区域设置

timePickerPlaceholder字符串选择时间时间选择器占位符中显示的文本。
容器/打开器特定参数
containerEl字符串
HTMLElement
带有CSS选择器或HTMLElement的字符串,用于放置生成的日期选择器HTML。仅用于内联日期选择器
openIn字符串自动可以是auto, popover(在弹出层中打开日期选择器),sheet(在表单模态中打开)或customModal(在自定义日期选择器模态覆盖层中打开)。在auto的情况下,在小屏幕上将在表单模态中打开,在大屏幕上将在弹出层中打开。
sheetPush布尔值false启用日期选择器表单在打开时推动视图/页面的后面
sheetSwipeToClose布尔值undefined启用通过滑动关闭日期选择器表单的能力。如果没有指定,它将继承应用的表单swipeToCloseparameter
inputEl字符串或 HTMLElement包含相关输入元素的 CSS 选择器或 HTMLElement。
scrollToInput布尔值true当日期选择器打开时滚动视口(page-content)到输入
inputReadOnly布尔值true在指定输入上设置“readonly”属性
cssClass字符串附加的CSS类名,用于设置在日期选择器元素上
closeByOutsideClick布尔值true启用后,点击颜色选择器或相关输入元素外部将关闭选择器
toolbar布尔值true启用日历工具栏
toolbarCloseText字符串完成完成/关闭工具栏按钮的文本
头部布尔值false启用日历头部
头部占位符字符串选择日期默认日历头部占位符文本
routableModals布尔值false将打开的日历添加到路由历史,这提供了通过路由历史返回关闭日历并设置当前路由为日历模态框的能力
url字符串date/将设置为当前路由的日历模态框URL
view对象routableModals启用时,要设置路由的位置。默认情况下为inputEl的父视图,如果找不到父视图,则为主视图
背景遮罩布尔值启用日历背景(暗色半透明层)。默认情况下,仅在日历在弹出框中打开时启用。
closeByBackdropClick布尔值true当启用时,点击背景将关闭日历
渲染函数
renderWeekHeader函数渲染星期头部的函数。必须返回星期头部HTML字符串
renderMonthsfunction(date)渲染月份包装器的函数。必须返回月份容器完整HTML字符串
renderMonthfunction(date, offset)渲染单个月份的函数。必须返回单个月份HTML字符串
renderMonthSelector函数渲染月份选择器的函数。必须返回月份选择器HTML字符串
renderYearSelector函数渲染年份选择器的函数。必须返回年份选择器HTML字符串
renderHeader函数渲染日历头部的函数。必须返回日历头部HTML字符串
renderToolbar函数用于渲染工具栏的函数。必须返回工具栏的HTML字符串
render函数渲染整个日历的函数。必须返回日历完整HTML字符串
事件
on对象

带有事件处理程序的对象。例如:

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

注意,所有以下参数都可以在calendar设置所有日历默认值的属性。例如:

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

日期范围

日历的一些参数 (禁用, 事件范围类) 接受所谓的日期范围。这是一种简单的方法来指定和涵盖所有可能的日期组合。

它可以是包含日期的数组,例如:

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

它可以是自定义函数,您需要返回truefalse

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;
        }
    },
    ...
});

或包含from属性

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)
    },
    ...
});

或仅包含from属性

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

或包含date派发动作

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

或包含混合日期和对象的数组:

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'
        },
    ],
    ...
});

范围类

范围类parameter接受包含日期范围和此范围类名的对象数组:

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示例中使用的变量)中拥有颜色选择器的初始化实例,其中包含有用的方法和属性:

属性
calendar.app链接到全局应用实例
calendar.containerEl日历包装容器HTML元素(当使用内联日历时)
calendar.$containerEl包含日历包装容器HTML元素的Dom7实例(当使用内联日历时)
calendar.el日历HTML元素
calendar.$el包含日历HTML元素的Dom7实例
calendar.inputEl日历输入HTML元素(传递到inputEl参数中)
calendar.$inputEl包含日历输入HTML元素的Dom7实例(传递到inputEl参数中)
calendar.value每个项目代表选定日期的数组
calendar.currentMonth日历视图当前月份。数字,从011
calendar.currentYear日历视图当前年份。数字,例如2020
calendar.openedtrue如果日历当前打开
calendar.inlinetrue当使用内联日历时
calendar.cols包含指定日历列的数组。每列也有自己的方法和属性(见下文)
calendar.url日历URL(传递到url参数中)
calendar.view日历视图(传递到view参数中)或找到的父视图
calendar.params包含初始化参数的对象
calendar.allowTouchMove将此标志设置为false以防止初始化后的触摸移动交互
方法
calendar.setValue(values)设置新的选定日期。values是一个数组,其中每个项目代表选定日期
calendar.getValue()返回当前日历值
calendar.addValue()将值添加到值数组。在启用多重选择的情况下很有用(使用multiple: true参数中)
calendar.update()重新渲染日历。在您动态添加/更改值并需要更新日历布局的情况下很有用
calendar.nextMonth(持续时间)日历过渡到指定的下一个月duration持续时间为毫秒
calendar.prevMonth(持续时间)日历过渡到指定的上一个月duration持续时间为毫秒
calendar.nextYear()日历过渡到下一年
calendar.prevYear()日历过渡到上一年
calendar.setYearMonth(year, month, 持续时间)日历过渡到指定的year, month持续时间为毫秒duration持续时间为毫秒
calendar.open()打开日历
calendar.close()关闭日历
calendar.destroy()销毁日历实例并删除所有事件
calendar.on(事件上触发, 处理程序)添加事件处理程序
calendar.once(事件上触发, 处理程序)添加在触发后将被移除的事件处理程序
calendar.off(事件上触发, 处理程序)移除事件处理程序
calendar.off(事件上触发)移除指定事件的所有处理程序
calendar.emit(事件上触发, ...args)在实例上触发事件

日期选择器事件

日历将在日历元素上触发以下DOM事件,并在应用和日历实例上触发事件:

DOM 事件

事件Target描述
calendar:open日历元素<div class="calendar">当日历开始其打开动画时将触发事件
calendar:opened日历元素<div class="calendar">当日历完成其打开动画后触发事件
calendar:close日历元素<div class="calendar">当日历开始其关闭动画时将触发事件
calendar:closed日历元素<div class="calendar">当日历完成其关闭动画后触发事件

应用和日期选择器实例事件

日历实例在自身实例和应用实例上触发事件。应用实例事件具有相同名称,前缀为calendar.

事件Target参数描述
dayClick日期选择器(calendar, dayEl, year, month, day)在点击日历日期元素后触发事件
calendarDayClickapp
change日期选择器(calendar, value)当日历值更改时触发事件
calendarChangeapp
monthAdd日期选择器(calendar, monthEl)当新的月份HTML布局已添加时触发事件。如果您需要后处理添加的HTML元素,则很有用
calendarMonthAddapp
monthYearChangeStart日期选择器(calendar, year, month)在过渡到下一个月开始时触发事件
calendarMonthYearChangeStartapp
monthYearChangeEnd日期选择器(calendar, year, month)在过渡到下一个月后触发事件
日期月份变更结束app
init日期选择器(日期选择器)当日期选择器初始化时将触发事件
日期选择器初始化app
open为前缀日期选择器(日期选择器)当日期选择器开始其打开动画时将触发事件。作为参数事件处理程序接收日期选择器实例
日期选择器打开app
opened日期选择器(日期选择器)当日期选择器完成其打开动画后将触发事件。作为参数事件处理程序接收日期选择器实例
日期选择器已打开app
close日期选择器(日期选择器)当日期选择器开始其关闭动画时将触发事件。作为参数事件处理程序接收日期选择器实例
日期选择器关闭app
closed日期选择器(日期选择器)当日期选择器完成其关闭动画后将触发事件。作为参数事件处理程序接收日期选择器实例
日期选择器已关闭app
beforeDestroy日期选择器(日期选择器)在日期选择器实例将被销毁之前将触发事件。作为参数事件处理程序接收日期选择器实例
日期选择器销毁前app

CSS 变量

以下是相关CSS 变量(CSS 自定义属性) 的列表。

注意,注释掉的变量默认未指定,其值在这种情况下是它们回退到的值。

: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);
}

示例

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>