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?
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?
Share Improve this question asked Oct 20, 2014 at 3:19 kibaekrkibaekr 1,3491 gold badge22 silver badges38 bronze badges 3
- I'm getting the scroll position but I can't seem to set it (fullcalendar seems to be doing stuff). Maybe you can solve it from here: jsfiddle/3E8nk/568 – Richard Löwenström Commented Oct 20, 2014 at 6:19
-
1
It seems that you need to use
minTime
. – Luís Cruz Commented Oct 20, 2014 at 11:31 - @milz I think that is just if I don't want to display earlier times at all. What I want is: I want all the times to be there, but just not to reset to the scrollTime when I press the next arrows. So just stay on the same time ranges that I was on prior to pressing the navigation arrows – kibaekr Commented Oct 21, 2014 at 1:08
8 Answers
Reset to default 4Unfortunately 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.
Working Code patible 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
What I have is:
var height = $(window).scrollTop();
console.log("current height " + height);
$('#calendar').fullCalendar( 'removeEvents');
$('#calendar').fullCalendar( 'addEventSource', e);
$('#calendar').fullCalendar( 'addEventSource', holiday);
$('#calendar').fullCalendar( 'refetchEvents');
window.scrollTo(0,height);
console.log("scroll to " + height);
and it works for me
Here you can set basic configuration.
scrollTime: '08:00:00',
minTime: '00:00:00', // Set your min time
maxTime: '24:00:00', // Set your max time
yes, main thing is 'height' parameter should not be there in calendar configuration.
Remove below parameter
height: 'auto'
While I would like to see this as build-in function, this is the fastest and at the same time less verbose solution I found:
viewDestroy: function (view) {
if (view.name=='agendaDay' || view.name=='agendaWeek') {
var scrollEl = document.querySelector('.fc-scroller');
var scrollFraction = scrollEl.scrollTop / scrollEl.scrollHeight;
this.scrollTime = moment().startOf('day').add(3600 * 24 * scrollFraction, 's').format('HH:mm:00');
view.options.scrollTime = this.scrollTime;
}
}
Notice that this assumes the scroll range is 12AM-12AM. If you limit your visible area, you should adapt the day duration as well.
You can try it out: JSFiddle
give a unique class to event object. add this code in after event render method. it will scroll to that specific event
$('.fc-scroller').animate({
scrollTop: $('write here unique class of event').position().top
});
To avoid any scroll "flicking", I did this this way (in fullCalendar 2.9.1) :
viewDestroy: function( aView ) {
// At first view date change, get height of an hour
if( !lineHeight )
lineHeight = $('#calendar').find( "tr.fc-minor" ).height() * 2;
// then convert current scroll to hour decimal
var lScrollCurrHour = Math.max( ($('#calendar').find( ".fc-scroller" )[0].scrollTop - 1) / lineHeight, 0 );
// finally, use moment() to convert to a formatted date
aView.options.scrollTime = moment().startOf('day')
.add(lScrollCurrHour, "hours").format("HH:mm:ss");
}
It will keep separated the scroll for week and days agendas
Hope it helps :o)
you could use this to make the scroll time as your desired time.
customButtons:{
PreviousButton: {
text: 'Prev',
icon: 'left-single-arrow',
click: function() {
$('#calendar').fullCalendar('prev');
$("#calendar").fullCalendar( 'scrollTime',"08:00:00" );
}
}
}`
The method I specified here is only for previous button. Likewise we can have custom button for all the default buttons in full calendar and we can add this method to scroll the time whenever needed. i hope this would help.