All Components

Calendar Overview

The Calendar is a form component that represents a graphical Gregorian calendar.

It supports the selection of and navigation between dates as well as data templates and ranges for scheduling appointments.

Basic Usage

The following example demonstrates the Calendar in action.

@Component({
selector: 'my-app',
styles: [ '.k-calendar { margin: 0 auto; }' ],
template: `
<kendo-calendar></kendo-calendar>
`
})
class AppComponent {}

Features

The Calendar delivers the following features:

Disabled State

By default, the Calendar is enabled. To disable the component, set its disabled property to true.

@Component({
selector: 'my-app',
template: `
<kendo-calendar [disabled]="true"></kendo-calendar>
`
})
class AppComponent { }

Dates

You can handle the dates of the Calendar by:

Set the Focused Date

The Calendar always displays a focused date and, by default, the focused date is today's date. To change the focused date, use the focusedDate property by setting it to a specific Date value. The Date value has to be a valid JavaScript Date object.

@Component({
selector: 'my-app',
template: `
<kendo-calendar [focusedDate]="focusedDate"></kendo-calendar>
`
})
class AppComponent {
    public focusedDate: Date = new Date(2010, 10, 10);
}

Set the Selected Date

By default, the selected date is not set and the Calendar displays only the focused date. To define the selected date, use the value property.

@Component({
selector: 'my-app',
template: `
<kendo-calendar [value]="value"></kendo-calendar>
`
})
class AppComponent {
    public value: Date = new Date(2010, 10, 10);
}

Date Ranges

The Calendar provides options for displaying date ranges. To define the start date of the range, use the min property. To define the end date of the range, use the max property.

The min date value has to be lower than the max date value.

@Component({
selector: 'my-app',
template: `
<kendo-calendar [min]="min" [max]="max"></kendo-calendar>
`
})
class AppComponent {
    public min: Date = new Date(2010, 10, 10);
    public max: Date = new Date(2010, 10, 20);
}

Navigation Control

By default, the Calendar renders a left-hand side-navigation bar. To hide the navigation bar, set the navigation property to false.

@Component({
  selector: 'my-app',
  template: `
      <kendo-calendar [navigation]="false"></kendo-calendar>
  `
})
class AppComponent { }

Active View and Navigation Depth

To define the first view that the Calendar initially renders, use the activeView property.

To control the navigation depth of the Calendar view, use the `topView and bottomView properties.

The CalendarView type defines the following possible view options:

  • month—Shows the days of the month.
  • year—Shows the months of the year.
  • decade&Mdash;Shows the years of the decade.
  • century—Shows the decades of the century.
@Component({
  selector: 'my-app',
  template: `
    <div class="example-config">
        Selected date is {{ value | kendoDate:'MMMM yyyy' }}
    </div>
      <kendo-calendar
          [activeView]="'decade'"
          [bottomView]="'year'"
          [topView]="'decade'"
          [(value)]="value"
      ></kendo-calendar>
  `
})
class AppComponent {
    public value: Date;
}

Templates

The Calendar enables you to customize the content of each cell by using cell templates. To define a cell template, nest a <ng-template> tag with one of the available cell template directives inside the <kendo-calendar> selector.

The available cell template directives are:

The template context is set to the current Calendar component. To get a reference to the current date, use the let-date directive.

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
      <style>
        .meeting {
          position: relative;
          color: #00a1e8;
        }

        .meeting:after {
            position: absolute;
            bottom: -2px;
            left: 50%;
            width: 3px;
            height: 3px;
            margin-left: -1.5px;
            content: '';
            border-radius: 50%;
            background-color: #00a1e8;
        }

        .k-state-selected .meeting {
          color: #fff;
        }

        .k-state-selected .meeting:after {
          background-color: #fff;
        }
      </style>
      <kendo-calendar>
        <ng-template kendoCalendarMonthCellTemplate let-date>
            <span [ngClass]="isMeeting(date)">{{date.getDate()}}</span>
        </ng-template>
        <ng-template kendoCalendarYearCellTemplate let-context="cellContext">
            <span [ngClass]="isYearMeeting(context.value)">{{context.formattedValue}}</span>
        </ng-template>
        <ng-template kendoCalendarDecadeCellTemplate let-context="cellContext">
            <span [ngClass]="isDecadeMeeting(context.value)">{{context.formattedValue}}</span>
        </ng-template>
        <ng-template kendoCalendarCenturyCellTemplate let-context="cellContext">
            <span [ngClass]="isCenturyMeeting(context.value)">{{context.formattedValue}}</span>
        </ng-template>
      </kendo-calendar>
  `,
  encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    public isMeeting(date: Date) {
        return /10|15|20/.test(date.getDate()) ? 'meeting' : '';
    }
    public isYearMeeting(date: Date) {
        return date.getMonth() % 3 ? 'meeting' : '';
    }
    public isDecadeMeeting(date: Date) {
        return date.getDate() % 2 ? 'meeting' : '';
    }
    public isCenturyMeeting(date: Date) {
        return date.getDate() % 20 ? 'meeting' : '';
    }
}

Forms Support

You can use the Calendar in:

The component accepts Date values and updates the model each time a selection is changed.

Template-Driven Forms

The template-driven forms enable you to bind the Calendar to the model by using the ngModel directive.

The following example demonstrates how to accomplish a two-way binding by using the ngModel directive.

@Component({
  selector: 'my-app',
  styles: ['.k-invalid { color: red; padding: 5px 0; }'],
  template: `
    <div class="example-config">
        Form value: {{ form.value | json }}
    </div>

    <form #form="ngForm">
      <kendo-calendar name="date" [(ngModel)]="model.date" #date="ngModel" required></kendo-calendar>
      <div [hidden]="date.valid" class="k-invalid">Date required. Please select one.</div>
    </form>
  `
})
class AppComponent {
    public model: any = { date: undefined };
}

