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

How to display events lasting more than 24 hours in day view?

7 Answers 526 Views
Scheduler
This is a migrated thread and some comments may be shown as answers.
Boris
Top achievements
Rank 1
Boris asked on 14 Jan 2016, 11:47 AM

Hello,

In scheduler's day view, when I create an event that starts for example at 10:00 AM and ends at 10:00 AM the next day, the event is created, but I can't see this event in the scheduler. You can try this behavior also in this scheduler demo: http://demos.telerik.com/kendo-ui/scheduler/restriction

I know that I can set allDaySlot field to true and see the event at the top row of the scheduler, but I want to see the event inside the scheduler, between the other events.

I have read that it's possible to achieve this by creating a custom view, but I haven't found any source code with a custom view that would solve my problem. Could anybody send me a code that would help me with this?

Thanks for replies,

Boris

7 Answers, 1 is accepted

Sort by
0
Vladimir Iliev
Telerik team
answered on 18 Jan 2016, 05:57 AM
Hello Boris,

Currently we have no such example which we can provide where the day, week and work week views shows events longer than 24 hours as regular event. That why I would suggest to instead start using the "Timeline" views where this behavior is build-in. Please check the example below:

Regards,
Vladimir Iliev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Bernd
Top achievements
Rank 2
answered on 17 Jan 2017, 08:36 AM

Dear Vladimir.

In my use case the timeline view is not accepted as solution. My users want the (multi-)day view with long running events being shown as normal events spanning more than 24 hours.

I had a look at the scheduler day view source and opened a suggestion in your portal. Unfortunately I got a call today, my customer told me he really needs to see those events as normal events. Especially the start and the end. To be able to schedule events seamlessly.

In other words: I can't wait till this feature might  make it into the product.

So what is the easiest way to achieve this?

Kind regards

Bernd

0
Vladimir Iliev
Telerik team
answered on 18 Jan 2017, 07:54 AM
Hello Bernd,

To achieve the desired behavior you should extend the desired view and override the methods that are responsible for rendering the events. Currently we have no such example which we can provide - that why I could only suggest to check the following demo which shows how to extend the Scheduler views: 

Also you can check our professional services for more options. 

Regards,
Vladimir Iliev
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.
0
Bernd
Top achievements
Rank 2
answered on 27 Jan 2017, 12:46 PM

Hello Vladimir.

Thank you for the link to your professional service portal. But it seems your professional service team needs no money. After two weeks trying to get a quote on this modification I ended up doing it myself. This is my custom view:

