Series vs Occurance problem

7 posts, 0 answers
  1. Andre Myburgh
    Andre Myburgh avatar
    7 posts
    Member since:
    Oct 2009

    Posted 27 Dec 2013 Link to this post

    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.

  2. Boyan Dimitrov
    Admin
    Boyan Dimitrov avatar
    1746 posts

    Posted 02 Jan 2014 Link to this post

    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.
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Andre Myburgh
    Andre Myburgh avatar
    7 posts
    Member since:
    Oct 2009

    Posted 02 Jan 2014 Link to this post

    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
  5. Boyan Dimitrov
    Admin
    Boyan Dimitrov avatar
    1746 posts

    Posted 07 Jan 2014 Link to this post

    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.
  6. Andre Myburgh
    Andre Myburgh avatar
    7 posts
    Member since:
    Oct 2009

    Posted 16 Jan 2014 Link to this post

    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
  7. Andre Myburgh
    Andre Myburgh avatar
    7 posts
    Member since:
    Oct 2009

    Posted 16 Jan 2014 Link to this post

    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)
  8. Boyan Dimitrov
    Admin
    Boyan Dimitrov avatar
    1746 posts

    Posted 21 Jan 2014 Link to this post

    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.
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017