Skip to content

Commit 131bde7

Browse files
dimodiyordan-mitev
andauthored
docs(Scheduler): Add Recurrence article (#2873)
* docs(Scheduler): Add Recurrence article * Update components/scheduler/recurrence.md Co-authored-by: Yordan <60105689+yordan-mitev@users.noreply.github.com> * Apply PR suggestions * Link recurrence editors * Update components/scheduler/overview.md * Remove content for next release --------- Co-authored-by: Yordan <60105689+yordan-mitev@users.noreply.github.com>
1 parent 1d58dea commit 131bde7

File tree

4 files changed

+245
-14
lines changed

4 files changed

+245
-14
lines changed

components/scheduler/navigation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Navigating the Scheduler for Blazor.
55
slug: scheduler-navigation
66
tags: telerik,blazor,scheduler,navigation
77
published: true
8-
position: 20
8+
position: 4
99
---
1010

1111
# Scheduler Navigation

components/scheduler/overview.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,26 +95,30 @@ The [Scheduler offers different views](slug:scheduler-views-overview) that are s
9595
* Timeline (agenda) view
9696

9797

98-
## Editing
99-
100-
Users can [create, edit and delete Scheduler appointments](slug:scheduler-appointments-edit). The component provides you with the new information so you can store it to the underlying data source.
101-
102-
10398
## Navigation
10499

105100
The [Scheduler features extensive navigation](slug:scheduler-navigation), which can be both programmatic and managed by the end user. The component can change the currently visible time range, the current view, and toggle business hours only display.
106101

107102

108-
## Templates
103+
## Editing
104+
105+
Users can [create, edit and delete Scheduler appointments](slug:scheduler-appointments-edit). The component provides you with the new information so you can store it to the underlying data source.
109106

110-
You can [customize the appointment appearance and content via Scheduler templates](slug:scheduler-templates-appointment). Another option is to use the [Scheduler `OnItemRender` event](slug:scheduler-events#itemrender).
111107

108+
## Recurrence
109+
110+
The Scheduler can display and edit [recurring appointments and recurrence exceptions](slug:scheduler-recurrence).
112111

113112
## Resources and Grouping
114113

115114
[Scheduler resources](slug:scheduler-resources) provide a way to associate and [group appointments](slug:scheduler-resource-grouping) by certain criteria, such as a meeting room, a participating person, or used equipment.
116115

117116

117+
## Templates
118+
119+
You can [customize the appointment appearance and content via Scheduler templates](slug:scheduler-templates-appointment). Another option is to use the [Scheduler `OnItemRender` event](slug:scheduler-events#itemrender).
120+
121+
118122
## Events
119123

120124
The [Scheduler component fires events](slug:scheduler-events) related to CRUD operations, item (appointment) clicks and user navigation. Use them to gain more information about user actions and enhance the component behavior.

components/scheduler/recurrence.md

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
---
2+
title: Recurrence
3+
page_title: Scheduler Recurrence
4+
description: Learn how to set up the Telerik Scheduler for Blazor to display and edit recurring appointments.
5+
slug: scheduler-recurrence
6+
tags: telerik, blazor, scheduler, recurrence
7+
published: True
8+
position: 7
9+
---
10+
11+
# Scheduler Recurrence
12+
13+
The Telerik Scheduler for Blazor supports displaying and editing of recurring appointments and exceptions. This article describes how to:
14+
15+
* Configure the Scheduler for using recurring appointments.
16+
* Define recurrence rules and recurrence exceptions in the Scheduler data.
17+
* Edit recurring appointments and exceptions.
18+
19+
## Basics
20+
21+
To display recurring appointments in the Scheduler component, the model class must implement [three recurrence-related properties](slug:scheduler-appointments-databinding#appointment-features):
22+
23+
* `RecurrenceRule`
24+
* `RecurrenceExceptions`
25+
* `RecurrenceId`
26+
27+
You can also [define custom property names](slug:scheduler-appointments-databinding#example-with-custom-field-names) through the respective Scheduler parameters:
28+
29+
* `RecurrenceRuleField`
30+
* `RecurrenceExceptionsField`
31+
* `RecurrenceIdField`
32+
33+
A single Scheduler data item defines one series of recurring appointments. Set the `RecurrenceRule` value, according to the [RFC5545 standard](https://tools.ietf.org/html/rfc5545#section-3.3.10). Then, if exceptions to the recurrence rule exist:
34+
35+
* Each exception must be a separate data item.
36+
* The `RecurrenceId` property of each exception must be equal to `Id` value of the recurring appointment.
37+
* The `RecurrenceExceptions` property of the recurring appointment must contain the `Start` values of all occurrences, which are exceptions to the recurrence rule. The correct values are the original start `DateTime` values of the occurrences, which would apply if there were no exceptions.
38+
39+
## Example
40+
41+
>caption Bind Scheduler to recurring appointments and recurrence exceptions
42+
43+
````RAZOR
44+
<TelerikScheduler Data="@SchedulerData"
45+
@bind-Date="@SchedulerDate"
46+
@bind-View="@SchedulerView"
47+
AllowCreate="true"
48+
AllowDelete="true"
49+
AllowUpdate="true"
50+
OnCreate="@OnSchedulerCreate"
51+
OnDelete="@OnSchedulerDelete"
52+
OnUpdate="@OnSchedulerUpdate"
53+
Height="99vh">
54+
<SchedulerViews>
55+
<SchedulerDayView StartTime="@SchedulerViewStartTime"
56+
EndTime="@SchedulerViewEndTime" />
57+
<SchedulerWeekView StartTime="@SchedulerViewStartTime"
58+
EndTime="@SchedulerViewEndTime" />
59+
<SchedulerMonthView />
60+
</SchedulerViews>
61+
<SchedulerSettings>
62+
<SchedulerPopupEditSettings MaxHeight="99vh" />
63+
</SchedulerSettings>
64+
</TelerikScheduler>
65+
66+
@code {
67+
private List<Appointment> SchedulerData { get; set; } = new();
68+
69+
private DateTime SchedulerDate { get; set; }
70+
71+
private SchedulerView SchedulerView { get; set; } = SchedulerView.Week;
72+
73+
private DateTime SchedulerViewStartTime { get; set; } = DateTime.Today.AddHours(10);
74+
private DateTime SchedulerViewEndTime { get; set; } = DateTime.Today.AddHours(19);
75+
76+
private void OnSchedulerCreate(SchedulerCreateEventArgs args)
77+
{
78+
Appointment item = (Appointment)args.Item;
79+
80+
SchedulerData.Add(item);
81+
}
82+
83+
private void OnSchedulerDelete(SchedulerDeleteEventArgs args)
84+
{
85+
Appointment item = (Appointment)args.Item;
86+
87+
SchedulerData.Remove(item);
88+
}
89+
90+
private void OnSchedulerUpdate(SchedulerUpdateEventArgs args)
91+
{
92+
Appointment item = (Appointment)args.Item;
93+
94+
int originalItemIndex = SchedulerData.FindIndex(a => a.Id == item.Id);
95+
96+
if (originalItemIndex >= 0)
97+
{
98+
SchedulerData[originalItemIndex] = item;
99+
}
100+
}
101+
102+
protected override void OnInitialized()
103+
{
104+
SchedulerDate = GetNextMonthStart();
105+
106+
DateTime mondayMidnight = GetStartDateTime();
107+
108+
SchedulerData.Add(new Appointment
109+
{
110+
Title = "Weekly team meeting",
111+
Start = mondayMidnight.AddHours(10).AddMinutes(30),
112+
End = mondayMidnight.AddHours(11).AddMinutes(30),
113+
RecurrenceRule = "FREQ=WEEKLY;BYDAY=MO"
114+
});
115+
116+
SchedulerData.Add(new Appointment
117+
{
118+
Title = "Workout at the gym",
119+
Start = mondayMidnight.AddHours(17),
120+
End = mondayMidnight.AddHours(18),
121+
RecurrenceRule = "FREQ=WEEKLY;BYDAY=MO,WE,FR"
122+
});
123+
124+
SchedulerData.Add(new Appointment
125+
{
126+
Title = "Quaterly meeting with manager",
127+
Start = mondayMidnight.AddDays(3).AddHours(14).AddMinutes(30),
128+
End = mondayMidnight.AddDays(3).AddHours(15).AddMinutes(30),
129+
RecurrenceRule = "FREQ=MONTHLY;INTERVAL=3;COUNT=36;BYDAY=TH;BYSETPOS=1"
130+
});
131+
132+
SchedulerData.Add(new Appointment
133+
{
134+
Title = "Pay monthly bills",
135+
Start = new DateTime(mondayMidnight.Year, mondayMidnight.Month, 1),
136+
End = new DateTime(mondayMidnight.Year, mondayMidnight.Month, 1),
137+
IsAllDay = true,
138+
RecurrenceRule = "FREQ=MONTHLY"
139+
});
140+
141+
// Create a base recurring appointment.
142+
// Exceptions are defined below.
143+
Appointment dailyLunch = new Appointment
144+
{
145+
Title = "Daily lunch",
146+
Start = mondayMidnight.AddHours(12),
147+
End = mondayMidnight.AddHours(13),
148+
RecurrenceRule = "FREQ=DAILY"
149+
};
150+
SchedulerData.Add(dailyLunch);
151+
152+
// Create exceptions to the base appointment.
153+
int daysSinceMonday = SchedulerDate.DayOfWeek - DayOfWeek.Monday;
154+
DateTime lastMonday = DateTime.SpecifyKind(SchedulerDate.AddDays(-daysSinceMonday), DateTimeKind.Unspecified);
155+
156+
Appointment lateLunchException = new Appointment
157+
{
158+
Title = "Late lunch",
159+
Start = lastMonday.AddHours(13),
160+
End = lastMonday.AddHours(14),
161+
RecurrenceId = dailyLunch.Id
162+
};
163+
SchedulerData.Add(lateLunchException);
164+
165+
Appointment earlyLunchException = new Appointment
166+
{
167+
Title = "Early lunch",
168+
Start = lastMonday.AddDays(3).AddHours(11),
169+
End = lastMonday.AddDays(3).AddHours(12),
170+
RecurrenceId = dailyLunch.Id
171+
172+
};
173+
SchedulerData.Add(earlyLunchException);
174+
175+
// Relate the exceptions to the base appointment.
176+
DateTime lateLunchOriginalStart = DateTime.SpecifyKind(lastMonday.AddHours(12), DateTimeKind.Unspecified);
177+
DateTime earlyLunchOriginalStart = DateTime.SpecifyKind(lastMonday.AddDays(3).AddHours(12), DateTimeKind.Unspecified);
178+
dailyLunch.RecurrenceExceptions = new List<DateTime>()
179+
{
180+
lateLunchOriginalStart,
181+
earlyLunchOriginalStart
182+
};
183+
}
184+
185+
private DateTime GetNextMonthStart()
186+
{
187+
DateTime today = DateTime.Today;
188+
189+
return new DateTime(today.Year, today.Month, 1).AddMonths(1);
190+
}
191+
192+
private DateTime GetStartDateTime()
193+
{
194+
DateTime firstDayOfLastYear = new DateTime(DateTime.Today.Year, 1, 1).AddYears(-1);
195+
196+
return firstDayOfLastYear.AddDays(1 - (int)firstDayOfLastYear.DayOfWeek);
197+
}
198+
199+
public class Appointment
200+
{
201+
public Guid Id { get; set; }
202+
203+
public string Title { get; set; } = string.Empty;
204+
public string Description { get; set; } = string.Empty;
205+
206+
public DateTime Start { get; set; }
207+
public DateTime End { get; set; }
208+
public bool IsAllDay { get; set; }
209+
210+
public string RecurrenceRule { get; set; } = string.Empty;
211+
public List<DateTime>? RecurrenceExceptions { get; set; }
212+
public object? RecurrenceId { get; set; }
213+
214+
public Appointment()
215+
{
216+
var rand = new Random();
217+
Id = Guid.NewGuid();
218+
}
219+
}
220+
}
221+
````
222+
223+
## Next Steps
224+
225+
* [Enable Scheduler Editing](slug:scheduler-appointments-edit)
226+
227+
## See Also
228+
229+
* [Live Demo: Scheduler Recurring Appointments](https://demos.telerik.com/blazor-ui/scheduler/recurring-appointments)
230+
* [Scheduler API Reference](slug:Telerik.Blazor.Components.TelerikScheduler-1)

docs-builder.yml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -312,16 +312,13 @@ meta:
312312
position: 80
313313
"*components/scheduler/templates":
314314
title: Templates
315-
position: 10
315+
position: 35
316316
"*components/scheduler/views":
317317
title: Views
318-
position: 5
318+
position: 3
319319
"*components/scheduler/editing":
320320
title: Editing
321-
position: 3
322-
"*components/scheduler/appointments":
323-
title: Appointments
324-
position: 2
321+
position: 5
325322
"*components/menu/data-binding":
326323
title: Data Binding
327324
position: 2

0 commit comments

Comments
 (0)