Angular Calendar Component Overview
Angular Calendar is a UI component used for displaying dates and days in an app. Supporting different features, it enables users to easily manage calendar functionalities, drag and create events in a calendar, navigate to a preferred date in it, and show events in an Angular calendar month view, week view, or day view in a single click.
The Ignite UI for Angular Calendar component, developed as a native Angular component, provides an easy and intuitive ways to display date information, enable dates or apply Angular calendar disable dates mode. Users can choose from three different selection modes - single selection, multi selection or range selection.
Angular Calendar Example
We created the following Angular Calendar example using the Ignite UI for Angular Calendar package. It quickly shows how a basic calendar looks and feels like, how users can choose and highlight a single date, and how to move back and forth to a specific date.
Getting Started with Ignite UI for Angular Calendar
To get started with the Ignite UI for Angular Calendar component, first you need to install Ignite UI for Angular. In an existing Angular application, type the following command:
ng add igniteui-angular
For a complete introduction to the Ignite UI for Angular, read the getting started topic.
The next step is to import the IgxCalendarModule
in your app.module.ts file.
Note
The IgxCalendarComponent also depends on the BrowserAnimationsModule
and optionally the HammerModule
for touch interactions, so they need to be added to the AppModule as well:
// app.module.ts
...
import { HammerModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { IgxCalendarModule } from 'igniteui-angular';
// import { IgxCalendarModule } from '@infragistics/igniteui-angular'; for licensed package
@NgModule({
...
imports: [..., BrowserAnimationsModule, HammerModule, IgxCalendarModule],
...
})
export class AppModule {}
Alternatively, as of 16.0.0
you can import the IgxCalendarComponent
as a standalone dependency, or use the IGX_CALENDAR_DIRECTIVES
token to import the component and all of its supporting components and directives.
// home.component.ts
import { HammerModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { IGX_CALENDAR_DIRECTIVES } from 'igniteui-angular';
// import { IGX_CALENDAR_DIRECTIVES } from '@infragistics/igniteui-angular'; for licensed package
@Component({
selector: 'app-home',
template: '<igx-calendar></igx-calendar>',
styleUrls: ['home.component.scss'],
standalone: true,
imports: [BrowserAnimationsModule, HammerModule, IGX_CALENDAR_DIRECTIVES]
/* or imports: [BrowserAnimationsModule, HammerModule, IgxCalendarComponent] */
})
export class HomeComponent {}
Now that you have the Ignite UI for Angular Calendar module or directives imported, you can start using the igx-calendar
component.
Note
The IgxCalendarComponent
uses the Intl Web API for localization and formatting of dates.
Consider using appropriate polyfills if your target platform does not support them.
Using the Angular Calendar
Angular Single Selection Calendar
Instantiating the IgxCalendarComponent
is as easy as placing its selector element in the template. This will display the current month in the single selection calendar mode.
<!-- app.component.html -->
<!-- Single selection mode -->
<igx-calendar></igx-calendar>
Angular Calendar Multiselect
We can easily change the default mode using the selection
property:
<!-- app.component.html -->
<!-- Multi selection mode -->
<igx-calendar selection="multi" [showWeekNumbers]="true"></igx-calendar>
Angular Calendar Range Picker
Following the same approach, we can switch to range selection mode:
<!-- app.component.html -->
<!-- Range selection mode -->
<igx-calendar selection="range"></igx-calendar>
Note
Notice that the calendar header is not rendered when the selection is either multi
or range
.
Localization and Formatting
Due to their very nature, localization and formatting are essential to any calendar. In the IgxCalendarComponent
those are controlled and customized through the following properties - locale
, formatOptions
, formatViews
, weekStart
.
Let's go ahead and try those along with other customizations from the IgxCalendarComponent API
. First thing we need to set is the weekStart
, which controls the starting day of the week. It defaults to 0, which corresponds to Sunday, so we will set a value of 1 for Monday. In the markup below we are also binding the formatOptions
and formatViews
properties to customize the display formatting. Finally, we are binding the locale
property to a value, based on the user's location choice:
<!-- app.component.html -->
<igx-select #select [(ngModel)]="locale">
<igx-select-item *ngFor="let locale of locales" [value]="locale">
{{ locale }}
</igx-select-item>
</igx-select>
<igx-calendar #calendar
[weekStart]="1"
[locale]="locale"
[formatOptions]="formatOptions"
[formatViews]="formatViews">
</igx-calendar>
All property values should be set in the AppCоmponent file:
// app.component.ts
@ViewChild('calendar', { read: IgxCalendarComponent }) public calendar: IgxCalendarComponent;
public formatOptions: any;
public formatViews: any;
public locales = ['EN', 'DE', 'FR', 'AR', 'ZH'];
public locale = 'EN';
public ngOnInit() {
this.formatOptions = { day: '2-digit', month: 'long', weekday: 'long', year: 'numeric' };
this.formatViews = { day: true, month: true, year: true };
}
If everything went well, we should now have a calendar with customized dates display, that also changes the locale representation, based on the user location. Let's have a look at it:
How to Disable Dates In Angular Calendar
This section demonstrates the usage of disabledDates
functionality. For this purpose, different single dates or ranges can be added to an array and then passed to the disabledDates
descriptor.
The DateRangeType
is used to specify a range that is going to be disabled.
Let's create a sample that is disabling the dates between the 3rd and the 8th of the current month:
export class CalendarSample6Component {
@ViewChild('calendar') public calendar: IgxCalendarComponent;
public today = new Date(Date.now());
public range = [
new Date(this.today.getFullYear(), this.today.getMonth(), 3),
new Date(this.today.getFullYear(), this.today.getMonth(), 8)
];
public ngOnInit() {
this.calendar.disabledDates = [{ type: DateRangeType.Between, dateRange: this.range }];
}
}
These configurions should have the following result:
Special dates
The specialDates
feature is using almost the same configuration principles as the disabledDates
. The ability to select and focus specialDates
is what differs them from the disabled
ones.
Let's add some specialDates
to our igxCalendar
. In order to do this, we have to create a DateRangeDescriptor
item of type DateRangeType.Specific
and pass an array of dates as a dateRange
:
export class CalendarSample7Component {
@ViewChild('calendar', { static: true })
public calendar: IgxCalendarComponent;
@ViewChild('alert', { static: true })
public dialog: IgxDialogComponent;
public range = [];
public selectPTOdays(dates: Date[]) {
this.range = dates;
}
public submitPTOdays(eventArgs) {
this.calendar.specialDates =
[{ type: DateRangeType.Specific, dateRange: this.range }];
this.range.forEach((item) => {
this.calendar.selectDate(item);
});
...
}
}
<igx-calendar #calendar weekStart="1"
selection="multi"
(selected)="selectPTOdays($event)">
</igx-calendar>
<igx-dialog #alert title="Request Time Off"
leftButtonLabel="OK"
(leftButtonSelect)="alert.close()">
</igx-dialog>
<button igxButton="contained" (click)="submitPTOdays($event)">Submit Request</button>
The following demo illustrates a calendar with a vacation request option:
Week numbers
You can now use showWeekNumbers
input to show the week numbers for both Calendar and DatePicker components.
<!-- app.component.html -->
<igx-calendar selection="multi" [showWeekNumbers]="true"></igx-calendar>
The following demo illustrates a calendar with enabled week numbers:
Calendar Events
Let's explore the events emitted by the calendar:
selected
- emitted when selecting date(s) in the calendar.viewDateChanged
- emitted every time when the presented month/year is changed - for example after navigating to thenext
orprevious
month.activeViewChanged
- emitted after the active view is changed - for example after the user has clicked on themonth
oryear
section in the header.
<!-- app.component.html -->
<igx-calendar #calendar
(selected)="onSelection($event)"
(viewDateChanged)="viewDateChanged($event)"
(activeViewChanged)="activeViewChanged($event)">
</igx-calendar>
The selected
event is suitable to build input validation logic. Use the code from below to alert the user if selection exceeds 5 days, and then reset the selection:
// app.component.ts
...
public onSelection(dates: Date[]) {
if (dates.length > 5) {
this.calendar.selectedDates = [];
// alert the user
}
}
public viewDateChanged(event: IViewDateChangeEventArgs) {
// use event.previousValue to get previous month/year that was presented.
// use event.currentValue to get current month/year that is presented.
}
public activeViewChanged(event: CalendarView) {
// use CalendarView[event] to get the current active view (DEFAULT, YEAR or DECADE)
}
Use the demo below to play around (change selection, navigate through months and years) and see the events logged real time:
Angular Calendar Views
There are separate views provided by the IgxCalendarModule
that can be used independently:
- Angular Calendar Days View -
igx-days-view
- Angular Calendar Month View -
igx-months-view
- Angular Calendar Year View -
igx-years-view
Keyboard navigation
If you traverse the page using Tab key you should keep in mind that based on W3 accessability recommendations the igxCalendarComponent now introduces the following tab stops:
- Previous month button
- Month selection button
- Year selection button
- Next month button
- Selected date, Current date, First focusable (not disabled) date in the days view
In an Angular Calendar that contains more than one selected dates, only the first date will be introduced as a tab stop. For example, when an Angular Calendar multiselect is enabled and you have selected the dates: 13/10/2020, 17/10/2020 and 21/10/2020 only 13/10/2020 will be accessible during tab navigation; in an Angular Calendar Range Picker, only the first date of the selected range will be part of the page tab sequence.
Note
Behavioral change, from v10.2.0 - Tab key navigation in the days view is no longer available. In order to navigate between the dates in the date view you should use the arrow keys.
When the igxCalendar
component is focused, use:
- PageUp key to move to the previous month,
- PageDown key to move to the next month,
- Shift + PageUp keys to move to the previous year,
- Shift + PageDown keys to move to the next year,
- Home key to focus the first day of the current month or first month in view
- End key to focus the last day of the current month or last month in view
When the prev
or the next
month buttons (in the subheader) are focused, use:
- Space or Enter key to scroll into view the next or previous month.
When the months
button (in the subheader) is focused, use:
- Space or Enter key to open the months view.
When the year
button (in the subheader) is focused, use:
- Space or Enter key to open the decade view.
When a day
inside the current month is focused:
- Use Arrow keys to navigate through the days. Note: The disabled dates will be skipped.
- Focus will be persisted on the current month that is in the view, while navigation from/to the last day/first day of the month.
- THe kb navigation would be continuous, which means that it will go through all months while navigating with the arrows.
- Use Enter key to select the currently focused day.
When a month
inside the months view is focused, use:
- Arrow keys to navigate through the months.
- Home key to focus the first month inside the months view.
- End key to focus the last month inside the months view.
- Enter key to select the currently focused month and close the view.
When an year
inside the decade view is focused, use:
- Arrow up and Arrow down keys to navigate through the years,
- Enter key to select the currently focused year and close the view.
Note
Following version 8.2.0, keyboard navigation will not focus days that are outside of current month, but will rather change the month in view.
Multi View Calendar
Multiview calendar supports all three types of selection. Use the monthsViewNumber
input to set the number of displayed months, which will be shown horizontally in a flex container. There is no limit on the max value set. While using a multi view calendar, you may want to hide the days that do not belong to the current month. You are able to do it with the hideOutsideDays
property. Keyboard navigation moves to next/previous months when those are in view.
Calendar Orientation
The orientation settings allows users to choose how the header and the view of the calendar are displayed.
Header Orientation Options:
You can change the header orientation to place the header of the calendar to be either horizontal(above the calendar view) or vertical(on the side of the calendar view).
To do that, use the [headerOrientation]
property, setting it respectively to horizontal
or vertical
View Orientation Options:
You can set the view orientation to place the months in the calendar either horizontally(side by side) or vertically(above one another).
To do that, use the [orientation]
property, setting it respectively to horizontal
or vertical
.
Note
You need at least two month view calendar to see that property working.
<igx-calendar [monthsViewNumber]="2" [headerOrientation]="headerOrientation" [orientation]="orientation"></igx-calendar>
const orientations = ["horizontal", "vertical"] as const;
type Orientation = (typeof orientations)[number];
export class CalendarSample9Component {
protected orientations = Array.from(orientations, (o) => o);
protected headerOrientation: Orientation = "horizontal";
protected orientation: Orientation = "horizontal";
protected setHeaderOrientation(orientation: Orientation) {
this.headerOrientation = orientation;
}
protected setOrientation(orientation: Orientation) {
this.orientation = orientation;
}
}
Styling
To get started with styling the calendar, we need to import the index
file, where all the theme functions and component mixins live:
@use "igniteui-angular/theming" as *;
// IMPORTANT: Prior to Ignite UI for Angular version 13 use:
// @import '~igniteui-angular/lib/core/styles/themes/index';
Following the simplest approach, we create a new theme that extends the calendar-theme
and accepts some of the default theme's parameters.
$custom-calendar-theme: calendar-theme(
$header-background: #345779,
$content-background: #fdfdfd,
$header-text-color: #ffffff,
$date-current-text-color: #2dabe8,
$picker-arrow-color: #2dabe8,
$date-selected-text-color: #fdfdfd,
$date-current-bg-color: #fdfdfd,
$picker-arrow-hover-color: #345779,
$year-current-text-color: #2dabe8,
$year-hover-text-color: #2dabe8,
$month-current-text-color: #2dabe8,
$month-hover-text-color: #2dabe8,
$picker-text-color: #2dabe8,
$picker-text-hover-color: #345779
);
Using CSS variables
The last step is to pass the custom calendar theme:
@include css-vars($custom-calendar-theme);
Using Theme Overrides
In order to style components for older browsers, like Internet Explorer 11, we have to use a different approach, since it doesn't support CSS variables.
If the component is using the Emulated
ViewEncapsulation, it is necessary to penetrate
this encapsulation using ::ng-deep
. To prevent the custom theme to leak into other components, be sure to include the :host
selector before ::ng-deep
:
:host {
::ng-deep {
@include calendar($custom-calendar-theme);
}
}
API References
Additional Resources
Our community is active and always welcoming to new ideas.