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

8 posts, 0 answers
  1. Boris
    Boris avatar
    18 posts
    Member since:
    Aug 2015

    Posted 14 Jan 2016 Link to this post

    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

  2. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2190 posts

    Posted 17 Jan 2016 Link to this post

    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!
     
  3. Bernd
    Bernd avatar
    79 posts
    Member since:
    Feb 2013

    Posted 17 Jan Link to this post

    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

  4. Vladimir Iliev
    Admin
    Vladimir Iliev avatar
    2190 posts

    Posted 18 Jan Link to this post

    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.
  5. Bernd
    Bernd avatar
    79 posts
    Member since:
    Feb 2013

    Posted 27 Jan in reply to Vladimir Iliev Link to this post

    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

  6. Ivan Danchev
    Admin
    Ivan Danchev avatar
    1213 posts

    Posted 31 Jan Link to this post

    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.
  7. Bernd
    Bernd avatar
    79 posts
    Member since:
    Feb 2013

    Posted 01 Feb in reply to Ivan Danchev Link to this post

    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

  8. Ivan Danchev
    Admin
    Ivan Danchev avatar
    1213 posts

    Posted 03 Feb Link to this post

    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.
Back to Top