Kendo Scheduler Recurrence Rule Causes DatePickers to Retain or Display Incorrect Values Across Views

3 Answers 24 Views
DatePicker DateTimePicker Scheduler
alayo
Top achievements
Rank 1
Iron
alayo asked on 14 Oct 2025, 09:06 PM | edited on 14 Oct 2025, 09:11 PM
I’m working on a legacy ASP.NET MVC application that leverages a custom Kendo Scheduler view (TestScheduler, extending Scheduler<ISchedulerEvent>).

We’ve noticed a recurring issue when editing recurring event series. Kendo DatePickers in the custom popup editor or other views end up displaying incorrect or “sticky” values, even though the underlying <input> element shows the correct value.

The CustomInput have multiple datefields like below, but all DateFields seems to be prefilled by the date cpart of the recurrence rule. This seems to also prefill all other DateFields in the page that use DatePicker component. 


Observed Behavior

When editing a recurring series (with a RecurrenceRule like below):

DTSTART;TZID=Europe/London:20240626T090000
DTEND;TZID=Europe/London:20240626T170000
RRULE:FREQ=WEEKLY;BYDAY=TU

Question

  • Is this behavior expected when RecurrenceRule is applied, i.e., does Kendo’s Scheduler reuse a shared RecurrenceEditor instance or observable model across views?

Here's the sample code that is used while editing a schedule


<div id="DivMainContent" class="content-region">
    <div class="popup-box-head accent-colour-background clearfix">
        <div class="box-title normal-text left">
            Select Start and End Times
        </div>
        <div class="button-funcs right">
            <a href="javascript:void(0);" title="Save" id="repair-manage-diary-difference-btnadd">
                Save
            </a> | <a href="javascript:void(0);" title="Close" class="close">Close</a>
        </div>
    </div>
    <div class="popup-box-main fieldset start-end-popup">
<form action="/read/data" id="manage-diary-difference-new-frm" method="post"><input data-val="true" data-val-required="The DiaryDetailId field is required." id="DiaryDetailId" name="DiaryDetailId" type="hidden" value="152" /><input id="Timestamp" name="Timestamp" type="hidden" value="AAAAAAADEjI=" /><input id="TimestampString" name="TimestampString" type="hidden" value="AAAAAAADEjI=" /><input data-val="true" data-val-required="The Id field is required." id="OwnerDiary_Id" name="OwnerDiary.Id" type="hidden" value="25" /><input id="ParentCalendar_TimestampString" name="ParentCalendar.TimestampString" type="hidden" value="AAAAAAACldk=" /><input data-val="true" data-val-required="The CalendarId field is required." id="ParentCalendar_CalendarId" name="ParentCalendar.CalendarId" type="hidden" value="3" /><input data-val="true" data-val-required="The MondayWorking field is required." id="ParentCalendar_MondayWorking" name="ParentCalendar.MondayWorking" type="hidden" value="True" /><input data-val="true" data-val-required="The TuesdayWorking field is required." id="ParentCalendar_TuesdayWorking" name="ParentCalendar.TuesdayWorking" type="hidden" value="True" /><input data-val="true" data-val-required="The WednesdayWorking field is required." id="ParentCalendar_WednesdayWorking" name="ParentCalendar.WednesdayWorking" type="hidden" value="True" /><input data-val="true" data-val-required="The ThursdayWorking field is required." id="ParentCalendar_ThursdayWorking" name="ParentCalendar.ThursdayWorking" type="hidden" value="True" /><input data-val="true" data-val-required="The FridayWorking field is required." id="ParentCalendar_FridayWorking" name="ParentCalendar.FridayWorking" type="hidden" value="True" /><input data-val="true" data-val-required="The SaturdayWorking field is required." id="ParentCalendar_SaturdayWorking" name="ParentCalendar.SaturdayWorking" type="hidden" value="False" /><input data-val="true" data-val-required="The SundayWorking field is required." id="ParentCalendar_SundayWorking" name="ParentCalendar.SundayWorking" type="hidden" value="False" />            <div id="error-diary-difference-overlap">
                <span id="error-lable-manage-diary-difference-overlap" class="k-invalid-msg-custom">
                </span>
            </div>
            <div class="line clearfix">
                <label for="day-selected" class="field-text">
                    Select Day
                </label>
                <div class="fieldform">

                    <input data-uid="c0a5911c-7f0b-4e73-ba95-eaa9f2f733f2" data-val="true" data-val-range="Please enter Day" data-val-range-max="6" data-val-range-min="0" id="SelectedDays" name="SelectedDays" type="text" value="5" /><script>
	kendo.syncReady(function(){jQuery("[data-uid='c0a5911c-7f0b-4e73-ba95-eaa9f2f733f2']").kendoDropDownList({"change":NameSpace.RepairManageTimeSlots.ChangeWorkingDay,"dataSource":[{"Key":1,"Value":"Monday"},{"Key":2,"Value":"Tuesday"},{"Key":3,"Value":"Wednesday"},{"Key":4,"Value":"Thursday"},{"Key":5,"Value":"Friday"}],"animation":false,"dataTextField":"Value","height":300,"autoBind":true,"dataValueField":"Key","rounded":"null"});});
