Apply minTime and maxTime for the current week

I am working in a weekly mode and I want to limit the visible time range to the earliest event of the week and the last event of the week.

I think the correct way to solve the problem is to manually filter the events that are visible in the current week, find the minimum and maximum times and set them to the minTime and maxTime property. The problem is that I don't see the weekChanged callback (or something like that) which seems to be the right place to recalculate minTime and maxTime.

+3


source to share


2 answers


This was a lot more work than I expected, hope it works well enough for you. I basically do what I suggested in the comments above.

Edit: Changed the code to improve performance, so we don't have to wait for the entire frame to be rendered before knowing we need to start over.

Note that in order to do this more efficiently, we would either have to execute a new callback, because none of the existing ones seem to have set clientEvents already or timed out the events in advance (which can get messy in the case of time zones).



http://jsfiddle.net/3E8nk/555/

(function(c) {

    var startedViewRender = true;

    function greaterTime(first, second) {
        //Assuming dates are the same year
        if (first.clone().dayOfYear(0).isBefore(second.clone().dayOfYear(0)))
            return second;
        else
            return first;
    }

    var calendarOptions = {
        header: {
            left: 'prev,next today',
            center: 'title',
            right: 'agendaWeek'
        },
        defaultView: 'agendaWeek',
        minTime: '00:00:00',
        maxTime: '24:00:00',
        defaultDate: '2014-06-12',
        defaultTimedEventDuration: '02:00:00',
        editable: true,
        events: [{
            title: 'All Day Event',
            start: '2014-06-01'
        }, {
            title: 'Long Event',
            start: '2014-06-07',
            end: '2014-06-10'
        }, {
            id: 999,
            title: 'Repeating Event',
            start: '2014-06-09T16:00:00'
        }, {
            id: 999,
            title: 'Repeating Event',
            start: '2014-06-16T16:00:00'
        }, {
            title: 'Meeting',
            start: '2014-06-12T10:30:00',
            end: '2014-06-12T12:30:00'
        }, {
            title: 'Lunch',
            start: '2014-06-12T12:00:00'
        }, {
            title: 'Birthday Party',
            start: '2014-06-13T07:00:00'
        }, {
            title: 'Click for Google',
            url: 'http://google.com/',
            start: '2014-06-28'
        }],
        viewRender: function(view) {
            startedViewRender = true;
        },
        eventRender: function(event, element, view) {
            if (!startedViewRender)
                return;
            else
                startedViewRender = false;

            if (view.name !== 'agendaWeek') {
                console.log('not agendaWeek');
                return;
            }

            var events = c.fullCalendar('clientEvents');

            if (events.length === 0) {
                console.log('no events at all');
                //Set to default times?
                return;
            }

            var visibleAndNotAllDayEvents = events.filter(function(event) {
                //end not necessarily defined
                var endIsWithin = event.end ? event.end.isWithin(view.start, view.end) : false;
                return !event.allDay && (event.start.isWithin(view.start, view.end) || endIsWithin);
            });

            if (visibleAndNotAllDayEvents.length === 0) {
                console.log('no visible not all day events');
                //Set to default times?
                return;
            }

            var earliest = visibleAndNotAllDayEvents.reduce(function(previousValue, event) {
                return greaterTime(previousValue, event.start).isSame(previousValue) ? event.start : previousValue;
            }, moment('23:59:59', 'HH:mm:ss'));

            var latest = visibleAndNotAllDayEvents.reduce(function(previousValue, event) {
                var end = event.end ? event.end.clone() : event.start.clone().add(moment(calendarOptions.defaultTimedEventDuration, 'HH:mm:ss'));

                return greaterTime(previousValue, end);
            }, moment('00:00:00', 'HH:mm:ss'));

            if (calendarOptions.minTime !== earliest.format('HH:mm:ss') || calendarOptions.maxTime !== latest.format('HH:mm:ss')) {
                //Reinitialize the whole thing

                var currentDate = c.fullCalendar('getDate');

                c.fullCalendar('destroy');
                c.fullCalendar($.extend(calendarOptions, {
                    defaultDate: currentDate,
                    minTime: earliest.format('HH:mm:ss'),
                    maxTime: latest.format('HH:mm:ss')
                }));
            }

        }
    };

    c.fullCalendar(calendarOptions);

})($('#calendar'));

      

+6


source


You can do this using eventAfterAllRender

which is executed after all events have been displayed

eventAfterAllRender: function(view) {
    var evts = $("#calendar").fullCalendar( 'clientEvents'),
        minTime = moment("2014-01-01 23:59:59").format("HH:mm:ss"),
        maxTime = moment("2014-01-01 00:00:00").format("HH:mm:ss"),
        currentDate = view.calendar.getDate(),
        currentMinTime = view.calendar.options.minTime,
        currentMaxTime = view.calendar.options.maxTime;

    // lets calculate minTime and maxTime based on the week events
    // if this event minTime is 'before' than the minTime, set this as the minTime
    for(var i in evts) {
        minTime = timeDiff(minTime, evts[i].start.format("HH:mm:ss"), true);
        maxTime = timeDiff(maxTime, evts[i].end.format("HH:mm:ss"), false);
    }

    // If minTime or maxTime don't match, recreate fullcalendar
    // This is a pain in the ass : \
    // We have to destroy and apply fullcalendar so this can work.
    if (minTime != currentMinTime || maxTime != currentMaxTime) {
        $("#calendar").fullCalendar('destroy');
        $("#calendar").fullCalendar(
            $.extend(fcOpts, {
                defaultDate: currentDate,
                minTime: minTime,
                maxTime: maxTime
            })
        );
    }
}

      

You should have a function to calculate what time is the most recent or earliest:



function timeDiff(time1, time2, getMin) {
    var d1 = new Date('2014-01-01 ' + time1),
        d2 = new Date('2014-01-01 ' + time2);

    if (getMin) {
        return d1.getTime(d1) - d2.getTime(d2) < 0 ? time1 : time2;
    } else {
        return d1.getTime(d1) - d2.getTime(d2) > 0 ? time1 : time2;
    }
}

      

For a working example see the following JsFiddle .

+3


source







All Articles