Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fullcalendar v2: How to maintain the same scroll time when navigating weeks?

On Fullcalendar 2, when I navigate between weeks, I'd like to maintain the same time ranges in the vertical scroll. For example, in the below images, I am initially looking at times from 12am-3pm. But when I press the next arrow to go to the next week, it resets at 8am.

I know that I can change the default starting time with

scrollTime: "08:00:00",

but how do I make it so that the vertical time range is "fixed" to what I am on?

enter image description hereenter image description here

like image 520
kibaekr Avatar asked Oct 20 '14 03:10

kibaekr


2 Answers

Unfortunately this is not build-in functionality. There is a workaround but you will always have a little bit of flickering when you go to the previous/next week.

var scroll = -1,
    viewNames = ['agendaWeek', 'agendaDay'];

$('#calendar').fullCalendar({
    //...
    eventAfterAllRender: function(view) {
        if(scroll > -1 && viewNames.indexOf(view.name) !== -1)
            //Use a setTimeout hack here because the scrollTime will be set after eventAfterAllRender is processed.
            setTimeout(function(){                
                document.querySelector('.fc-agenda-slots').parentNode.parentNode.scrollTop = scroll;
            }, 0);
    },
    viewDestroy: function(view) {
        if(viewNames.indexOf(view.name) !== -1)
            scroll = document.querySelector('.fc-agenda-slots').parentNode.parentNode.scrollTop;
    }
    //...
});

jsfiddle

This code will work for FullCalendar v2. It assumes that the scrolling div is the parent of the parent of the .fc-agenda-slots div.

like image 184
A1rPun Avatar answered Nov 15 '22 03:11

A1rPun


Working Code compatible with fullcalendar 2.6.1

I started this code from the post below (A1rPun).

Working JSFiddle

var scroll = -1;

$('#calendar').fullCalendar({

    // init calendar
    header: {left: 'today prev,next, refresh title', 
    right: 'agendaDay,agendaWeek'},
    allDaySlot: false,
    defaultView: 'agendaDay',


    // when all the events are rendered, scroll to the previous saved scroll position
    eventAfterAllRender: function(view) {
        if(scroll > -1 && (view.name=='agendaDay' || view.name=='agendaWeek'))
            setTimeout(function(){
            document.querySelector('.fc-scroller').scrollTop = scroll;
        },0);
    },

    // when view is destroyed, we keep the scroll position in a variable
    viewDestroy: function(view) {
        if(view.name=='agendaDay' || view.name=='agendaWeek')
            scroll = document.querySelector('.fc-scroller').scrollTop;
    }

}); // end calendar

This solution is working in 'agendaDay', and 'agendaWeek' views. It's also working when you switch between them.

I don't think it is very pretty because you need to wait until after all the events are rendered. The more events you have on your calendar, the more time the scroll will take..

A good solution would be to use the

Fullcalendar option scrollTime

You can set it in viewRender like this. That will have the effect to make the calendar scroll to this time.

viewRender: function(view, element){
    view.options.scrollTime = '09:00:00';
}

Maybe there is a way to convert the scroll value into time and then render it to the calendar.

EDIT 1

I figured out that is way much better to use the viewRender callback, instead of the eventAfterAllRender callback to set the scroll position.

Here is the JSFiddle

viewRender: function(view, element){

        if(scroll > -1 && (view.name=='agendaDay' || view.name=='agendaWeek')){
                    setTimeout(function(){
                    document.querySelector('.fc-scroller').scrollTop = scroll;
                },0);

            }
        },

It's allowing to switch between other wiews (month, basicWeek...) and keep saving the scroll. And it's a bit faster

like image 20
Julha Avatar answered Nov 15 '22 04:11

Julha