DevExtreme v24.1 is now available.

Explore our newest features/capabilities and share your thoughts with us.

Your search did not match any results.


This demo shows how to use additional properties to customize your Calendar. You can toggle the checkboxes on the right to change the Calendar in real time.

DevExtreme Accessibility Compliance
DevExtreme component libraries meet a variety of WCAG and Section 508 compliance standards. To assess this demo’s accessibility level, click the Run AXE® Validation button to launch the AXE® web accessibility evaluation tool.
All trademarks or registered trademarks are property of their respective owners. AXE® Terms of Use
The overall accessibility level of your application depends on the Calendar features used.
Backend API
<template> <div id="calendar-demo"> <div class="calendar-container"> <DxCalendar v-model:value="currentValue" v-model:zoom-level="zoomLevel" :first-day-of-week="firstDay" :show-week-numbers="showWeekNumbers" :week-number-rule="weekNumberRule" :disabled="disabled" :cell-template="cellTemplate" > <template #custom="{ data: cell }"> <span :class="getCellCssClass(cell)"> {{ cell.text }} </span> </template> </DxCalendar> </div> <div class="options"> <div class="caption">Options</div> <div class="option"> <span>Zoom level</span> <DxSelectBox v-model:value="zoomLevel" :input-attr="{ 'aria-label': 'Zoom Level' }" :data-source="zoomLevels" /> </div> <div class="option"> <span>Selected date</span> <DxDateBox v-model:value="currentValue" :input-attr="{ 'aria-label': 'Date' }" /> </div> <div class="option"> <DxCheckBox :value="false" text="Use custom cell template" @value-changed="useCellTemplate" /> </div> <div class="option"> <DxCheckBox v-model:value="disabled" text="Disable the calendar" /> </div> <div class="caption option"> <span>Week numeration</span> </div> <div class="option"> <DxCheckBox v-model:value="showWeekNumbers" text="Show week numbers" /> </div> <div class="option"> <span>First day of week</span> <DxSelectBox v-model:value="firstDay" :data-source="weekDays" :input-attr="{ 'aria-label': 'First Day of Week' }" value-expr="id" display-expr="text" /> </div> <div class="option"> <span>Week number rule</span> <DxSelectBox v-model:value="weekNumberRule" :input-attr="{ 'aria-label': 'Week Number Rule' }" :data-source="weekNumberRules" /> </div> </div> </div> </template> <script setup lang="ts"> import { ref } from 'vue'; import DxCheckBox from 'devextreme-vue/check-box'; import DxSelectBox from 'devextreme-vue/select-box'; import DxDateBox from 'devextreme-vue/date-box'; import DxCalendar from 'devextreme-vue/calendar'; const zoomLevels = ['month', 'year', 'decade', 'century']; const zoomLevel = ref('month'); const currentValue = ref(new Date()); const cellTemplate = ref('cell'); const disabled = ref(false); const showWeekNumbers = ref(false); const firstDay = ref(0); const weekNumberRule = ref('auto'); const weekDays = [ { id: 0, text: 'Sunday' }, { id: 1, text: 'Monday' }, { id: 2, text: 'Tuesday' }, { id: 3, text: 'Wednesday' }, { id: 4, text: 'Thursday' }, { id: 5, text: 'Friday' }, { id: 6, text: 'Saturday' }, ]; const weekNumberRules = ['auto', 'firstDay', 'firstFourDays', 'fullWeek']; function isWeekend(date) { const day = date.getDay(); return day === 0 || day === 6; } function useCellTemplate({ value }) { cellTemplate.value = value ? 'custom' : 'cell'; } function getCellCssClass({ date, view }) { let cssClass = ''; const holidays = [[1, 0], [4, 6], [25, 11]]; if (view === 'month') { if (!date) { cssClass = 'week-number'; } else { if (isWeekend(date)) { cssClass = 'weekend'; } holidays.forEach((item) => { if (date.getDate() === item[0] && date.getMonth() === item[1]) { cssClass = 'holiday'; } }); } } return cssClass; } </script> <style scoped> #calendar-demo { display: flex; } .calendar-container { display: flex; flex-direction: column; flex-grow: 1; align-items: center; justify-content: center; } .dx-calendar-cell:not(.dx-calendar-other-month) .weekend, .dx-calendar-cell:not(.dx-calendar-other-month) .holiday { text-shadow: none; font-weight: bold; } .dx-calendar-cell:not(.dx-calendar-other-month) .weekend { color: #3030ff; } .dx-state-disabled.dx-calendar .dx-calendar-cell:not(.dx-calendar-other-month) .weekend { color: #8080ff; } .dx-calendar-cell:not(.dx-calendar-other-month) .holiday { color: #ff3030; } .dx-state-disabled.dx-calendar .dx-calendar-cell:not(.dx-calendar-other-month) .holiday { color: #ff8080; } .dx-calendar-week-number-cell .week-number { font-style: italic; } .caption { font-weight: 500; font-size: 18px; } .options { padding: 20px; background-color: rgba(191, 191, 191, 0.15); } .option { margin-top: 10px; } </style>
window.exports = window.exports || {}; window.config = { transpiler: 'plugin-babel', meta: { '*.vue': { loader: 'vue-loader', }, '*.ts': { loader: 'demo-ts-loader', }, '*.svg': { loader: 'svg-loader', }, 'devextreme/time_zone_utils.js': { 'esModule': true, }, 'devextreme/localization.js': { 'esModule': true, }, 'devextreme/viz/palette.js': { 'esModule': true, }, }, paths: { 'root:': '../../../../', 'npm:': '', }, map: { 'vue': 'npm:vue@3.2.47/dist/vue.esm-browser.js', 'vue-loader': 'npm:dx-systemjs-vue-browser@1.1.1/index.js', 'demo-ts-loader': 'root:utils/demo-ts-loader.js', 'svg-loader': 'root:utils/svg-loader.js', 'mitt': 'npm:mitt/dist/mitt.umd.js', 'rrule': 'npm:rrule@2.6.4/dist/es5/rrule.js', 'luxon': 'npm:luxon@1.28.1/build/global/luxon.min.js', 'es6-object-assign': 'npm:es6-object-assign@1.1.0', 'devextreme': 'npm:devextreme@24.1.3/cjs', 'devextreme-vue': 'npm:devextreme-vue@24.1.3/cjs', 'jszip': 'npm:jszip@3.10.1/dist/jszip.min.js', 'devextreme-quill': 'npm:devextreme-quill@1.7.1/dist/dx-quill.min.js', 'devexpress-diagram': 'npm:devexpress-diagram@2.2.8/dist/dx-diagram.js', 'devexpress-gantt': 'npm:devexpress-gantt@4.1.56/dist/dx-gantt.js', '@devextreme/runtime': 'npm:@devextreme/runtime@3.0.13', 'inferno': 'npm:inferno@7.4.11/dist/inferno.min.js', 'inferno-compat': 'npm:inferno-compat/dist/inferno-compat.min.js', 'inferno-create-element': 'npm:inferno-create-element@7.4.11/dist/inferno-create-element.min.js', 'inferno-dom': 'npm:inferno-dom/dist/inferno-dom.min.js', 'inferno-hydrate': 'npm:inferno-hydrate@7.4.11/dist/inferno-hydrate.min.js', 'inferno-clone-vnode': 'npm:inferno-clone-vnode/dist/inferno-clone-vnode.min.js', 'inferno-create-class': 'npm:inferno-create-class/dist/inferno-create-class.min.js', 'inferno-extras': 'npm:inferno-extras/dist/inferno-extras.min.js', 'plugin-babel': 'npm:systemjs-plugin-babel@0.0.25/plugin-babel.js', 'systemjs-babel-build': 'npm:systemjs-plugin-babel@0.0.25/systemjs-babel-browser.js', // Prettier 'prettier/standalone': 'npm:prettier@2.8.8/standalone.js', 'prettier/parser-html': 'npm:prettier@2.8.8/parser-html.js', }, packages: { 'devextreme-vue': { main: 'index.js', }, 'devextreme': { defaultExtension: 'js', }, 'devextreme/events/utils': { main: 'index', }, 'devextreme/events': { main: 'index', }, 'es6-object-assign': { main: './index.js', defaultExtension: 'js', }, }, packageConfigPaths: [ 'npm:@devextreme/*/package.json', 'npm:@devextreme/runtime@3.0.13/inferno/package.json', ], babelOptions: { sourceMaps: false, stage0: true, }, }; System.config(window.config);
import { createApp } from 'vue'; import App from './App.vue'; createApp(App).mount('#app');
<!DOCTYPE html> <html lang="en"> <head> <title>DevExtreme Demo</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" /> <link rel="stylesheet" type="text/css" href="" /> <link rel="stylesheet" type="text/css" href="" /> <script type="module"> import * as vueCompilerSFC from ""; window.vueCompilerSFC = vueCompilerSFC; </script> <script src=""></script> <script src=""></script> <script src=""></script> <script type="text/javascript" src="config.js"></script> <script type="text/javascript"> System.import("./index.ts"); </script> </head> <body class="dx-viewport"> <div class="demo-container"> <div id="app"> </div> </div> </body> </html>

When you add a Calendar to an application, you need to specify its value in one of the following formats:

  • Date
    Specifies the date directly.

  • Number
    Specifies the date with a timestamp (total milliseconds since 1970/01/01).

  • String
    Specifies the date with a string value. The UI component supports the following formats of a date string:

    • "yyyy-MM-dd" (for example, "2017-03-06")
    • "yyyy-MM-ddTHH:mm:ss" (for example, "2017-03-27T16:54:48")
    • "yyyy-MM-ddTHH:mm:ssZ" (for example, "2017-03-27T13:55:41Z")
    • "yyyy-MM-ddTHH:mm:ssx" (for example, "2017-03-27T16:54:10+03")
  • Array of the formats mentioned before
    Available only for 'multiple' and 'range' selection modes. The array includes all selected dates.

Specify First Day of Week and Display Week Numbers

To specify the first day of the week, assign its index (0 - for Sunday, 1 - for Monday, and so on) to the firstDayOfWeek property. You can also display a column with week numbers. For this, enable the showWeekNumbers property.

The start of the first week of the year depends on the locale. If you want to apply a specific rule, use the weekNumberRule property.

Handle Value Change

Set the onValueChanged property to handle the value change. In this demo, the DateBox and the Calendar both use this property to pass values between each other, and you can use one of these components to change the date.

Customize Cell Appearance

Use the cellTemplate property to customize cell appearance. In this demo, the following customizations are applied when you toggle the "Use custom cell template" checkbox:

  • All the weekends on the Calendar become blue.

  • All the holidays become red.

  • If a column with week numbers is shown, week numbers are italicized.

You can set your own function that changes the class of the span element that contains cell text.

Other Customizations

Set the disabled property to disable the Calendar.

To specify the initial calendar view (month, year, decade, or century), set the zoomLevel property.