Our powerful JS Calendar component


Post by tdset »

Using the Calendar+Scheduler integration.

When datepicker.showEvents is enabled, changing the date in Timeline view will determine 2 date change events, with conflicting new.startDate and new.endDate values.
(About 70 date change events are actually fired, but I filtered the ones with changed == true, as seen below).

To replicate, please add this to the calendar's configuration in the default demo (https://bryntum.com/products/calendar/examples/calendar-scheduler/):

datePicker: {
        showEvents: true,
    },

listeners: {
    dateRangeRequested: (event) => {
        if ( ! event.changed) return;

        console.table({
           startDate: event.new.startDate.toDateString(),
           endDate: event.new.endDate.toDateString(),
        });
    }
},

As soon as you apply the changes, you should already see 3 events in the console, where the third is the same as the first one:

Image

The ranges are sometimes unexpected, too (not sure why it reports Oct 01 - Nov 12, whereas the week Oct 07 - Oct 14 makes sense).

If you switch from 12th to 18th, you should see one change event:

Image

But if you now switch to 17th, you should see two change events:

Image

The first one refers to the Oct 01 - Nov 12 interval again.

These would go unnoticed, however in our application we are loading events on demand and we're listening to date change events in order to know what to load. But the date ranges Calendar gives are conflicting, the application makes multiple requests, and since the dateRangeRequested event fires again a couple more times after the data is loaded, Calendar goes into an infinite fetch loop.

Please can you confirm if this is a bug and whether we can work around it somehow.

Thanks!


Post by Animal »

If Datepicker is showing events, it will ask the EventStore for all events which are in its date range.


Post by Animal »

There must be a lot of misunderstanding of what this event means.

It just means that the EventStore has been accessed to get a block of events by some widget. There's nothing wrong with it being asked for a block of events.


Post by Animal »

If you are loading a new event block on this, then both widgets are going to react to the new event arrival and re-request their events.

Each one has a different idea about its date range. So this will happen.

Maybe the SchedulerDatePicker should not trigger the call. Maybe it should be able to do a "silent" request for a block of events. I will try this with the LoadOnDemand Feature.


Post by Animal »

Try configuring the datePicker with this:

    refreshEventsMap() {
        const me = this;

        if (me.showEvents) {
            me.eventStore.suspendEvents();
            me.eventsMap = me.eventStore[me.showEvents === 'dots' ? 'getEvents' : 'getEventCounts']({
                startDate : me.startDate,
                endDate   : me.endDate,
                dateMap   : me.eventsMap || (me.eventsMap = new Map()),
                filter    : me.eventFilter
            });
            me.eventStore.suspendEvents();
        }
    }

Post by Animal »

But then if you ever go forwards or backwards just in the DatePicker it won't get any events to show.

Because they have not been loaded for that date range, and we must not kick off a request.

I don't think there's a good way of having two visible views both loading different date ranges on demand.


Post by tdset »

Thank you.

If this is the expected behaviour, is there any way we can listen for a more specific date range change event (ideally the one that reports the largest date interval) and avoid reacting to the date range events fired after load?

We are currently doing something like this within dateRangeRequested, only if changed === true and only if the dates have changed:

    event.source.crudManager.load({
        request: {
            params: {
                startDate: newStartDate,
                endDate: newEndDate
            }
        }
    }).then(...);

However upon first load, we are already reacting to 3 events; the first reports DATE RANGE 1, the second reports DATE RANGE 2, and the third reports DATE RANGE 1 again.
For each one, an event.source.crudManager.load() happens.
After each load, the 3 events are intercepted again, hence the loop.

Not sure I explained it clearly enough but basically what I'm after is for a way to get Calendar to tell me what's the date interval I need to load records for.
dateRangeRequested may not be the best place to do what I need.
I remember trying loadOnDemand in the past but got into other issues (reported a confirmed bug at the time: viewtopic.php?p=93498#p93498), probably I should try that again.


Post by Animal »

I don't think there is a way round this.

Each widget will ask for a block of events based on its range.

The Scheduler, when refreshing in response to the data arriving for that will ask for a block of events based on its range.

The DatePicker, when refreshing in response to the data arriving for that will ask for a block of events based on its range.

etc...


Post by tdset »

That makes sense, thank you.

I still believe there's a bug somewhere, at least in regard to the datePicker.showEvents implementation, since adding

datePicker: {
    showEvents: true,
},

breaks the "load on demand" demo here: https://www.bryntum.com/products/calendar/examples/load-on-demand/.


Post by Animal »

Well, it breaks because of the interaction I described above. Each widget which wants to read the event store asks for a different range of events.

And upon refresh of the event store, each widget then reads the event store to refresh itself.

Leading to it bouncing between them.


Post Reply