Recurrence Editor in Angular Scheduler
The recurrence editor is integrated into the Scheduler’s editor window by default to process recurrence rule generation for events. Apart from this, it can also be used as an individual component from the Scheduler repository to work with recurrence-related processes.
All valid recurrence rule strings defined in the iCalendar specification apply to the recurrence editor.
Customizing the repeat type option in editor
By default, the recurrence editor provides five repeat options:
- Never
- Daily
- Weekly
- Monthly
- Yearly
You can customize the recurrence editor to display only specific repeat options, such as Daily and Weekly, by setting the frequencies property.
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { ScheduleModule } from '@syncfusion/ej2-angular-schedule'
import { ButtonModule } from '@syncfusion/ej2-angular-buttons'
import { DayService, WeekService, WorkWeekService, MonthService, AgendaService, MonthAgendaService} from '@syncfusion/ej2-angular-schedule'
import { Component, ViewChild} from '@angular/core';
import { EventSettingsModel, PopupOpenEventArgs, ScheduleComponent } from '@syncfusion/ej2-angular-schedule';
import { scheduleData } from './datasource';
@Component({
imports: [
ScheduleModule,
ButtonModule
],
providers: [DayService,
WeekService,
WorkWeekService,
MonthService,
AgendaService,
MonthAgendaService],
standalone: true,
selector: 'app-root',
// specifies the template string for the Schedule component
template: `<ejs-schedule #scheduleObj width='100%' height='550px' [selectedDate]='selectedDate'
[eventSettings]='eventSettings' (popupOpen)='onPopupOpen($event)'>
</ejs-schedule>`
})
export class AppComponent {
@ViewChild('scheduleObj')
public scheduleObj?: ScheduleComponent;
public selectedDate: Date = new Date(2018, 1, 15);
public eventSettings: EventSettingsModel = { dataSource: scheduleData };
onPopupOpen(args: PopupOpenEventArgs): void {
if (args.type == 'Editor') {
(<any>this.scheduleObj!.eventWindow).recurrenceEditor.frequencies = ['daily', 'weekly'];
}
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));The other properties available in recurrence editor are tabulated below:
| Properties | Type | Description |
|---|---|---|
| firstDayOfWeek | number | Sets the first day of the week on recurrence editor. |
| startDate | Date | Sets the start date from which date the recurrence event starts. |
| dateFormat | string | Sets the specific date format on recurrence editor. |
| locale | string | Sets the locale to be applied on recurrence editor. |
| cssClass | string | Allows styling to be applied on recurrence editor with custom class names. |
| enableRtl | boolean | Allows recurrence editor to render in RTL mode. |
| minDate | Date | Sets the minimum date on recurrence editor. |
| maxDate | Date | Sets the maximum date on recurrence editor. |
| value | string | Sets the recurrence rule value on recurrence editor. |
| selectedType | number | Sets the specific repeat type on the recurrence editor. |
Customizing the End Type Option in Editor
By default, the recurrence editor provides three end options:
- Never
- Until
- Count
You can customize the recurrence editor to display only specific end options, such as Until and Count, by setting the endTypes property.
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { RecurrenceEditorModule } from '@syncfusion/ej2-angular-schedule'
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'
import { Component, ViewChild } from '@angular/core';
import { RecurrenceEditorComponent } from '@syncfusion/ej2-angular-schedule';
@Component({
imports: [
RecurrenceEditorModule,
DropDownListAllModule
],
standalone: true,
selector: 'app-root',
template: `<ejs-recurrenceeditor #recurrenceObj></ejs-recurrenceeditor>`
})
export class AppComponent {
@ViewChild('recurrenceObj')
public recurrenceObj?: RecurrenceEditorComponent;
ngAfterViewInit() {
(this.recurrenceObj as RecurrenceEditorComponent ).selectedType = 1;
(this.recurrenceObj as RecurrenceEditorComponent | any ).endTypes = ['until', 'count'];
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Accessing the recurrence rule string
The recurrence rule is usually generated based on the options selected from the recurrence editor and also it follows the iCalendar specifications. The generated recurrence rule string is a valid one to be used with the Scheduler event’s recurrence rule field.
There is a change event available in the recurrence editor that triggers every time the fields of the recurrence editor change. Within this event argument, you can access the generated recurrence value through the value option as shown in the following code example.
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { RecurrenceEditorModule } from '@syncfusion/ej2-angular-schedule'
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'
import { Component} from '@angular/core';
import { RecurrenceEditorChangeEventArgs } from '@syncfusion/ej2-angular-schedule';
import { isNullOrUndefined } from "@syncfusion/ej2-base";
@Component({
imports: [
RecurrenceEditorModule,
DropDownListAllModule
],
standalone: true,
selector: 'app-root',
// specifies the template string for the Schedule component
template: `<div style="padding-bottom:15px;">
<label id="rule-label">Rule Output</label>
<div class="rule-output-container">
<div id="rule-output"></div>
</div>
</div>
<ejs-recurrenceeditor (change)="onChange($event)"></ejs-recurrenceeditor>
`
})
export class AppComponent {
public selectRule: string = 'Select Rule';
onChange(args: RecurrenceEditorChangeEventArgs): void {
if (!isNullOrUndefined(args.value)) {
if(args.value == "") {
this.selectRule = 'Select Rule';
} else {
this.selectRule = args.value;
}
}
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Set specific value on recurrence editor
It is possible to display the recurrence editor with specific options loaded initially, based on the rule string that we provide. The fields of recurrence editor will change its values accordingly, when we provide a particular rule through the setRecurrenceRule method.
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { RecurrenceEditorModule } from '@syncfusion/ej2-angular-schedule'
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'
import { Component } from '@angular/core';
import { isNullOrUndefined } from '@syncfusion/ej2-base';
import { RecurrenceEditorChangeEventArgs } from '@syncfusion/ej2-angular-schedule';
@Component({
imports: [
RecurrenceEditorModule,
DropDownListAllModule
],
standalone: true,
selector: 'app-root',
// specifies the template string for the Schedule component
template: `<div class="content-wrapper recurrence-editor-wrap">
<div style="padding-bottom:15px;">
<label>Rule Output</label>
<div class="rule-output-container">
<div id="rule-output"></div>
</div>
</div>
<ejs-recurrenceeditor (change)="onChange($event)" value="FREQ=DAILY;INTERVAL=2;COUNT=8"></ejs-recurrenceeditor>
</div>`
})
export class AppComponent {
public selectRule: string = 'FREQ=DAILY;INTERVAL=2;COUNT=8';
public onChange(args: RecurrenceEditorChangeEventArgs): void {
if (!isNullOrUndefined(args.value)) {
this.selectRule = args.value;
}
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Recurrence date generation
You can parse the recurrenceRule of an event to generate the date instances on which that particular event is going to occur by using the getRecurrenceDates method. It generates the dates based on the recurrenceRule that you provide. The parameters for the getRecurrenceDates method are as follows.
| Field name | Type | Description |
|---|---|---|
startDate |
Date | Appointment start date. |
rule |
String | Recurrence rule present in an event object. |
excludeDate |
String | Date collection (in ISO format) to be excluded. It is optional. |
maximumCount |
Number | Number of dates to be generated. It is optional. |
viewDate |
Date | Current view range’s first date. It is optional. |
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { RecurrenceEditorModule } from '@syncfusion/ej2-angular-schedule'
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'
import { Component, ViewChild } from '@angular/core';
import { RecurrenceEditor, RecurrenceEditorChangeEventArgs } from '@syncfusion/ej2-angular-schedule';
import { isNullOrUndefined } from '@syncfusion/ej2-base';
@Component({
imports: [
RecurrenceEditorModule,
DropDownListAllModule
],
standalone: true,
selector: 'app-root',
// specifies the template string for the Schedule component
template: `<div style="padding-bottom:15px;">
<label id="rule-label">Date Collections</label>
<div class="rule-output-container">
<div id="rule-output">
<div *ngFor="let date of dateArray"></div>
</div>
</div>
</div>
<ejs-recurrenceeditor #recurrenceObj [value]="value" (change)="onChange($event)"></ejs-recurrenceeditor>`
})
export class AppComponent {
@ViewChild('recurrenceObj') public recObject: RecurrenceEditor =
new RecurrenceEditor();
public value = 'FREQ=DAILY;INTERVAL=1';
public dateArray: string[] = [];
public selectRule: string = 'Select Rule';
onChange(args: RecurrenceEditorChangeEventArgs): void {
if (!isNullOrUndefined(args.value)) {
this.dateArray = [];
if (args.value == '') {
this.dateArray.push(this.selectRule.toString());
} else {
let dates: number[] = this.recObject.getRecurrenceDates(
new Date(),
args.value
);
for (let i: number = 0; i < dates.length; i++) {
this.dateArray.push(new Date(dates[i]).toString());
}
}
}
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));The above example generates two dates, January 7, 2018 and January 9, 2018, by excluding the in-between dates January 8, 2018 and January 10, 2018, since those dates were given in the exclusion list. Generated dates can then be used to create appointments.
Recurrence date generation in server-side
It is also possible to generate recurrence date instances from the server side by manually referring to the RecurrenceHelper class, which is specifically written and referenced from the application side to handle this date generation process.
Refer here for the step-by-step procedure to achieve date generation on the server side.
Restrict date generation with specific count
If the rule is given in the “NEVER ENDS” category, you can specify the maximum count when you want to stop date generation from the provided start date. To do so, provide the appropriate maximumCount value within the getRecurrenceDates method as shown in the following code example.
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { RecurrenceEditorModule } from '@syncfusion/ej2-angular-schedule'
import { DropDownListAllModule } from '@syncfusion/ej2-angular-dropdowns'
import { NumericTextBoxAllModule } from '@syncfusion/ej2-angular-inputs'
import { Component, OnInit } from '@angular/core';
import { RecurrenceEditor } from '@syncfusion/ej2-angular-schedule';
import { ChangeEventArgs } from '@syncfusion/ej2-angular-inputs';
import { isNullOrUndefined } from '@syncfusion/ej2-base';
@Component({
imports: [
RecurrenceEditorModule,
DropDownListAllModule,
NumericTextBoxAllModule
],
standalone: true,
selector: 'app-root',
// specifies the template string for the Schedule component
template: `<div style="padding-bottom:15px;">
<label id="rule-label">Date Collections</label>
<div class="rule-output-container">
<div id="rule-output">
<div *ngFor="let date of dateArray"></div>
</div>
</div>
</div>
<ejs-numerictextbox [(value)]='numericValue' (change)= "onChange($event)"></ejs-numerictextbox>`
})
export class AppComponent implements OnInit {
public ruleString = 'FREQ=DAILY;INTERVAL=1';
public numericValue: number = 10;
public dateArray: string[] = [];
public recObject: RecurrenceEditor = new RecurrenceEditor();
ngOnInit(): void {
let dates: number[] = this.recObject.getRecurrenceDates(
new Date(2018, 0, 7, 10, 0),
this.ruleString,
'20180108T114224Z,20180110T114224Z',
this.numericValue,
new Date(2018, 0, 7)
);
for (let i: number = 0; i < dates.length; i++) {
this.dateArray.push(new Date(dates[i]).toString());
}
}
onChange(args: ChangeEventArgs) {
if (!isNullOrUndefined(args.value)) {
this.dateArray = [];
let dates: number[] = this.recObject.getRecurrenceDates(
new Date(2018, 0, 7, 10, 0),
this.ruleString,
'20180108T114224Z,20180110T114224Z',
args.value,
new Date(2018, 0, 7)
);
for (let i: number = 0; i < dates.length; i++) {
this.dateArray.push(new Date(dates[i]).toString());
}
}
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));You can refer to our Angular Scheduler feature tour page for its groundbreaking feature representations. You can also explore our Angular Scheduler example to know how to present and manipulate data.