001.(function (f, define) {
002.    define('kendo.dispatcher.dayview', ['kendo.scheduler.dayview'], f);
003.}(function () {
004.    var __meta__ = {
005.        id: 'dispatcher.dayview',
006.        name: 'Dispatcher Day View',
007.        category: 'web',
008.        description: 'The Dispatcher Day View',
009.        depends: ['scheduler.dayview'],
010.        hidden: true
011.    };
012.    (function ($, undefined) {
013.        var kendo = window.kendo, ui = kendo.ui, Widget = ui.Widget, getDate = kendo.date.getDate, extend = $.extend;
014.        function addContinuousEvent(group, range, element, isAllDay) {
015.            var events = group._continuousEvents;
016.            var lastEvent = events[events.length - 1];
017.            var startDate = getDate(range.start.startDate()).getTime();
018.            if (isAllDay && lastEvent && getDate(lastEvent.start.startDate()).getTime() == startDate) {
019.                var idx = events.length - 1;
020.                for (; idx > -1; idx--) {
021.                    if (events[idx].isAllDay || getDate(events[idx].start.startDate()).getTime() < startDate) {
022.                        break;
023.                    }
024.                }
025.                events.splice(idx + 1, 0, {
026.                    element: element,
027.                    isAllDay: true,
028.                    uid: element.attr(kendo.attr('uid')),
029.                    start: range.start,
030.                    end: range.end
031.                });
032.            } else {
033.                events.push({
034.                    element: element,
035.                    isAllDay: isAllDay,
036.                    uid: element.attr(kendo.attr('uid')),
037.                    start: range.start,
038.                    end: range.end
039.                });
040.            }
041.        }
042.        var DispatcherMultiDayView = ui.MultiDayView.extend({
043.            _renderEvents: function (events, groupIndex) {
044.                var allDayEventContainer = this.datesHeader.find('.k-scheduler-header-wrap > div');
045.                var byDate = this._isGroupedByDate();
046.                var event;
047.                var idx;
048.                var length;
049.                for (idx = 0, length = events.length; idx < length; idx++) {
050.                    event = events[idx];
051.                    if (this._isInDateSlot(event)) {
052.                        var isMultiDayEvent = event.isAllDay;// || event.end.getTime() - event.start.getTime() >= MS_PER_DAY;
053.                        var container = isMultiDayEvent && !this._isVerticallyGrouped() ? allDayEventContainer : this.content;
054.                        var element, ranges, range, start, end, group;
055.                        if (!isMultiDayEvent) {
056.                            if (this._isInTimeSlot(event)) {
057.                                group = this.groups[groupIndex];
058.                                if (!group._continuousEvents) {
059.                                    group._continuousEvents = [];
060.                                }
061.                                ranges = group.slotRanges(event, false);
062.                                var rangeCount = ranges.length;
063.                                for (var rangeIndex = 0; rangeIndex < rangeCount; rangeIndex++) {
064.                                    range = ranges[rangeIndex];
065.                                    start = event.start;
066.                                    end = event.end;
067.                                    if (rangeCount > 1) {
068.                                        if (rangeIndex === 0) {
069.                                            end = range.end.endDate();
070.                                        } else if (rangeIndex == rangeCount - 1) {
071.                                            start = range.start.startDate();
072.                                        } else {
073.                                            start = range.start.startDate();
074.                                            end = range.end.endDate();
075.                                        }
076.                                    }
077.                                    var occurrence = event.clone({
078.                                        start: start,
079.                                        end: end,
080.                                        _startTime: event._startTime,
081.                                        _endTime: event.endTime
082.                                    });
083.                                    if (this._isInTimeSlot(occurrence)) {
084.                                        var head = range.head;
085.                                        element = this._createEventElement(event, !isMultiDayEvent, head, range.tail);
086.                                        element.appendTo(container);
087.                                        this._positionEvent(occurrence, element, range);
088.                                        addContinuousEvent(group, range, element, false);
089.                                    }
090.                                }
091.                            }
092.                        } else if (this.options.allDaySlot) {
093.                            group = this.groups[groupIndex];
094.                            if (!group._continuousEvents) {
095.                                group._continuousEvents = [];
096.                            }
097.                            ranges = group.slotRanges(event);
098.                            if (ranges.length) {
099.                                range = ranges[0];
100.                                var startIndex = range.start.index;
101.                                var endIndex = range.end.index;
102.                                if (byDate && startIndex !== endIndex) {
103.                                    start = range.start.start;
104.                                    end = range.end.end;
105.                                    var newStart = new Date(start);
106.                                    var newEnd = new Date(start);
107.                                    for (var i = range.start.index; i <= range.end.index; i++) {
108.                                        element = this._createEventElement(event, !isMultiDayEvent, i !== endIndex, i !== startIndex);
109.                                        var dateRange = group.daySlotRanges(newStart, newEnd, true)[0];
110.                                        newEnd.setDate(newEnd.getDate() + 1);
111.                                        newStart.setDate(newStart.getDate() + 1);
112.                                        this._positionAllDayEvent(element, dateRange);
113.                                        addContinuousEvent(group, dateRange, element, true);
114.                                        element.appendTo(container);
115.                                    }
116.                                } else {
117.                                    element = this._createEventElement(event, !isMultiDayEvent);
118.                                    this._positionAllDayEvent(element, ranges[0]);
119.                                    addContinuousEvent(group, ranges[0], element, true);
120.                                    element.appendTo(container);
121.                                }
122.                            }
123.                        }
124.                    }
125.                }
126.            },
127.        });
128.        extend(true, ui, {
129.            DispatcherMultiDayView: DispatcherMultiDayView,
130.            DispatcherDayView: DispatcherMultiDayView.extend({
131.                options: {
132.                    name: 'DayView',
133.                    title: 'Day'
134.                },
135.                name: 'dispatcherDay'
136.            }),
137.            DispatcherWeekView: DispatcherMultiDayView.extend({
138.                options: {
139.                    name: 'WeekView',
140.                    title: 'Week',
141.                    selectedDateFormat: '{0:D} - {1:D}',
142.                    selectedShortDateFormat: '{0:d} - {1:d}'
143.                },
144.                name: 'dispatcherWeek',
145.                calculateDateRange: function () {
146.                    var selectedDate = this.options.date, start = kendo.date.dayOfWeek(selectedDate, this.calendarInfo().firstDay, -1), idx, length, dates = [];
147.                    for (idx = 0, length = 7; idx < length; idx++) {
148.                        dates.push(start);
149.                        start = kendo.date.nextDay(start);
150.                    }
151.                    this._render(dates);
152.                }
153.            }),
154.            DispatcherWorkWeekView: DispatcherMultiDayView.extend({
155.                options: {
156.                    name: 'WorkWeekView',
157.                    title: 'Work Week',
158.                    selectedDateFormat: '{0:D} - {1:D}',
159.                    selectedShortDateFormat: '{0:d} - {1:d}'
160.                },
161.                name: 'dispatcherWorkWeek',
162.                nextDate: function () {
163.                    var weekStart = kendo.date.dayOfWeek(kendo.date.nextDay(this.startDate()), this.calendarInfo().firstDay, 1);
164.                    return kendo.date.addDays(weekStart, this._workDays[0]);
165.                },
166.                previousDate: function () {
167.                    var weekStart = kendo.date.dayOfWeek(this.startDate(), this.calendarInfo().firstDay, -1);
168.                    var workDays = this._workDays;
169.                    return kendo.date.addDays(weekStart, workDays[workDays.length - 1] - 7);
170.                },
171.                calculateDateRange: function () {
172.                    var selectedDate = this.options.date, dayOfWeek = kendo.date.dayOfWeek, weekStart = dayOfWeek(selectedDate, this.calendarInfo().firstDay, -1), start = dayOfWeek(weekStart, this.options.workWeekStart, 1), end = dayOfWeek(start, this.options.workWeekEnd, 1), dates = [];
173.                    while (start <= end) {
174.                        dates.push(start);
175.                        start = kendo.date.nextDay(start);
176.                    }
177.                    this._render(dates);
178.                }
179.            })
180.        });
181.    }(window.kendo.jQuery));
182.    return window.kendo;
183.}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
184.    (a3 || a2)();
185.}));

