RadScheduler displaying appointments in wrong locations

8 posts, 0 answers
  1. Graham
    Graham avatar
    41 posts
    Member since:
    Feb 2011

    Posted 30 Dec 2016 Link to this post

    We have a problem with RadScheduler when an appointment is dragged.

    The attached RadScheduler1.jpg shows our screen before a drag/drop is done. The appointment to be moved is highlighted in red.

    The intention is that we drag this appointment over to 12 December.

    RadScheduler2.jpg shows what happens while the drag is in progress. The mouse NSEW cursor is actually located over the 12 December cell, yet the appointment position is way out of step with the mouse position and appears on 29 November. In fact, most dragging seems to want to put the appointment on the top row. If we scroll up a bit and move the mouse down, the dragged appointment can go to the next row, but the mouse cursor is off the bottom of the scheduler cells, although it is still within the scheduler.

    Upon dropping, the appointment drops where the mouse is, so it appears that it is out of place during the drag. When it has dropped, it looses its background colour (which we set in OnAppointmentDataBound) and appears grey.

    This is some of our code:

            protected void radScheduler_OnAppointmentDataBound(object sender, SchedulerEventArgs e) {
                CustomEvent customEvent = (CustomEvent)e.Appointment.DataItem;
                
                e.Appointment.BackColor = System.Drawing.Color.FromArgb( Convert.ToInt32("0x" + customEvent.Colour, 16));
                e.Appointment.ToolTip = customEvent.Description.Replace("<br/>", "\n");
            }

            protected void radScheduler_OnAppointmentUpdate(object sender, AppointmentUpdateEventArgs e) {

                var modifiedAppointment = e.ModifiedAppointment;

                DiaryEvent diaryEvent = omDb.FindDiaryEvent(Convert.ToInt32(modifiedAppointment.ID));
                if (diaryEvent == null) {
                    SetRecordError("DiaryEvent", Convert.ToInt32(modifiedAppointment.ID));
                    e.Cancel = true;

                } else {
                    // Check for conflicts with the new date
                    bool bGotConflicts = false;
                    ...........
                    if(!bGotConflicts) {
                        // No conflicts or not checking for conflicts, so update the appointment
                        diaryEvent.StartDateTime = modifiedAppointment.Start;
                        diaryEvent.EndDateTime = modifiedAppointment.End;
                        omDb.InsertOrUpdateDiaryEvent(diaryEvent);

                        radScheduler.Rebind();
                    }
                }
            }

    Note that we Rebind() after updating the database. This is not causing radScheduler_OnAppointmentDataBound to be called, so this probably explains why the colour is being lost.

    The above is the month view.

    The week view also seems to be full of bugs - RadScheduler3.jpg shows the 'before' with the event to be dragged marked. We drag the event across to Tue, 13 and nothing happens - the appointment does even get 'picked up' !

    These issues occur in both Edge and Chrome. We are using Telerik 2016.2.607.40.

    Our RadScheduler is defined as follows:

    <telerik:RadScheduler ID="radScheduler" runat="server" RenderMode="Lightweight" 
                                                Height="800"
                                                OnAppointmentUpdate="radScheduler_OnAppointmentUpdate"
                                                OnAppointmentDataBound="radScheduler_OnAppointmentDataBound"
                                                OnAppointmentContextMenuItemClicked="radScheduler_OnAppointmentContextMenuItemClicked"
                                                OnClientAppointmentContextMenuItemClicked="ShowProgress"
                                                OnNavigationComplete="radScheduler_OnNavigationComplete"
                                                OnClientAppointmentDoubleClick="OnClientAppointmentDoubleClick"
                                                OnClientAppointmentEditing="OnClientAppointmentEditing"
                                                RowHeight="40px"
                                                OverflowBehavior="Auto"
                                                SelectedView="WeekView" 
                                                ShowFooter="false"
                                                DayStartTime="00:00:00" DayEndTime="23:59:59"
                                                FirstDayOfWeek="Sunday"
                                                LastDayOfWeek="Saturday"
                                                EnableDescriptionField="true" 
                                                AppointmentStyleMode="Default"
                                                DataKeyField="Id"
                                                DataStartField="Start"
                                                DataEndField="End"
                                                DataSubjectField="Title"
                                                DataDescriptionField="Description"
                                                AllowInsert="false"
                                                AllowDelete="false"
                                                DayView-SlotWidth="70" DayView-HeaderDateFormat="ddd dd MMM yyyy"
                                                WeekView-SlotWidth="150" WeekView-HeaderDateFormat="ddd dd/M yyyy"
                                                MonthView-SlotWidth="200" MonthView-HeaderDateFormat="ddd dd MMM yyyy" MonthView-AdaptiveRowHeight="true"
                                                YearView-SlotWidth="250" YearView-HeaderDateFormat="MMM yyyy">
                            <DayView UserSelectable="true" />
                            <MultiDayView UserSelectable="true" />
                            <WeekView UserSelectable="true" />
                            <MonthView UserSelectable="true" />
                            <YearView UserSelectable="true" />
                            <TimelineView UserSelectable="false" />
                            <TimeSlotContextMenuSettings EnableDefault="true" />
                            <AppointmentContextMenuSettings EnableDefault="true" />
                            <AppointmentTemplate>
                                <div><%#Eval("Subject") %></div>
                                <div><%#Eval("Description") %></div>
                            </AppointmentTemplate>
                            <AppointmentContextMenus>
                                <%--The appointment context menu interaction is handled on the client in this example--%>
                                <%--See the JavaScript code above--%>
                                <telerik:RadSchedulerContextMenu runat="server" ID="SchedulerAppointmentContextMenu">
                                    <Items>
                                        <telerik:RadMenuItem Text="Edit" Value="EditSchedule"></telerik:RadMenuItem>
                                        <telerik:RadMenuItem IsSeparator="True"></telerik:RadMenuItem>
                                        <telerik:RadMenuItem Text="Resources" Value="CourseResources"></telerik:RadMenuItem>
                                        <telerik:RadMenuItem Text="Course Info" Value="CourseInfo"></telerik:RadMenuItem>
                                        <telerik:RadMenuItem Text="Course Instructors" Value="PanelInstructors"></telerik:RadMenuItem>
                                        <telerik:RadMenuItem Text="Course Trainees" Value="PanelTrainees"></telerik:RadMenuItem>
                                        <telerik:RadMenuItem Text="Support Material" Value="SupportMaterial"></telerik:RadMenuItem>
                                        <telerik:RadMenuItem Text="Course News" Value="CourseNews"></telerik:RadMenuItem>
                                        <telerik:RadMenuItem Text="Trainee Progress" Value="ViewProgress"></telerik:RadMenuItem>
                                        <telerik:RadMenuItem IsSeparator="True"></telerik:RadMenuItem>
                                        <telerik:RadMenuItem Text="Duplicate" Value="DuplicateSchedule"></telerik:RadMenuItem>
                                    </Items>
                                </telerik:RadSchedulerContextMenu>
                            </AppointmentContextMenus>
                        </telerik:RadScheduler>

    Can someone please advise what might be causing this ?

    There seems to be a serious bug with the mouse and dragged cell being completely out of step with each other. Coupled with appointments not even getting picked up by drag, and other appointments which won't seem to drag where we want them, this makes RadScheduler a rather buggy showstopper for delivering to our client. We don't appear to have any control over the functionality which is failing.

    Additional suggested improvements:

    -     Display rotator wheel when changing between views

    -     Display rotator wheel when appointment is dropped (to cover scenario of back-end server processing delay)

    -     Allow HTML is tooltips and/or make it properly template-driven

    Graham Plowman

  2. Plamen
    Admin
    Plamen avatar
    2790 posts

    Posted 01 Jan Link to this post

    Hi,

    Yes indeed when the issue is most probably caused by the way you have bound your Schedule. In cases when  DataSource property is used we recommend using a technique similar to the one in this demo and the one described in this help topic.

    As for the loading panel - you can use the AjaxManager and it will help you display it when a view is changes and an appointment is updated as it is done in the linked demo.

    Regards,
    Plamen
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  3. Graham
    Graham avatar
    41 posts
    Member since:
    Feb 2011

    Posted 02 Jan in reply to Plamen Link to this post

    Thanks Plamen,

    I have modified our code per the examples you quote:

            void DisplayEvents() {
                    radScheduler.DataSource = CalendarEvents;
            }

            List<CustomEvent> CalendarEvents {
                get {
                    viewType = radScheduler.SelectedView;
                    viewDateStart = radDateFrom1.SelectedDate.Value;
                    viewDateEnd = radDateTo1.SelectedDate.Value;
                    searchKeywords = txtSearch1.Text.Trim();
                    locationId = Convert.ToInt32(ddlLocation1.SelectedValue);
                    SaveState();
                    string tempKeyWords = "";
                    if (ddlLocation1.SelectedValue != "0") tempKeyWords = ddlLocation1.SelectedItem.Text + "|";
                    tempKeyWords += searchKeywords;
                    CMatchString matcher = new CMatchString(tempKeyWords);

                   // The following calls a stored proc on the database

                    List<CustomEvent> eventList = omDb.FindCourseScheduleViewItems(omVariables.imOrganisationId, viewDateStart, viewDateEnd, matcher.GetWordList(false), omVariables.imLanguageId)
                           .Select(task => new CustomEvent {
                               ID = task.Id.Value,
                               Start = task.StartDateTime.Value,
                               End = task.EndDateTime.Value,
                               BookingName = task.BookingName,
                               QualificationModule = task.QualificationModule,
                               Title = task.Title,
                               Instructors = task.Instructors,
                               Colour = task.Colour,
                               Location = task.Location,
                               ResourceList = task.Resources,
                               People = task.People,
                               Description = MakeToolTipText(task, true)
                           })
                        .ToList();
                    return eventList;
                }
            }

            protected void radScheduler_OnAppointmentDataBound(object sender, SchedulerEventArgs e) {
                CustomEvent customEvent = (CustomEvent)e.Appointment.DataItem;
               
                e.Appointment.BackColor = System.Drawing.Color.FromArgb( Convert.ToInt32("0x" + customEvent.Colour, 16));
                e.Appointment.ToolTip = customEvent.Description.Replace("<br/>", "\n");
            }

            protected void radScheduler_OnAppointmentUpdate(object sender, AppointmentUpdateEventArgs e) {
                SchedulerService schedulerService = new SchedulerService(omDb, omVariables, langProvider);
                var modifiedAppointment = e.ModifiedAppointment;
                DiaryEvent diaryEvent = omDb.FindDiaryEvent(Convert.ToInt32(modifiedAppointment.ID));
                if (diaryEvent == null) {
                    SetRecordError("DiaryEvent", Convert.ToInt32(modifiedAppointment.ID));
                    e.Cancel = true;
                } else {
                        diaryEvent.StartDateTime = modifiedAppointment.Start;
                        diaryEvent.EndDateTime = modifiedAppointment.End;
                        omDb.InsertOrUpdateDiaryEvent(diaryEvent);
                        radScheduler.Rebind();   // Removing this makes no difference
                    }
                }
            }

        public class CustomEvent : Appointment {
            //public int ID { set; get; }
            //public DateTime Start { set; get; }
            //public DateTime End { set; get; }
            public string BookingName { set; get; }
            public string QualificationModule { set; get; }
            public string Title { set; get; }
            public string Instructors { set; get; }
            public string Colour { set; get; }
            public string Location { set; get; }
            public string ResourceList { set; get; }
            public string People { set; get; }
            //public string Description { set; get; }
            public CustomEvent() {}
            public CustomEvent(CustomEvent source)
                : base() {
                CopyInfo(source);
            }
            public void CopyInfo(CustomEvent source) {
                ID = source.ID;
                Start = source.Start;
                End = source.End;
                BookingName = source.BookingName;
                QualificationModule = source.QualificationModule;
                Title = source.Title;
                Instructors = source.Instructors;
                Colour = source.Colour;
                Location = source.Location;
                ResourceList = source.ResourceList;
                People = source.People;
                Description = source.Description;
            }
        }

     

    Unfortunately, the problem is not resolved. The first time an event is dragged/dropped, all works fine, but after that, moving the event again exhibits the problem of the drag panel being in the wrong place and not able to be dropped in the right place.

    Almost like the control looses itself on postback.

    I fail to understand how the data source can affect drag/drop on the UI !

    Storing the diary records in the session (per the examples) is not an option with large numbers of records.

    Any ideas ?

    Thankyou

    Graham Plowman

  4. Graham
    Graham avatar
    41 posts
    Member since:
    Feb 2011

    Posted 02 Jan Link to this post

    In addition, if we have an appointment which starts at 9AM on Friday and Finishes at 5PM on Monday, but the event doesn't operate on the weekend, how do we stop RadScheduler showing the weekend as part of the event ? ie observe working hours ?
  5. Graham
    Graham avatar
    41 posts
    Member since:
    Feb 2011

    Posted 02 Jan Link to this post

    OK, I think we have nailed the mis-positioned panel while dragging.

    Our code is now basically a copy of the Telerik Sample here.

    We now have it working properly in IE11 and Chrome - dragging objects around all follow the mouse correctly which they weren't before. The key to this seems to be the code:

    protected void RadScheduler1_AppointmentUpdate(object sender, AppointmentUpdateEventArgs e)
    {
        AppointmentInfo ai = FindById(e.ModifiedAppointment.ID.ToString());
        ai.CopyInfo(e.ModifiedAppointment);
    }

    However, while it works in IE11 and Chrome, it doesn't in Edge - the same mis-positioned drag object is occurring as before - I think there may be a problem with the JavaScript which drives this when running under Edge.

    Graham Plowman

     

     

     

     

  6. Graham
    Graham avatar
    41 posts
    Member since:
    Feb 2011

    Posted 02 Jan in reply to Graham Link to this post

    Just following up on my previous post:

    In Edge, the problem of the mis-placed drag object doesn't occur on the first drag/drop after a page first displays. It occurs on the second and all subsequent drag/drops. Presumably, postback has something to do with this ?

    Graham Plowman

  7. Graham
    Graham avatar
    41 posts
    Member since:
    Feb 2011

    Posted 02 Jan Link to this post

    A further suggestion:

    The data source system of RadScheduler really should work on the principal of a provider such that RadScheduler calls the provider with a date range for the provider to return data for. RadScheduler should call the provider whenever it needs data for a date range.

    Otherwise, we have to load all data into the session and RadScheduler - which doesn't work well when there is large amounts of data!

  8. Plamen
    Admin
    Plamen avatar
    2790 posts

    Posted 05 Jan Link to this post

    Hi,

    I have tried to replicate the issue on our online demos but to no avail.
    Would you please let us know if the unusual behavior can be observed on any of the demos s owe could inspect it and be more helpful.

    As for your last suggestion - RadScheduler does support binding with different types of providers as it is documented here. The technique that I recommended in my previous post is recommended only when DataSource property is used in the code behind. 

    Regards,
    Plamen
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top