This is a migrated thread and some comments may be shown as answers.

Series vs Occurance problem

6 Answers 47 Views
Scheduler
This is a migrated thread and some comments may be shown as answers.
Andre Myburgh
Top achievements
Rank 1
Andre Myburgh asked on 27 Dec 2013, 07:44 AM

I have had to implement recurrence on the control because WinForms and WebForms are still unable to work with the same database entries.

In doing so, when recurrence is selected, I only allow daily and create physical entries in the booking table for each appointment. The child appointments point back to the parent but the recurrence rule on the parent stays blank.

All of this works fine (mostly). This allows for editing series or occurrence entries. It does however break the moment that an occurrence that does not appear on the same web page as the master entry is edited. The problem occurs on server side when you select Series on an edit of an existing entry:

#Region "Protected properties"
 
    Protected ReadOnly Property Owner() As RadScheduler
        Get
            Return Appointment.Owner
        End Get
    End Property
 
    Protected ReadOnly Property Appointment() As Appointment
        Get
            Dim container As SchedulerFormContainer = DirectCast(BindingContainer, SchedulerFormContainer)
            Return container.Appointment
        End Get
    End Property
 
#End Region

container.Appointment returns Nothing. If you choose instance when editing, it works fine. If you have the master appointment on the screen at the time of selecting series, it also works fine.

Any idea why that would be the case and how I can work around it? If there is no suitable solution I will be removing the control from our project as it has created huge controversy around the rendering times, browser compatibility and WinForms integration issues.

Thank you for your time, paying for it was great fun.

6 Answers, 1 is accepted

Sort by
0
Boyan Dimitrov
Telerik team
answered on 02 Jan 2014, 09:51 AM
Hello,

Could you please clarify that you are facing this problem with the RadScheduler for ASP.NET AJAX or for WinForms?

I would like to clarify that by default the RadScheduler for ASP.NET AJAX loads all appointments (except for the web service binding)  in the RadScheduler1.Appointments collection. As far as I understand from the provided information you are implementing your own logic for occurrence appointment edit and you are facing difficulties in finding the master appointment for specific occurrence appointments in order to modify the recurrence rule.

An easy and convenient way of finding the master appointment for an occurring appointment is shown in the code snippet below:
//code behind
If e.Appointment.RecurrenceParentID IsNot Nothing Then
    Dim masterAppointmentID As Object = e.Appointment.RecurrenceParentID
    Dim masterAppointment As Appointment = RadScheduler1.Appointments.FindByID(masterAppointmentID)
    masterAppointment.RecurrenceRule = "here goes your new recurrence rule"
End If



Regards,
Boyan Dimitrov
Telerik
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to the blog feed now.
0
Andre Myburgh
Top achievements
Rank 1
answered on 03 Jan 2014, 05:32 AM

Hi Boyan,

Asp.net. If I use the code you have provided, it would crash on line 1 because the e.appointment is null. This is the problem I am facing.

Which event are you using the code in? I am using it on the advanced edit form to populate the form
0
Boyan Dimitrov
Telerik team
answered on 07 Jan 2014, 01:31 PM
Hello,

As far as I understand you want to modify the master appointment recurrence rule when you try to edit an occurrence appointment. So I have used the AppointmentUpdate server-side event. If you want to use the FormCreated which is fired when user opens the insert or edit forms you have to check whether e.Appointment.RecurrenceParentID is not null and then implement the logic for finding the master appointment.


Regards,
Boyan Dimitrov
Telerik
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to the blog feed now.
0
Andre Myburgh
Top achievements
Rank 1
answered on 17 Jan 2014, 04:42 AM
Imports System
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Drawing
Imports Telerik.Web.UI
 
Public Enum BookingRequestAdvancedFormAdvancedFormMode
    Insert
    Edit
End Enum
 
Partial Class BookingRequestAdvancedFormAdvancedForm
    Inherits System.Web.UI.UserControl
 
    Const DEFAULT_START_TIME As Integer = 8
    Const DEFAULT_DURATION As Integer = 12
 
#Region "Private members"
 
    Private Property FormInitialized() As Boolean
        Get
            Dim storedValue As Object = ViewState("FormInitialized")
            If storedValue IsNot Nothing Then
                Return CBool(storedValue)
            End If
 
            Return False
        End Get
 
        Set(ByVal value As Boolean)
            ViewState("FormInitialized") = value
        End Set
    End Property
 
    Private _mode As BookingRequestAdvancedFormAdvancedFormMode = BookingRequestAdvancedFormAdvancedFormMode.Insert
 
