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

You can enable or disable the Calendar for Angular. By default, the Calendar is enabled. To disable the Calendar, 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

To define the currently 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.

The Calendar always displays a focused date. By default, the focused date is today's date.

@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

To define the selected date, use the value property. If it is not set, the Calendar displays only the focused date.

@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 you to control the displayed date range. 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

The Calendar provides an option for you to control the visibility of the 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 { }

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 a kendoCalendarCellTemplate directive inside the <kendo-calendar> selector. 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 } from '@angular/core';

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 kendoCalendarCellTemplate let-date>
            <span [ngClass]="isMeeting(date)">{{date.getDate()}}</span>
        </ng-template>
      </kendo-calendar>
  `,
  encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    public isMeeting(date: Date) {
        return /10|15|20/.test(date.getDate()) ? 'meeting' : '';
    }
}

Forms Support

You can use the Calendar in template-driven or reactive forms. 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;
    }
}

Using with JSON

In most cases, the data received from the server is serialized as JSON. The date object in the JSON will be
a ISO8601 formatted date string. For more details check the JSON.stringify
documentation.

The Calendar component, on the other hand, works only with JavaScript Date instances.
To bind the component to dates serialized as strings, you need to handle the parsing process.

Generally, you have to:

  1. Convert the JSON date strings into valid JavaScript Date objects. You can use IntlService or any suitable Date parser for that task.
  2. Define the value input property of the component. Note that the same approach applies to Reactive and Template-Driven forms.
  3. Wire the component valueChange output property to get the selected Date value.

The following example demonstrates how to set the component's value.

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

   //simple method for 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 events of the Calendar component.

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