I am trying to prevent users from creating overlapping events in our calendar. I was able to implement this somewhat successfully using the demo at https://demos.telerik.com/aspnet-ajax/scheduler/examples/limitconcurrentappointments/defaultvb.aspx. I am having an issue though due to the fact that we use a customized Advanced Form template for our events. On insert or update, I can use the ExceedsLimit() function to cancel the insert or update, but the Advanced Form is cleared out and loses all of the information the user has entered. Ideally we would present the user with an error message and allow them to fix the data rather than having to enter it all over from scratch. Is this possible?
I updated the Advanced Insert and Edit Forms demo located at https://demos.telerik.com/aspnet-ajax/scheduler/examples/advancedformtemplate/defaultvb.aspx to demonstrate the issue.
DefaultVB.aspx
<%@ Page Language="vb" AutoEventWireup="true" Inherits="Scheduler.Examples.AdvancedFormTemplate.DefaultVB"
CodeFile="DefaultVB.aspx.vb" MasterPageFile="~/MasterPageCDNDisabled.master" %>
<%@ Register TagPrefix="sds" Namespace="Telerik.Web.SessionDS" %>
<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
<%@ Register TagPrefix="scheduler" TagName="AdvancedForm" Src="AdvancedFormCS.ascx" %>
<
asp:Content
ID
=
"Content1"
ContentPlaceHolderID
=
"head"
runat
=
"Server"
>
<
link
rel
=
"Stylesheet"
type
=
"text/css"
href
=
"styles.css"
/>
</
asp:Content
>
<
asp:Content
ID
=
"Content2"
ContentPlaceHolderID
=
"ContentPlaceholder1"
runat
=
"Server"
>
<
telerik:RadAjaxManager
ID
=
"RadAjaxManager1"
runat
=
"server"
>
<
AjaxSettings
>
<
telerik:AjaxSetting
AjaxControlID
=
"RadScheduler1"
>
<
UpdatedControls
>
<
telerik:AjaxUpdatedControl
ControlID
=
"RadScheduler1"
LoadingPanelID
=
"RadAjaxLoadingPanel1"
/>
</
UpdatedControls
>
</
telerik:AjaxSetting
>
</
AjaxSettings
>
</
telerik:RadAjaxManager
>
<
telerik:RadAjaxLoadingPanel
ID
=
"RadAjaxLoadingPanel1"
runat
=
"server"
/>
<
telerik:RadScriptBlock
runat
=
"Server"
ID
=
"RadScriptBlock1"
>
<
script
type
=
"text/javascript"
src
=
"scripts.js"
></
script
>
</
telerik:RadScriptBlock
>
<
telerik:RadNotification
runat
=
"server"
ID
=
"RadNotification1"
Title
=
"Error"
TitleIcon
=
"warning"
ContentIcon
=
"warning"
Position
=
"Center"
Width
=
"430px"
Height
=
"200px"
AutoCloseDelay
=
"10000"
ShowSound
=
"warning"
Font-Size
=
"Large"
>
<
NotificationMenu
Visible
=
"false"
></
NotificationMenu
>
</
telerik:RadNotification
>
<
div
class
=
"demo-container no-bg"
>
<
telerik:RadScheduler
RenderMode
=
"Lightweight"
runat
=
"server"
ID
=
"RadScheduler1"
SelectedDate
=
"2012-04-16"
OnDataBound
=
"RadScheduler1_DataBound"
OnAppointmentCreated
=
"RadScheduler1_AppointmentCreated"
OnAppointmentInsert
=
"RadScheduler1_AppointmentInsert"
OnAppointmentDataBound
=
"RadScheduler1_AppointmentDataBound"
OnClientFormCreated
=
"schedulerFormCreated"
CustomAttributeNames
=
"AppointmentColor"
EnableDescriptionField
=
"true"
>
<
AdvancedForm
Modal
=
"true"
EnableTimeZonesEditing
=
"true"
/>
<
Reminders
Enabled
=
"true"
/>
<
AppointmentTemplate
>
<
div
class
=
"rsAptSubject"
>
<%# Eval("Subject") %>
</
div
>
<%# Eval("Description") %>
</
AppointmentTemplate
>
<
AdvancedEditTemplate
>
<
scheduler:AdvancedForm
runat
=
"server"
ID
=
"AdvancedEditForm1"
Mode
=
"Edit"
Subject='<%# Bind("Subject") %>'
Description='<%# Bind("Description") %>'
Start='<%# Bind("Start") %>'
End='<%# Bind("End") %>'
RecurrenceRuleText='<%# Bind("RecurrenceRule") %>'
Reminder='<%# Bind("Reminder") %>'
AppointmentColor='<%# Bind("AppointmentColor") %>'
UserID='<%# Bind("User") %>'
RoomID='<%# Bind("Room") %>'
TimeZoneID='<%# Bind("TimeZoneID") %>' />
</
AdvancedEditTemplate
>
<
AdvancedInsertTemplate
>
<
scheduler:AdvancedForm
runat
=
"server"
ID
=
"AdvancedInsertForm1"
Mode
=
"Insert"
Subject='<%# Bind("Subject") %>'
Start='<%# Bind("Start") %>'
End='<%# Bind("End") %>'
Description='<%# Bind("Description") %>'
RecurrenceRuleText='<%# Bind("RecurrenceRule") %>'
Reminder='<%# Bind("Reminder") %>'
AppointmentColor='<%# Bind("AppointmentColor") %>'
UserID='<%# Bind("User") %>'
RoomID='<%# Bind("Room") %>'
TimeZoneID='<%# Bind("TimeZoneID") %>' />
</
AdvancedInsertTemplate
>
<
TimelineView
UserSelectable
=
"false"
/>
<
TimeSlotContextMenuSettings
EnableDefault
=
"true"
/>
<
AppointmentContextMenuSettings
EnableDefault
=
"true"
/>
</
telerik:RadScheduler
>
</
div
>
</
asp:Content
>
DefaultVB.aspx.vb
Imports
System
Imports
System.Web.UI
Imports
System.Drawing
Imports
System.Web.UI.WebControls
Imports
Telerik.Web.UI
Namespace
Scheduler.Examples.AdvancedFormTemplate
Public
Class
DefaultVB
Inherits
System.Web.UI.Page
Private
Const
ProviderSessionKey
As
String
=
"Telerik.Web.Examples.Scheduler.AdvancedFormTemplate.DefaultVB"
' You can safely ignore this method.
' Its purpose is to limit the changes to the underlying data only to the active user session.
Protected
Sub
Page_Init(
ByVal
sender
As
Object
,
ByVal
e
As
EventArgs)
Dim
manager
As
ScriptManager = RadScriptManager.GetCurrent(Page)
manager.Scripts.Add(
New
ScriptReference(ResolveUrl(
"AdvancedForm.js"
)))
Dim
provider
As
XmlSchedulerProvider
If
((Session(ProviderSessionKey)
Is
Nothing
) _
OrElse
Not
IsPostBack)
Then
provider =
New
XmlSchedulerProvider(Server.MapPath(
"~/App_Data/Appointments_CustomTemplates.xml"
),
False
)
Session(ProviderSessionKey) = provider
Else
provider =
CType
(Session(ProviderSessionKey), XmlSchedulerProvider)
End
If
RadScheduler1.Provider = provider
End
Sub
Protected
Sub
Page_Load(
ByVal
sender
As
Object
,
ByVal
e
As
EventArgs)
RadScheduler1.TimeZoneID =
"Pacific Standard Time"
End
Sub
Protected
Sub
RadScheduler1_DataBound(
ByVal
sender
As
Object
,
ByVal
e
As
EventArgs)
RadScheduler1.ResourceTypes.FindByName(
"User"
).AllowMultipleValues =
True
RadScheduler1.ResourceTypes.FindByName(
"Room"
).AllowMultipleValues =
False
End
Sub
Protected
Sub
RadScheduler1_AppointmentCreated(
ByVal
sender
As
Object
,
ByVal
e
As
AppointmentCreatedEventArgs)
If
e.Appointment.RecurrenceState = RecurrenceState.Master
OrElse
e.Appointment.RecurrenceState = RecurrenceState.Occurrence
Then
Dim
recurrenceStateDiv
As
New
Label()
recurrenceStateDiv.CssClass =
"rsAptRecurrence"
Dim
recurrenceStateIcon
As
New
Label()
recurrenceStateIcon.CssClass =
"t-font-icon t-i-recurrence"
recurrenceStateDiv.Controls.Add(recurrenceStateIcon)
e.Container.Controls.AddAt(0, recurrenceStateDiv)
End
If
If
e.Appointment.RecurrenceState = RecurrenceState.Exception
Then
Dim
recurrenceStateDiv
As
New
Label()
recurrenceStateDiv.CssClass =
"rsAptRecurrenceException"
Dim
recurrenceStateIcon
As
New
Label()
recurrenceStateIcon.CssClass =
"t-font-icon t-i-recurrence-exception"
recurrenceStateDiv.Controls.Add(recurrenceStateIcon)
e.Container.Controls.AddAt(0, recurrenceStateDiv)
End
If
End
Sub
Protected
Sub
RadScheduler1_AppointmentDataBound(
ByVal
sender
As
Object
,
ByVal
e
As
SchedulerEventArgs)
Dim
colorAttribute
As
String
= e.Appointment.Attributes(
"AppointmentColor"
)
If
Not
String
.IsNullOrEmpty(colorAttribute)
Then
Dim
colorValue
As
Integer
If
Integer
.TryParse(colorAttribute, colorValue)
Then
Dim
borderColorValue
As
Integer
=
CInt
(
If
(colorValue < -&H7F7F7F, colorValue + &H202020, colorValue - &H202020))
e.Appointment.BackColor = Color.FromArgb(colorValue)
e.Appointment.BorderColor = Color.FromArgb(borderColorValue)
End
If
End
If
e.Appointment.ToolTip = e.Appointment.Subject +
": "
+ e.Appointment.Description
End
Sub
Protected
Sub
RadScheduler1_AppointmentInsert(sender
As
Object
, e
As
SchedulerCancelEventArgs)
If
ExceedsLimit(e.Appointment)
Then
e.Cancel =
True
RadNotification1.Show(
"Cannot add appointment! There are too many appointments in this time slot. You can only have "
& AppointmentsLimit)
End
If
End
Sub
Private
Const
AppointmentsLimit
As
Integer
= 1
Private
Function
ExceedsLimit(apt
As
Appointment)
As
Boolean
Dim
appointmentsCount
As
Integer
= 0
For
Each
existingApt
As
Appointment
In
RadScheduler1.Appointments.GetAppointmentsInRange(apt.Start, apt.[
End
])
If
existingApt.Visible
Then
appointmentsCount += 1
End
If
Next
Return
(appointmentsCount > AppointmentsLimit - 1)
End
Function
End
Class
End
Namespace