</script>

                </div>
            </div>
            <div class="line clearfix">
                <label for="start-time" class="field-text">
                    Start Time
                </label>
                <div>
                    <input data-val="true" data-val-required="Please enter Start time" id="StartTime" name="StartTime" type="text" value="00:00" /><script>
	kendo.syncReady(function(){jQuery("#StartTime").kendoTimePicker({"format":"HH:mm","min":new Date(2025,9,14,0,0,0,0),"max":new Date(2025,9,14,0,0,0,0),"interval":15});});
</script>
                    <span class="field-validation-valid" data-valmsg-for="StartTime" data-valmsg-replace="true"></span>
                </div>
            </div>
            <div class="line clearfix">
                <label for="end-time" class="field-text">
                    End Time
                </label>
                <div>
                    <input data-val="true" data-val-required="Please enter end time" id="EndTime" name="EndTime" type="text" value="23:59" /><script>
	kendo.syncReady(function(){jQuery("#EndTime").kendoTimePicker({"format":"HH:mm","min":new Date(2025,9,14,0,0,0,0),"max":new Date(2025,9,14,0,0,0,0),"interval":15});});
</script>
                    <span class="field-validation-valid" data-valmsg-for="EndTime" data-valmsg-replace="true"></span>
                </div>
            </div>
            <div class="line clearfix">
                    <label for="effective-from" class="field-text">
                        Effective from
                    </label>
                    <div class="fieldform">
                        <input data-val="true" data-val-required="Please enter Effective from" endDatePicker="EffectiveToDate" id="EffectiveFromDate" name="EffectiveFromDate" type="text" value="Wed, Oct 15 2025" /><script>
	kendo.syncReady(function(){jQuery("#EffectiveFromDate").kendoDatePicker({"change":NameSpace.RepairManageDiaryDifferences.startChangeCalendar,"open":Helpers.DatePicker.calendarOpen,"format":"ddd, MMM dd yyyy","parseFormats":["dd/MM/yyyy","ddd, MMM dd yyyy"],"min":new Date(1900,0,1,0,0,0,0),"max":new Date(2099,11,31,0,0,0,0)});});
</script>
                        <span class="field-validation-valid" data-valmsg-for="EffectiveFromDate" data-valmsg-replace="true"></span>
                    </div>
                </div>
            <div class="line clearfix">
                    <label for="effective-to" class="field-text">
                        Effective to
                    </label>
                    <div class="fieldform">
                        <input id="EffectiveToDate" name="EffectiveToDate" startDatePicker="EffectiveFromDate" type="text" value="Tue, Oct 21 2025" /><script>
	kendo.syncReady(function(){jQuery("#EffectiveToDate").kendoDatePicker({"change":NameSpace.RepairManageDiaryDifferences.endChangeCalendar,"open":Helpers.DatePicker.calendarOpen,"format":"ddd, MMM dd yyyy","parseFormats":["dd/MM/yyyy","ddd, MMM dd yyyy"],"min":new Date(1900,0,1,0,0,0,0),"max":new Date(2099,11,31,0,0,0,0)});});
