Our powerful JS Calendar component


Post by nvondru »

I'm using a datepicker set to "range" to select a range istead of a singular date.
When trying to set the range config for dayresource and resource views at runtime, the corresponding views don't update correctly .

Unintended behavior:

  • the top bar doesn't update at all, it always displays the initial dates
  • the schedule area only updates its width / colums per day upon triggering a onLayout (here demonstrated by changing the minEventHeight using the slider)
  • even upon onLayout the data doesn't actually update -> only empty columns are displayed

When setting a range in the initial config, the views render as intended. Are those properties not intended to change at runtime? How could i trigger a full "reload" of a view / the whole calendar? I tried using

calendar.refresh();
calendar.refreshSoon();

both to no avail...

Here is the eventHandler which is triggered when the datepicker fires "selectionChanged", as well as the relevant configuration on the calendar object:


// Relevant calendar config:
new Calendar({
date: "2024-03-04",
...

modes: {
    day: null,
    week: null,
    month: null,
    year: null,
    agenda: null,
    list: null,
    resource: {
        title: "Kanaele",
        minEventHeight: "0px",
        view: {
            type: "week",
            syncCalendarDate: false,
            range: "7d",
        },
        listeners: {
            layoutUpdate: "up.onViewLayout",
            show({ source: Widget }) {
                const { hourHeightSlider } = calendar.widgetMap;
                Widget.views?.forEach(wv => {
                    wv.zoomTo?.(hourHeightSlider.value);
                });
            }
        },
    },
    dayresource: {
        title: "Kanaele pro Tag",
        minEventHeight: "0px",
        syncCalendarDate: false,
        range: "7d",
        listeners: {
            layoutUpdate: "up.onViewLayout",
            show({ source: Widget }) {
                if (calendar) {
                    const { hourHeightSlider } = calendar.widgetMap;
                    Widget.zoomTo?.(hourHeightSlider.value);
                }
            }
        },
    }
}

...

sidebar: {
    width: '20em',
    items: {
        datePicker: null,
        dateRangePicker: {
            weight: 0,
            type: 'datepicker',
            date: selectedStartAndEndDates[0],
            selection: selectedStartAndEndDates,
            // In this mode, the "selection" is applied to any child
            // EventList views - EventList and AgendaView
            multiSelect: 'range',
            listeners: {
                selectionChange: 'up.onDatePickerRangeSelected'
            }
        },
    }
}

....

// EventHandler listening on selectionChange from datepicker
onDatePickerRangeSelected: ({ source, selection: [startDate, endDate] }) => {
    if (source.multiSelect === 'range') {
        const rangeInMilliseconds = endDate - startDate;
        const rangeInDays = Math.ceil(rangeInMilliseconds / (1000 * 3600 * 24)) + 1;
        calendar.views.forEach(v => {

        switch (v.type) {
            case "resourceview":
                v.views?.forEach(wv => {
                    wv.range = rangeInDays + "d";

                });
                break;
            case "dayresource":
                v.range = rangeInDays + "d";
                break;

            default:
                break;
        }
    });
    calendar.date = startDate;
    calendar.refresh();
}
}

....

});


Edit: Another finding I have is, when I toggle a resource, this causes the dayResourceView to render the events for the empty columns in the previous video clip. However the eventColumns still don't match with the day headers, which are incorrect

2024-03-26_17-12-17.mp4
Video 2, showing how toggling a resource causes the calendar to somewhat correctly render events
(3.6 MiB) Downloaded 18 times

Edit 2:
This is the behvior after additionally setting the views.allDayEvents.range property, as well as setting a startDate

2024-03-26_18-13-19.mp4
(5.04 MiB) Downloaded 14 times

Showcase of the flexibility the views should offer:

2024-03-27_15-56-42.mp4
(18.66 MiB) Downloaded 12 times
Last edited by nvondru on Wed Mar 27, 2024 5:00 pm, edited 2 times in total.

Post by Animal »

The child DayViews of the ResourceView should of course change the range of their "all day" rows, so we will fix this.

But it does work with

resourceView.eachView(v => v.range = v.allDayEvents.range = '2d');
Screenshot 2024-03-26 at 17.34.31.png
Screenshot 2024-03-26 at 17.34.31.png (237.08 KiB) Viewed 270 times

Post by Animal »

There's a lot going on there. Very difficult to see what exactly is happening with an enormously busy screen and the action over within three seconds. I will try.... things.


Post by nvondru »

Thanks for your quick reply! Let me know, how I can assist you, by delivering more/better material showcasing my issue.
Following your above reply, after additionally setting

v.allDayEvents.range

the views update correctly when only selecting a single day. I'll provide a video in a couple minutes


Post by Animal »

The dayResourceView doesn't appear to react well to having its range changed. Will take a look.


Post by Animal »

There's a bug with reacting to range change. If the start date doesn't change (which it won't if you're just setting range), it doesn't refresh.


Post by Animal »

OK, I have DayResourceView successfully updating itself on range change:

changerange.mov
(1.02 MiB) Downloaded 17 times

Will create a ticket for this cluster of issues and it will be fixed in the forthcoming patch release.


Post by Animal »


Post by nvondru »

I added a video in my inital post, showcasing the current behavior after your suggested changes (also cleaned up the screen a bit). The code now looks like this:

  onDatePickerRangeSelected: ({ source, selection: [startDate, endDate] }) => {
      if (source.multiSelect === 'range') {
          const rangeInMilliseconds = endDate - startDate;
          const rangeInDays = Math.ceil(rangeInMilliseconds / (1000 * 3600 * 24)) + 1;
          calendar.views.forEach(v => {

          switch (v.type) {

              case "resourceview":
                  v.views?.forEach(wv => {
                      wv.startDate = startDate;
                      wv.allDayEvents.startDate = startDate;
                      wv.range = rangeInDays + "d";
                      wv.allDayEvents.range = rangeInDays + "d";                                 

                  });
                  break;
              case "dayresource":
                  v.startDate = startDate;
                  v.allDayEvents.startDate = startDate;
                  v.range = rangeInDays + "d";
                  v.allDayEvents.range = rangeInDays + "d";                                
                  break;

              default:
                  break;
          }
      });
      calendar.date = startDate;
  }
  },

Last edited by nvondru on Tue Mar 26, 2024 7:22 pm, edited 2 times in total.

Post by nvondru »

Thanks for your quick and helpful assistance! I'll stay tuned for the upcoming patch release


Post Reply