Anything I could have done smarter/better here?

Kind regards

Bernd

0
Ivan Danchev
Telerik team
answered on 31 Jan 2017, 03:53 PM
Hello Bernd,

We are glad you have found a way to achieve the desired behavior by extending the view. We cannot guarantee this solution will work in all possible scenarios since it hasn't undergone our internal testing procedures.
With regard to the issues with getting in touch with Professional Services, I received information that the team has already gotten into contact with you and the reasons behind the delay in establishing communication are currently under investigation.

Regards,
Ivan Danchev
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.
0
Bernd
Top achievements
Rank 2
answered on 01 Feb 2017, 05:07 PM

Well. It doesn't work in all scenarios.

I have a drop down to change the tick count. this change event function works with the standard views. With my inherited one it reloads the data, but it doesn't change layout.

function minorTickChange(e) {
    scheduler.setOptions({
        minorTickCount: Number(this.value())
    })
    scheduler.view(scheduler.view().name);
}

Any ideas what's wrong with my custom view?

Thanks in advance

Bernd

0
Ivan Danchev
Telerik team
answered on 03 Feb 2017, 12:21 PM
Hello Bernd,

I am afraid providing advice on custom implementations that modify the default behavior of the components falls outside the scope of the support service (Soruce Code Explanation section). Consulting and assistance on the customization of the default behavior are provided by the Professional Services team. Let us know in case you have questions on the built-in Scheduler functionality and its API.

Regards,
Ivan Danchev
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.
Tags
Scheduler
Asked by
Boris
Top achievements
Rank 1
Answers by
Vladimir Iliev
Telerik team
Bernd
Top achievements
Rank 2
Ivan Danchev
Telerik team
Share this question
or