DevExtreme v23.2 is now available.

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

Your search did not match any results.


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

  • Date objects

  • The number of milliseconds since 00:00:00 on January 1, 1970

  • Strings that match the following patterns:

    • 'yyyy-MM-dd'
    • 'yyyy-MM-ddTHH:mm:ss'
    • 'yyyy-MM-ddTHH:mm:ssZ'
    • 'yyyy-MM-ddTHH:mm:ssx'

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.

Disable Dates

Use the min and max properties to specify the range of available dates. In this demo, these properties limit the range to three days before and after the current date. Enable the "Set minimum date" and "Set maximum date" checkboxes to apply the properties.

If you need to disable specific dates, use the disabledDates property. Toggle the "Disable weekends" checkbox to see how this setting affects the component's behavior. You can specify either an array of predefined dates or a function that determines whether a date is available.

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.

Handle Value Change

To handle value changes, use two-way binding to bind the value properties of different components. In this demo, you can use the DateBox or Calendar component to change the date because their value properties are bound.

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.

Backend API
<div id="calendar-demo"> <div class="calendar-container"> <dx-calendar #calendar [(value)]="currentValue" [showWeekNumbers]="false" [disabled]="false" [firstDayOfWeek]="0" [zoomLevel]="zoomLevels[0]" [cellTemplate]="cellTemplate" weekNumberRule="auto" > <span *dxTemplate="let cell of 'custom'" [ngClass]="getCellCssClass(cell)" > {{ cell.text }} </span> </dx-calendar> </div> <div class="options"> <div class="caption">Options</div> <div class="option"> <span>Zoom level</span> <dx-select-box [dataSource]="zoomLevels" [(value)]="calendar.zoomLevel" [inputAttr]="{ 'aria-label': 'Zoom Level' }" > </dx-select-box> </div> <div class="option"> <span>Selected date</span> <dx-date-box id="selected-date" [(value)]="currentValue" [inputAttr]="{ 'aria-label': 'Date' }" > </dx-date-box> </div> <div class="option"> <dx-check-box text="Use custom cell template" [value]="false" (onValueChanged)="useCellTemplate($event)" > </dx-check-box> </div> <div class="option"> <dx-check-box [(value)]="calendar.disabled" text="Disable the calendar"> </dx-check-box> </div> <div class="caption option"> <span>Week numeration</span> </div> <div class="option"> <dx-check-box text="Show week numbers" [(value)]="calendar.showWeekNumbers" > </dx-check-box> </div> <div class="option"> <span>First day of week</span> <dx-select-box [dataSource]="weekDays" [inputAttr]="{ 'aria-label': 'First Day of Week' }" [(value)]="calendar.firstDayOfWeek" valueExpr="id" displayExpr="text" ></dx-select-box> </div> <div class="option"> <span>Week number rule</span> <dx-select-box [dataSource]="weekNumberRules" [inputAttr]="{ 'aria-label': 'Week Number Rule' }" [(value)]="calendar.weekNumberRule" ></dx-select-box> </div> </div> </div>
import { Component, NgModule, enableProdMode } from '@angular/core'; import { BrowserModule, BrowserTransferStateModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { DxCheckBoxModule, DxDateBoxModule, DxSelectBoxModule, DxTemplateModule, } from 'devextreme-angular'; import { DxCalendarModule, DxCalendarTypes } from 'devextreme-angular/ui/calendar'; if (!/localhost/.test( { enableProdMode(); } declare var __moduleName: string; @Component({ selector: 'demo-app', templateUrl: 'app.component.html', styleUrls: ['app.component.css'], moduleId: __moduleName, }) export class AppComponent { now = new Date(); currentValue = new Date(); zoomLevels: DxCalendarTypes.CalendarZoomLevel[] = [ 'month', 'year', 'decade', 'century', ]; weekDays: { id: number; text: string }[] = [ { 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' }, ]; weekNumberRules: DxCalendarTypes.WeekNumberRule[] = [ 'auto', 'firstDay', 'firstFourDays', 'fullWeek', ]; cellTemplate = 'cell'; holidays = [[1, 0], [4, 6], [25, 11]]; isWeekend(date: Date) { const day = date.getDay(); return day === 0 || day === 6; } useCellTemplate({ value }) { this.cellTemplate = value ? 'custom' : 'cell'; } getCellCssClass({ date, view }) { let cssClass = ''; if (view === 'month') { if (!date) { cssClass = 'week-number'; } else { if (this.isWeekend(date)) { cssClass = 'weekend'; } this.holidays.forEach((item) => { if (date.getDate() === item[0] && date.getMonth() === item[1]) { cssClass = 'holiday'; return false; } }); } } return cssClass; } } @NgModule({ imports: [ BrowserModule, BrowserTransferStateModule, DxCalendarModule, DxCheckBoxModule, DxDateBoxModule, DxSelectBoxModule, DxTemplateModule, ], declarations: [AppComponent], bootstrap: [AppComponent], }) export class AppModule { } platformBrowserDynamic().bootstrapModule(AppModule);
::ng-deep #calendar-demo { display: flex; } ::ng-deep .calendar-container { display: flex; flex-direction: column; flex-grow: 1; align-items: center; justify-content: center; } ::ng-deep .dx-calendar-cell:not(.dx-calendar-other-month) .weekend, ::ng-deep .dx-calendar-cell:not(.dx-calendar-other-month) .holiday { text-shadow: none; font-weight: bold; } ::ng-deep .dx-calendar-cell:not(.dx-calendar-other-month) .weekend { color: #3030ff; } ::ng-deep .dx-state-disabled.dx-calendar .dx-calendar-cell:not(.dx-calendar-other-month) .weekend { color: #8080ff; } ::ng-deep .dx-calendar-cell:not(.dx-calendar-other-month) .holiday { color: #ff3030; } ::ng-deep .dx-state-disabled.dx-calendar .dx-calendar-cell:not(.dx-calendar-other-month) .holiday { color: #ff8080; } ::ng-deep .dx-calendar-week-number-cell .week-number { font-style: italic; } ::ng-deep .caption { font-weight: 500; font-size: 18px; } ::ng-deep .options { padding: 20px; background-color: rgba(191, 191, 191, 0.15); } ::ng-deep .option { margin-top: 10px; }
// In real applications, you should not transpile code in the browser. // You can see how to create your own application with Angular and DevExtreme here: // window.exports = window.exports || {}; window.config = { transpiler: 'ts', typescriptOptions: { module: 'system', emitDecoratorMetadata: true, experimentalDecorators: true, }, meta: { 'typescript': { 'exports': 'ts', }, 'devextreme/time_zone_utils.js': { 'esModule': true, }, 'devextreme/localization.js': { 'esModule': true, }, 'devextreme/viz/palette.js': { 'esModule': true, }, }, paths: { 'npm:': '', }, map: { 'ts': 'npm:plugin-typescript@4.2.4/lib/plugin.js', 'typescript': 'npm:typescript@4.2.4/lib/typescript.js', '@angular/core': 'npm:@angular/core@12.2.17', '@angular/platform-browser': 'npm:@angular/platform-browser@12.2.17', '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic@12.2.17', '@angular/forms': 'npm:@angular/forms@12.2.17', '@angular/common': 'npm:@angular/common@12.2.17', '@angular/compiler': 'npm:@angular/compiler@12.2.17', 'tslib': 'npm:tslib@2.6.2/tslib.js', 'rxjs': 'npm:rxjs@7.5.3/dist/bundles/rxjs.umd.js', 'rxjs/operators': 'npm:rxjs@7.5.3/dist/cjs/operators/index.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@23.2.6/cjs', 'devextreme/bundles/dx.all': 'npm:devextreme@23.2.6/bundles/dx.all.js', 'jszip': 'npm:jszip@3.10.1/dist/jszip.min.js', 'devextreme-quill': 'npm:devextreme-quill@1.6.4/dist/dx-quill.min.js', 'devexpress-diagram': 'npm:devexpress-diagram@2.2.5', 'devexpress-gantt': 'npm:devexpress-gantt@4.1.54', 'devextreme-angular': 'npm:devextreme-angular@23.2.6', '@devextreme/runtime': 'npm:@devextreme/runtime@3.0.12', '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', // Prettier 'prettier/standalone': 'npm:prettier@2.8.4/standalone.js', 'prettier/parser-html': 'npm:prettier@2.8.4/parser-html.js', }, packages: { 'app': { main: './app.component.ts', defaultExtension: 'ts', }, 'devextreme': { defaultExtension: 'js', }, 'devextreme/events/utils': { main: 'index', }, 'devextreme/events': { main: 'index', }, 'es6-object-assign': { main: './index.js', defaultExtension: 'js', }, 'rxjs': { defaultExtension: 'js', }, 'rxjs/operators': { defaultExtension: 'js', }, }, packageConfigPaths: [ 'npm:@devextreme/*/package.json', 'npm:@devextreme/runtime@3.0.12/inferno/package.json', 'npm:@angular/*/package.json', 'npm:@angular/common@12.2.17/*/package.json', 'npm:rxjs@7.5.3/package.json', 'npm:rxjs@7.5.3/operators/package.json', 'npm:devextreme-angular@23.2.6/*/package.json', 'npm:devextreme-angular@23.2.6/ui/*/package.json', 'npm:devextreme-angular@23.2.6/package.json', 'npm:devexpress-diagram@2.2.5/package.json', 'npm:devexpress-gantt@4.1.54/package.json', ], }; System.config(window.config);
<!DOCTYPE html> <html xmlns=""> <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=1.0" /> <link rel="stylesheet" type="text/css" href="" /> <script src=""></script> <script src=""></script> <script src=""></script> <script src=""></script> <script src="config.js"></script> <script> System.import("app").catch(console.error.bind(console)); </script> </head> <body class="dx-viewport"> <div class="demo-container"> <demo-app>Loading...</demo-app> </div> </body> </html>