#End Region
 
#Region "Protected properties"
 
    Protected ReadOnly Property Owner() As RadScheduler
        Get
            Return Appointment.Owner
        End Get
    End Property
 
    Protected ReadOnly Property Appointment() As Appointment
        Get
            Dim container As SchedulerFormContainer = DirectCast(BindingContainer, SchedulerFormContainer)
            Return container.Appointment
        End Get
    End Property
 
#End Region
 
#Region "Attributes and resources"
 
    <Bindable(BindableSupport.Yes, BindingDirection.TwoWay)> _
    Public Property Description() As String
        Get
            Return DescriptionText.Text
        End Get
 
        Set(ByVal value As String)
            DescriptionText.Text = value
        End Set
    End Property
 
    <Bindable(BindableSupport.Yes, BindingDirection.TwoWay)> _
    Public Property ActivityID() As String
        Get
            Return ResActivity.Value.ToString
        End Get
 
        Set(ByVal value As String)
            If value <> "" Then
                ResActivity.Value = CInt(value)
            Else
                ResActivity.Value = ""
            End If
        End Set
    End Property
 
    <Bindable(BindableSupport.Yes, BindingDirection.TwoWay)> _
    Public Property StatusID() As String
        Get
            Return ResStatus.Value.ToString
        End Get
 
        Set(ByVal value As String)
            If value <> "" Then
                ResStatus.Value = CChar(value)
            End If
        End Set
    End Property
 
    <Bindable(BindableSupport.Yes, BindingDirection.TwoWay)> _
    Public Property EnvironmentID() As String
        Get
            Return ResEnvironment.Value.ToString
        End Get
 
        Set(ByVal value As String)
            If value <> "" Then
                ResEnvironment.Value = CInt(value)
            Else
                '                ResEnvironment.Value = ""
            End If
        End Set
    End Property
 
    <Bindable(BindableSupport.Yes, BindingDirection.TwoWay)> _
    Public Property ContactNetworkID() As String
        Get
            Return txtContactPersonUserID.Text
        End Get
 
        Set(ByVal value As String)
            txtContactPersonUserID.Text = value.ToString
        End Set
    End Property
 
    <Bindable(BindableSupport.Yes, BindingDirection.TwoWay)> _
    Public Property ContactEMail() As String
        Get
            Return txtContactPersonEMail.Text
        End Get
 
        Set(ByVal value As String)
            txtContactPersonEMail.Text = value.ToString
        End Set
    End Property
 
    <Bindable(BindableSupport.Yes, BindingDirection.TwoWay)> _
    Public Property ContactName() As String
        Get
            Return txtContactPersonName.Text
        End Get
 
        Set(ByVal value As String)
            txtContactPersonName.Text = value.ToString
        End Set
    End Property
 
    <Bindable(BindableSupport.Yes, BindingDirection.TwoWay)> _
    Public Property ContactPhoneNumber() As String
        Get
            Return txtContactPersonPhoneNumber.Text
        End Get
 
        Set(ByVal value As String)
            txtContactPersonPhoneNumber.Text = value.ToString
        End Set
    End Property
#End Region
 