Reactive Forms

The FormGroup decorator provides a way to render reactive forms. For more details, refer to the Angular documentation.

The following example demonstrates how to use the Calendar in a reactive form.

import {
    FormsModule,
    ReactiveFormsModule,
    FormGroup,
    FormControl,
    Validators
} from '@angular/forms';

@Component({
  selector: 'my-app',
  styles: ['.k-invalid { color: red; padding: 5px 0; }'],
  template: `
    <div class="example-config">
        Form value: {{ form.value | json }}
    </div>

    <form [formGroup]="form">
      <kendo-calendar formControlName="date" required></kendo-calendar>
      <div [hidden]="isDateValid()" class="k-invalid">Date required. Please select one.</div>
    </form>
  `
})
class AppComponent {
    public form: FormGroup;

    constructor() {
        this.form = new FormGroup({
            date: new FormControl(null, Validators.required)
        });
    }

    public isDateValid(): boolean {
        return this.form.controls.date.valid;
    }
}

Integration with JSON

Generally, the data which is received from the server is serialized in a JSON format. The date object in JSON is an ISO8601-formatted date string. For more details, refer to the documentation on the JSON.stringify method. On the other hand, the Calendar works only with JavaScript Date instances.

To bind the Calendar to dates which are serialized as strings, handle the parsing process:

  1. Convert the JSON date strings into valid JavaScript Date objects by using the IntlService or any other suitable Date parser.
  2. Define the value input property of the component—the same approach applies to reactive and template-driven forms.
  3. Wire the valueChange output property of the Calendar to get the selected Date value.

The following example demonstrates how to set the value of the Calendar.

import { Component } from '@angular/core';
import { IntlService } from '@progress/kendo-angular-intl';

export interface JsonModel {
   birthDate: string;
}

export interface User {
   birthDate: Date;
}

@Component({
    selector: 'my-app',
    template: `
      <form #form="ngForm">
           <div class="example-config">
               <p>Form model: {{ user | json }}</p>
               <p>Model: {{ output }}</p>
           </div>
           <label>
               Select Birthdate:
               <kendo-calendar
                   #birthdate
                   name="birthDate"
                   [(ngModel)]="user.birthDate"
                   (valueChange)="handleChange($event)"
               ></kendo-calendar>
           </label>
       </form>
    `
})
export class AppComponent implements OnInit {
   public user: User;
   public model: JsonModel = JSON.parse('{ "birthDate": "2017-06-30" }'); //parse JSON data
   public output: string = JSON.stringify(this.model); //stringify model for presentational purposes

   constructor(private intl: IntlService) {}

   public ngOnInit() {
       this.user = this.parse(this.model);
   }

   public handleChange(value: Date) {
     this.model.birthDate = this.intl.formatDate(value, 'yyyy-MM-dd'); //update the JSON birthDate string date
     this.output = JSON.stringify(this.model);
   }

   // A simple method for the string-to-date conversion
   private parse(json: { [x]: string | number }) {
     Object.keys(json).map(key => {
       const date = this.intl.parseDate(json[key]);
       if (date !== null) { json[key] = date; }
     });

     return json;
   }
}
import { NgModule }      from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { IntlModule } from '@progress/kendo-angular-intl';
import { HttpModule } from '@angular/http';
import { DateInputsModule } from '@progress/kendo-angular-dateinputs';

import 'hammerjs';

import { AppComponent }   from './app.component';

@NgModule({
  imports:      [ FormsModule, BrowserModule, BrowserAnimationsModule, IntlModule, HttpModule, DateInputsModule ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})

export class AppModule { }
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Events

The following example demonstrates basic Calendar events.

import { Component, ViewEncapsulation } from '@angular/core';
import { IntlService } from '@progress/kendo-angular-intl';

@Component({
  encapsulation: ViewEncapsulation.None,
  selector: 'my-app',
  template: `
    <div class="container-fluid">
        <div class="row">
            <kendo-calendar
                (blur)="onBlur()"
                (focus)="onFocus()"
                (valueChange)="onChange($event)"
            >
            </kendo-calendar>
            <event-log title="Event log" [events]="events">
            </event-log>
        </div>
    </div>
  `
})
export class AppComponent {
  public events: string[] = [];

  constructor(private intl: IntlService) {}

  public onBlur(): void {
    this.log('blur');
  }

  public onFocus(): void {
    this.log('focus');
  }

  public onChange(value: Date): void {
    this.log('change', value);
  }

  private log(event: string, value?: Date): void {
    this.events = [`${event}${this.formatValue(value)}`].concat(this.events);
  }

  private formatValue(value?: Date): string {
    return value ? ` - ${this.intl.formatDate(value, 'd')}` : '';
  }
}
import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { CalendarModule } from '@progress/kendo-angular-dateinputs';

import { AppComponent }   from './app.component';
import { EventLogComponent }   from './event-log.component';

@NgModule({
  bootstrap:    [ AppComponent ],
  declarations: [ AppComponent, EventLogComponent ],
  imports:      [ BrowserModule, BrowserAnimationsModule, CalendarModule ]
})

export class AppModule { }
import { Component, Input } from '@angular/core';

@Component({
  selector: 'event-log',
  template: `
    <div class="example-config">
      <h5>{{ title }}</h5>
      <ul class="event-log">
        <li *ngFor="let event of events">{{ event }}</li>
      </ul>
    </div>
  `
})
export class EventLogComponent {
  @Input() title: string;
  @Input() events: string[];
}
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);
In this article