</script>
                        <span class="field-validation-valid" data-valmsg-for="EffectiveToDate" data-valmsg-replace="true"></span>
                    </div>
                </div>
            <div class="line clearfix">
                <label for="effective-to-date" class="field-text">
                    Effective to date js
                </label>
                <div class="fieldform">
                    <input id="TestDate" name="TestDate" type="text" />
                    <script>
                        kendo.syncReady(function () {
                            jQuery("#TestDate").kendoDatePicker({
                                "format": "ddd, MMM dd yyyy",
                                "parseFormats": ["dd/MM/yyyy", "ddd, MMM dd yyyy"],
                                "min": new Date(1900, 0, 1, 0, 0, 0, 0),
                                "max": new Date(2099, 11, 31, 0, 0, 0, 0),
                                "change": function (e) {
                                    console.log("On Change of date picker");
                                    console.log(e);
                                    e.preventDefaut();
                                    var value = this.value();
                                    console.log(value);
                                }
                            });
                        });
                    </script>
                    <span class="field-validation-valid" data-valmsg-for="TestDate" data-valmsg-replace="true"></span>
                </div>
            </div>
            <div class="line clearfix">
                <label for="notes" class="field-text">
                    Comments
                </label>
                <div class="fieldform">
                    <input id="Notes" name="Notes" type="text" value="" />
                </div>
            </div>
</form>    </div>
</div>
<div id="DivMessage_AppointmentOutsite" style="display: none" class="content-region">
    <div class="popup-box-head accent-colour-background clearfix">
        <div class="box-title normal-text left">
            Confirm
        </div>
        <div class="button-funcs right">
            <a id="btnClose-appointmentOutside" href="javascript:void(0);" title="Close">Close</a>
        </div>
    </div>
    <div id="message-content" class="popup-box-content">Message.</div>
    <div class="YNButton clearfix" id="buttons-message">
        <button id='btnOk-appointmentOutside' type="button" title="Ok" class="active-background active-text">
            Ok
        </button>
    </div>
</div>

<div id='hiddenDiv1760456443763' style='display:none'></div>





3 Answers, 1 is accepted

Sort by
0
Anton Mironov
Telerik team
answered on 17 Oct 2025, 06:32 AM

Hi Alayo,

This behavior is not expected by design. The Kendo Scheduler does not reuse a shared RecurrenceEditor instance or observable model across different editor popups or views. Each editor should maintain its own state, and the recurrence rule should only affect the relevant fields for the event being edited.

If all DatePickers are being prefilled with the date part of the recurrence rule, this usually indicates that:

  • The initialization logic for your editors is sharing data or observable objects between instances.
  • The same value or model is set for multiple DatePicker components unintentionally.

To avoid this, ensure each DatePicker in your popup editor is initialized with a unique name and ID, and that the values are set explicitly based on the event data. For example:

function onEditPopupOpen(eventData) {
    $("#EffectiveFromDate").data("kendoDatePicker").value(eventData.effectiveFromDate);
    $("#EffectiveToDate").data("kendoDatePicker").value(eventData.effectiveToDate);
    $("#TestDate").data("kendoDatePicker").value(null); // Reset if not used for this event
}