#Region "Public properties"
 
    Public Property Mode() As BookingRequestAdvancedFormAdvancedFormMode
        Get
            Return _mode
        End Get
        Set(ByVal value As BookingRequestAdvancedFormAdvancedFormMode)
            _mode = value
        End Set
    End Property
 
    <Bindable(BindableSupport.Yes, BindingDirection.TwoWay)> _
    Public Property Subject() As String
        Get
            Return SubjectText.Text
        End Get
 
        Set(ByVal value As String)
            SubjectText.Text = value
        End Set
    End Property
 
    <Bindable(BindableSupport.Yes, BindingDirection.TwoWay)> _
    Public Property Start() As DateTime
        Get
            Dim result As DateTime = StartDate.SelectedDate.Value.Date
 
            If AllDayEvent.Checked Then
                result = result.Date
            Else
                Dim time As TimeSpan = StartTime.SelectedDate.Value.TimeOfDay
                result = result.Add(time)
            End If
 
            Return Owner.DisplayToUtc(result)
        End Get
 
        Set(ByVal value As DateTime)
            StartDate.SelectedDate = Owner.UtcToDisplay(value)
            StartTime.SelectedDate = Owner.UtcToDisplay(value)
        End Set
    End Property
 
    <Bindable(BindableSupport.Yes, BindingDirection.TwoWay)> _
    Public Property [End]() As DateTime
        Get
            Dim result As DateTime = EndDate.SelectedDate.Value.Date
 
            If AllDayEvent.Checked Then
                result = result.Date.AddDays(1)
            Else
                Dim time As TimeSpan = EndTime.SelectedDate.Value.TimeOfDay
                result = result.Add(time)
            End If
 
            Return Owner.DisplayToUtc(result)
        End Get
 
        Set(ByVal value As DateTime)
            EndDate.SelectedDate = Owner.UtcToDisplay(value)
            EndTime.SelectedDate = Owner.UtcToDisplay(value)
        End Set
    End Property
 
    <Bindable(BindableSupport.Yes, BindingDirection.TwoWay)> _
    Public Property RecurrenceRuleText() As String
        Get
            If RadCalendarRecurring.SelectedDates.Count > 0 Then
                Dim RepeatDates() As Date
 
                RepeatDates = RadCalendarRecurring.SelectedDates.ToArray
 
                Return String.Join("~", RepeatDates.ToList().ConvertAll(Of String)(Function(I) I.ToString).ToArray)
            End If
 
            Return String.Empty
        End Get
 
        Set(ByVal value As String)
            Dim rrule As RecurrenceRule
            RecurrenceRule.TryParse(value, rrule)
 
            If value IsNot Nothing AndAlso value <> "" Then
                Dim SelectedDates = value.Split("~"c).ToList().ConvertAll(Of RadDate)(Function(I) New RadDate(CDate(I)))
                RadCalendarRecurring.SelectedDates.AddRange(SelectedDates.ToArray)
 
                OriginalRecurrenceRule.Value = value
            End If
        End Set
    End Property
#End Region
 
    Private Sub SetupComboBoxes()
        SubjectText.WebServiceSettings.Path = SystemInterface.GetProjectServicePath()
    End Sub
 
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
        If Mode = BookingRequestAdvancedFormAdvancedFormMode.Edit Then
            UpdateButton.CommandName = "Update"
        Else
            UpdateButton.CommandName = "Insert"
        End If
        SubmitButton.CommandName = UpdateButton.CommandName
 
        InitializeStrings()
 
        If Not FormInitialized Then
            UpdateResetExceptionsVisibility()
            SetupComboBoxes()
        End If
    End Sub
 
    Private Sub SetAvailableControls()
        SetReadOnly(True)
 
        ' Make the form editable for the contact person
        If ((Security.GetLoggedOnUser.ToUpper = ContactNetworkID.ToUpper Or ContactNetworkID = "") And _
            StatusID = Status.STATUS_PENDING_SUBMIT) _
            Then
            SetReadOnly(False)
        End If
    End Sub
 
    Protected Overloads Overrides Sub OnPreRender(ByVal e As EventArgs)
        MyBase.OnPreRender(e)
 
        If Not FormInitialized Then
            If IsAllDayAppointment(Appointment) Then
                EndDate.SelectedDate = EndDate.SelectedDate.Value.AddDays(-1)
            End If
 
            FormInitialized = True
 
            RemoveBlankActivity(DirectCast(ResActivity.FindControl("ResourceValue"), RadComboBox))
            RemoveBlankActivity(DirectCast(ResEnvironment.FindControl("ResourceValue"), RadComboBox))
            SetDefaultStatusOption(DirectCast(ResStatus.FindControl("ResourceValue"), RadComboBox))
        End If
 
        SetAvailableControls()
        '  InitializeRecurrenceEditor()
    End Sub
 
    Protected Sub BasicControlsPanel_DataBinding(ByVal sender As Object, ByVal e As EventArgs)
        If Mode = BookingRequestAdvancedFormAdvancedFormMode.Insert Then
            ' Set the default values for new entries
            AllDayEvent.Checked = False
 
            Appointment.Start = Now.Date.AddHours(DEFAULT_START_TIME)
            Appointment.End = Appointment.Start.AddHours(DEFAULT_DURATION)
 
            Start = Appointment.Start
            [End] = Appointment.End
        End If
        AllDayEvent.Checked = IsAllDayAppointment(Appointment)
        chkRecurring.Checked = RecurrenceRuleText <> String.Empty
    End Sub
 
    Protected Sub DurationValidator_OnServerValidate(ByVal source As Object, ByVal args As ServerValidateEventArgs) Handles DurationValidator.ServerValidate
        args.IsValid = ([End] - Start) > TimeSpan.Zero
    End Sub
 
    Protected Sub ResetExceptions_OnClick(ByVal sender As Object, ByVal e As EventArgs)
        Owner.RemoveRecurrenceExceptions(Appointment)
        OriginalRecurrenceRule.Value = Appointment.RecurrenceRule
        ResetExceptions.Text = Owner.Localization.AdvancedDone
    End Sub
 
