Scroll Event to top of list


#1

With an mbsc-eventcalendar, is there a way I can force the event list to scroll to the selected day ?

For example, in the screenshot below, selecting 19th October, I would want the events of 19th October to scroll to the top of the event list.


#2

Hi Dave,

You could use the onDayChange event to scroll to the given day.
Example:

onDayChange: (event, inst) => {
  // Find all day headers
  const headers = inst.markup.querySelectorAll('.mbsc-event-day');
  const formattedDate = mobiscroll.util.datetime.formatDate(inst.settings.dateFormat, event.date);
  // Find the day header to scroll into view
  const day = [].find.call(headers, (el) => el.innerHTML == formattedDate);
  if (day !== undefined) {
    setTimeout(() => {
      day.scrollIntoView({ behavior: 'smooth', block: 'start' });
    });
  }
}

But if you’re using the calendar in fixed mode, it might not work correctly, since it will scroll the day on the top of the scrollable content, under the calendar. Is this your case?


#3

Hi Isti, thanks for the code, which almost works. I am using a fixed calendar view (by fixing mbsc-fr-c), and it looks like the day.scollIntoView is not taking account of this ? - I have done a short video showing what happens:


#4

Unfortunately the scrollIntoView method does not take into account the fixed elements, and doesn’t have any option to specify an offset.
A possible solution would be to don’t set the calendar as fixed, and instead make the list scrollable. The challenge is to calculate the height of the event list - in your case that would be the distance between the bottom of the calendar and the bottom navigation bar. This can be done inside the onPosition event:
Example:

  calOptions: MbscEventcalendarOptions = {
    cssClass: 'my-calendar',
    view: {
      calendar: { type: 'week' },
      eventList: { type: 'week' }
    },
    onPosition: (event, inst) => {
      const eventList = inst.markup.querySelector('.mbsc-event-list');
      const top = eventList.getBoundingClientRect().top + document.body.scrollTop;
      const bottomNavHeight = 50;

      setTimeout(() => {
        eventList.style.height = window.innerHeight - top - bottomNavHeight + 'px';
      });
    },
    onDayChange: (event, inst) => {
      // Find all day headers
      const headers = inst.markup.querySelectorAll('.mbsc-event-day');
      const formattedDate = mobiscroll.util.datetime.formatDate(inst.settings.dateFormat, event.date);
      // Find the day header to scroll into view
      const day = [].find.call(headers, (el) => el.innerHTML == formattedDate);
      if (day !== undefined) {
        setTimeout(() => {
          day.scrollIntoView({ behavior: 'smooth', block: 'start' });
        });
      }
    }
  }

CSS:

.my-calendar .mbsc-event-list {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

Let me know if this works!


#5

Hi Isti, thanks very much - it works perfectly - see new video.


#6

In version 4.6.0 we added built in support for scrollable event list.
This can be enabled using the scrollable property on the eventList inside the view setting:

view: {
  calendar: {
    type: 'month'
  },
  eventList: {
    type: 'month',
    scrollable: true
  }
}

When enabled, the event list will have a height to fill the parent container. This means you have to make sure the parent container of the eventcalendar has the right height and only contains the eventcalendar component.

E.g. putting the <mbsc-eventcalendar> directly inside <ion-content> will fill the entire page.
If you also have other content inside the <ion-content> (like the switch and segmented buttons). you will need to put the eventcalendar in a new container which has the right height. This can be achieved with flex layout for example, like in this demo.