Please check if you are sharing the same observable or object reference when initializing your DatePickers, and confirm that you reset or set the values for each field when opening the editor.

 

    Kind Regards,
    Anton Mironov
    Progress Telerik

    Your perspective matters! Join other professionals in the State of Designer-Developer Collaboration 2025: Workflows, Trends and AI survey to share how AI and new workflows are impacting collaboration, and be among the first to see the key findings.
    Start the 2025 Survey
    0
    alayo
    Top achievements
    Rank 1
    Iron
    answered on 17 Oct 2025, 06:55 AM
    Thanks Anton, I have looked into this over the past few days, and made some progress on it. 

    First, None of the affected DatePicker components have the same ID/Name. They just seems to share the same state upon mounted.

    I have been able to fix the Modal issue when editing a Scheduler Event, By plugging in into the event data in the Edit Event handler and forcing an overwrite on the component. 

    But that doesn't fix the issue on other pages being mounted (basically inserted in the active DOM like a SPA app), as it seems to be picking the data from the global context and applies it to all Date component 

    This is the sample code for the Modal fix 
      var schedulerEventModel = e.event;
      console.log(schedulerEventModel);
    
      // Get the Kendo DatePicker instances in your modal
      var effectiveFromPicker = $("#EffectiveFromDate").getKendoDatePicker();
      var effectiveToPicker = $("#EffectiveToDate").getKendoDatePicker();
    
      // Manually set the values of the Kendo DatePickers
      // Use the correct camelCase property names from your Scheduler Model
      if (schedulerEventModel) {
          if (effectiveFromPicker && schedulerEventModel.EffectiveFromDate) {
              console.log('Setting Effective from Date to => ' + schedulerEventModel.EffectiveFromDate);
              effectiveFromPicker.value(schedulerEventModel.EffectiveFromDate);
          }
    
          if (effectiveToPicker && schedulerEventModel.EffectiveToDate) {
              console.log('Setting Effective to Date to => ' + schedulerEventModel.EffectiveToDate);
              effectiveToPicker.value(schedulerEventModel.EffectiveToDate);
          }
      }
    Is there a way to check for an existence of a key (EffectiveFromDate) in the Global observable object as that seems to be the value they're all binded too. 
    alayo
    Top achievements
    Rank 1
    Iron
    commented on 17 Oct 2025, 09:12 AM

    Here's the initialization logic if that helps


       @(Html.Kendo().Scheduler<NameSpace.Housing.Cx.Repair.Contracts.Web.ViewModels.TestRepairDiaryTimeSlotsViewModel>()
                                                     .StartTime(DateTime.Now.Date)
                                                     .EndTime(DateTime.Now.Date.AddDays(31))
                                                     .ShowWorkHours(true)
                                                     .Events(e => e.ResizeEnd("NameSpace.RepairManageTimeSlots.ResizeEnd")
                                                     .MoveEnd("NameSpace.RepairManageTimeSlots.MoveEnd").Edit("NameSpace.RepairManageTimeSlots.EditTimeSlot")
                                                     .Resize("NameSpace.RepairManageTimeSlots.Resize")
                                                     .Move("NameSpace.RepairManageTimeSlots.Move").Remove("NameSpace.RepairManageTimeSlots.RemoveTimeSlot").DataBound("NameSpace.RepairManageTimeSlots.TimeSlotSchedulerDataBound"))
                                                     .DataSource(d => d
                                                     .Model(m =>
                                                     {
                                                         m.Field(f => f.Title).DefaultValue("No title");
                                                         m.Id(f => f.Id);
                                                         m.Field(f => f.RecurrenceException).DefaultValue("");
                                                         m.Field(f => f.Start);
                                                         m.Field(f => f.End);
                                                         m.Field(f => f.RecurrenceRule);
                                                         m.Field(f => f.RecurrenceId);
                                                         m.Field(f => f.IsAllDay);
                                                         m.Field(f => f.EffectiveFromDate);
                                                         m.Field(f => f.EffectiveToDate).DefaultValue(DateTime.Now);
                                                     })
                                                     .Read(r => r.Action("Read", "RepairManageDiarySlots", new {diaryId = 25}))
                                                     .Destroy("Destroy", "RepairConfigCalendar"))
                                                     .Editable(e => e.Confirmation(false))
                                                     .Resources(resource => resource.Add(m => m.OwnerId)
                                                         .Title("Owner")
                                                         .DataTextField("Text")
                                                         .DataValueField("Value")
                                                         .DataColorField("Color")
                                                         .BindTo(new[] {
                                                          new { Text = "", Value = 150, Color = "#DCDCDC"}
                                                         }))
                                                     .Name("RepairDiaryTimeSlotsViewModelScheduler")
                                                     .Views(views =>
                                                     {
                                                         views.DayView();
                                                         views.WeekView(m => m.Selected(true));
                                                     })
                                                     .Timezone("Europe/London")
                                                     .Date(DateTime.Now.Date)
                                                     .DateHeaderTemplate("<span class='k-link k-nav-day'>#=kendo.toString(date, 'ddd  dd/MM')#</span>")
                                                     .MajorTimeHeaderTemplate("<div class='schedule-tick'>#=kendo.toString(date, 'HH:mm')#</div>"))

    0
    Anton Mironov
    Telerik team
    answered on 21 Oct 2025, 07:17 AM

    Hello Alayo,

    Thank you for the additional details provided.

    You can check for the existence of a property like EffectiveFromDate in a global observable object using standard JavaScript:

    if ("EffectiveFromDate" in globalObservableObject) {
        // Property exists
    }
    

    Or, to ensure the value is not null or undefined:

    if (globalObservableObject.EffectiveFromDate != null) {
        // Property exists and is not null
    }
    

    If you are using a Kendo observable (created via kendo.observable), you can use:

    if (globalObservableObject.get("EffectiveFromDate") != null) {
        // Property exists and is not null
    }
    

    However, based on your description, it sounds like the main issue is that DatePickers across different pages or views are sharing state due to binding to a global object. This can lead to unintended value propagation between components.

    To help resolve this:

    • Consider using local, view-specific observables or models for each page/component, rather than a global one.
    • Ensure that each DatePicker is initialized and bound only to the relevant data for its context.
    • Double-check if any global event handlers or model updates are affecting all DatePickers at once.
    • If you are using a SPA-like setup, make sure to reset or re-initialize DatePicker values when mounting new views.

    As this is a custom implementation, I would recommend contacting the Professional Services Team for additional assistance.

     

      Best Regards,
      Anton Mironov
      Progress Telerik

      Your perspective matters! Join other professionals in the State of Designer-Developer Collaboration 2025: Workflows, Trends and AI survey to share how AI and new workflows are impacting collaboration, and be among the first to see the key findings.
      Start the 2025 Survey
      alayo
      Top achievements
      Rank 1
      Iron
      commented on 21 Oct 2025, 07:48 AM

      Thanks @anton. I will work with the suggestion above, Though I noticed the issue stopped happening when I commented out this code from the kendo.scheduler.js script. That can help aid my investigation onwards


       that.editable = container.kendoEditable({
              fields: editableFields,
              model: model,
              clearContainer: false,
              validateOnBlur: true,
              target: that.options.target
          }).data("kendoEditable");
      
          for (var field in editableFields) {
              if (editableFields[field].field !== "recurrenceRule") {
                  fieldName = editableFields[field].field;
                  container.find("[name='" + fieldName + "']").attr("aria-labelledby", fieldName + "_label");
              }
          }

      Anton Mironov
      Telerik team
      commented on 23 Oct 2025, 05:55 AM

      Hi Alayo,

      This is great - I am glad to hear the issue is now not represented.

      Please note all the extensions of the widgets and components are not recommended. All the customizations are usually covered by the Telerik Professional Services Team.

      Best Regards,
      Anton Mironov

      Tags
      DatePicker DateTimePicker Scheduler
      Asked by
      alayo
      Top achievements
      Rank 1
      Iron
      Answers by
      Anton Mironov
      Telerik team
      alayo
      Top achievements
      Rank 1
      Iron
      Share this question
      or