#Region "Private methods"
    Private Sub RemoveBlankActivity(ByVal cboActivity As RadComboBox)
        Dim BlankOption As RadComboBoxItem
 
        BlankOption = cboActivity.Items.FindItemByValue("NULL")
        If Not BlankOption Is Nothing Then
            cboActivity.Items.Remove(BlankOption)
        End If
    End Sub
 
    Private Sub SetDefaultStatusOption(ByVal cboStatus As RadComboBox)
        If Mode = BookingRequestAdvancedFormAdvancedFormMode.Edit Then
            cboStatus.SelectedIndex = cboStatus.Items.FindItemByText(Status.GetDescription(StatusID)).Index
        Else
            cboStatus.SelectedIndex = cboStatus.Items.FindItemByText(Status.GetDescription(Status.STATUS_PENDING_SUBMIT)).Index
        End If
 
        cboStatus.Enabled = False
    End Sub
 
    Private Sub InitializeStrings()
        AllDayEvent.Text = Owner.Localization.AdvancedAllDayEvent
 
        StartDateValidator.ErrorMessage = Owner.Localization.AdvancedStartDateRequired
        StartDateValidator.ValidationGroup = Owner.ValidationGroup
 
        StartTimeValidator.ErrorMessage = Owner.Localization.AdvancedStartTimeRequired
        StartTimeValidator.ValidationGroup = Owner.ValidationGroup
 
        EndDateValidator.ErrorMessage = Owner.Localization.AdvancedEndDateRequired
        EndDateValidator.ValidationGroup = Owner.ValidationGroup
 
        EndTimeValidator.ErrorMessage = Owner.Localization.AdvancedEndTimeRequired
        EndTimeValidator.ValidationGroup = Owner.ValidationGroup
 
        DurationValidator.ErrorMessage = "(end less than start time)"
        DurationValidator.ValidationGroup = Owner.ValidationGroup
 
        ResetExceptions.Text = Owner.Localization.AdvancedReset
 
        SharedCalendar.FastNavigationSettings.OkButtonCaption = Owner.Localization.AdvancedCalendarOK
        SharedCalendar.FastNavigationSettings.CancelButtonCaption = Owner.Localization.AdvancedCalendarCancel
        SharedCalendar.FastNavigationSettings.TodayButtonCaption = Owner.Localization.AdvancedCalendarToday
    End Sub
 
    'Private Sub InitializeRecurrenceEditor()
    '    AppointmentRecurrenceEditor.SharedCalendar = SharedCalendar
    '    AppointmentRecurrenceEditor.Culture = Owner.Culture
    '    AppointmentRecurrenceEditor.StartDate = Appointment.Start
    '    AppointmentRecurrenceEditor.EndDate = Appointment.End
    'End Sub
 
    Private Sub UpdateResetExceptionsVisibility()
        If String.IsNullOrEmpty(Owner.WebServiceSettings.Path) Then
            ResetExceptions.Visible = False
            Dim rrule As RecurrenceRule = RecurrenceRule.Empty
            If RecurrenceRule.TryParse(Appointment.RecurrenceRule, rrule) Then
                ResetExceptions.Visible = rrule.Exceptions.Count > 0
            End If
        End If
    End Sub
 
    Private Function IsAllDayAppointment(ByVal appointment As Appointment) As Boolean
        Dim displayStart As DateTime = Owner.UtcToDisplay(appointment.Start)
        Dim displayEnd As DateTime = Owner.UtcToDisplay(appointment.[End])
        Return displayStart.CompareTo(displayStart.[Date]) = 0 AndAlso displayEnd.CompareTo(displayEnd.[Date]) = 0
    End Function
 
    Private Sub LookupContactValues()
        Dim UserDetails As ADUser
 
        ' Lookup all relevant information for the given userid
        UserDetails = ADUser.PerformADSearch(txtContactPersonUserID.Text.Trim)
 
        ' If details were found, populate the form as best we can
        If UserDetails.Name.Length <> 0 Then
            txtContactPersonEMail.Text = UserDetails.Email
            txtContactPersonName.Text = UserDetails.Name & " " & UserDetails.Surname
            txtContactPersonPhoneNumber.Text = UserDetails.Telephone
        End If
    End Sub
 
    Private Sub SetReadOnly(ByVal DisableControls As Boolean)
        txtContactPersonEMail.ReadOnly = DisableControls
        txtContactPersonName.ReadOnly = DisableControls
        txtContactPersonPhoneNumber.ReadOnly = DisableControls
        txtContactPersonUserID.ReadOnly = DisableControls
        SubjectText.Enabled = Not DisableControls
        CheckIDButton.Enabled = Not DisableControls
        StartDate.Enabled = Not DisableControls
        EndDate.Enabled = Not DisableControls
        AllDayEvent.Enabled = Not DisableControls
        SubmitButton.Enabled = Not DisableControls
        UpdateButton.Enabled = Not DisableControls
        DescriptionText.ReadOnly = DisableControls
        '   AppointmentRecurrenceEditor.Enabled = Not DisableControls
 
        DirectCast(ResEnvironment.FindControl("ResourceValue"), RadComboBox).Enabled = Not DisableControls
        DirectCast(ResActivity.FindControl("ResourceValue"), RadComboBox).Enabled = Not DisableControls
    End Sub
#End Region
 
    Protected Sub SubmitButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles SubmitButton.Click
        Page.Validate()
 
        If Page.IsValid Then
            StatusID = Status.STATUS_PENDING_APPROVAL
        End If
    End Sub
 
    Protected Sub CheckIDButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles CheckIDButton.Click
        If txtContactPersonUserID.Text.Trim <> "" Then
            LookupContactValues()
        End If
    End Sub
 
    Private Sub UpdateButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles UpdateButton.Click
        Page.Validate()
    End Sub
End Class
0
Andre Myburgh
Top achievements
Rank 1
answered on 17 Jan 2014, 04:54 AM
With the stack trace as follows (AdvancedForm.ascx.vb is the advanced edit form posted in the previous reply): 

   at Chronos.BookingRequestAdvancedFormAdvancedForm.get_Owner() in C:\Source\Chronos\Chronos\Controls\AdvancedForm.ascx.vb:line 43
   at Chronos.BookingRequestAdvancedFormAdvancedForm.InitializeStrings() in C:\Source\Chronos\Chronos\Controls\AdvancedForm.ascx.vb:line 345
   at Chronos.BookingRequestAdvancedFormAdvancedForm.Page_Load(Object sender, EventArgs e) in C:\Source\Chronos\Chronos\Controls\AdvancedForm.ascx.vb:line 261
   at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
   at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
   at System.Web.UI.Control.OnLoad(EventArgs e)
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Control.AddedControl(Control control, Int32 index)
   at System.Web.UI.ControlCollection.Add(Control child)
   at System.Web.UI.Control.AddParsedSubObject(Object obj)
   at System.Web.UI.Control.System.Web.UI.IParserAccessor.AddParsedSubObject(Object obj)
   at ASP.forms_bookingoverview_aspx.__BuildControl__control12(Control __ctrl) in C:\Source\Chronos\Chronos\Forms\BookingOverview.aspx:line 80
   at System.Web.UI.CompiledBindableTemplateBuilder.InstantiateIn(Control container)
   at Telerik.Web.UI.RadScheduler.CreateChildControls(Boolean bindFromDataSource)
   at Telerik.Web.UI.RadScheduler.CreateChildControls()
   at System.Web.UI.Control.EnsureChildControls()
   at System.Web.UI.Control.PreRenderRecursiveInternal()
   at System.Web.UI.Control.PreRenderRecursiveInternal()
   at System.Web.UI.Control.PreRenderRecursiveInternal()
   at System.Web.UI.Control.PreRenderRecursiveInternal()
   at System.Web.UI.Control.PreRenderRecursiveInternal()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
0
Boyan Dimitrov
Telerik team
answered on 21 Jan 2014, 03:15 PM
Hello,

Please refer to our code library help resource that shows how you use the advanced form as a complete separate user control. It does provide a template projects for server-side and web service binding in both C# and VB.

Regards,
Boyan Dimitrov
Telerik
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to the blog feed now.
Tags
Scheduler
Asked by
Andre Myburgh
Top achievements
Rank 1
Answers by
Boyan Dimitrov
Telerik team
Andre Myburgh
Top achievements
Rank 1
Share this question
or