LoadOnDemand

Loads the host Calendar's CrudManager on demand as the date range required to produce the UI changes.

Passes the requested startDate and endDate as extra HTTP parameters along with the load request.

By default, the HTTP parameters are called 'startDate' and 'endDate'. This is configurable using the startDateParamName and endDateParamName configs.

The date values are formatted according to the dateFormat config.

Usage:

new Calendar({
    features : {
        loadOnDemand : true
    }
});

Load on demand
//<code-header>
fiddle.title = 'Load on demand';
//</code-header>
const calendar = new Calendar({
    appendTo : targetElement,

    // Configure the LoadOnDemand feature
    features : {
        loadOnDemand : true
    },

    // Configure CrudManager for data management
    crudManager : {
        autoLoad : false, // Don't load initially, let LoadOnDemand handle it
        loadUrl  : '/calendar/load',
        syncUrl  : '/calendar/sync'
    },

    date    : new Date(2023, 0, 1),
    sidebar : false,
    width   : 800,
    height  : 600,

    onDateRangeLoad({ response }) {
        Toast.show(`Loaded ${response.events.rows.length} events`);
    }
});

// hide mocking the AJAX endpoint for loading data
AjaxHelper.mockUrl('/calendar/load', (url, urlParams, { queryParams }) => {
    const
        startDate = new Date(queryParams.startDate),
        endDate   = new Date(queryParams.endDate),
        events    = [],
        resources = [
            { id : 'r1', name : 'Resource 1' }
        ];

    // Generate events for the requested date range
    const current = new Date(startDate);
    let eventId = 1;

    while (current <= endDate) {
        // Generate 1-3 events per day
        const eventsToday = Math.floor(Math.random() * 3) + 1;

        for (let i = 0; i < eventsToday; i++) {
            const isMultiDay = Math.random() < 0.3; // 30% chance of multi-day event

            if (isMultiDay) {
                // Multi-day event (1-5 days)
                const
                    daySpan   = Math.floor(Math.random() * 5) + 1,
                    startTime = new Date(current),
                    endTime   = new Date(current);

                startTime.setHours(9, 0, 0, 0); // Start at 9 AM
                endTime.setDate(endTime.getDate() + daySpan);
                endTime.setHours(17, 0, 0, 0); // End at 5 PM

                events.push({
                    id         : eventId++,
                    name       : `Conference ${eventId} (${daySpan} days)`,
                    startDate  : startTime,
                    endDate    : endTime,
                    resourceId : 'r1',
                    allDay     : daySpan > 2 // Mark as all-day if longer than 2 days
                });
            }
            else {
                // Single day event
                const
                    startTime = new Date(current),
                    duration  = (Math.floor(Math.random() * 4) + 1) * 30; // 30min to 2hrs

                startTime.setHours(9 + Math.floor(Math.random() * 8)); // 9 AM to 5 PM
                startTime.setMinutes(Math.floor(Math.random() * 2) * 30); // 0 or 30 minutes

                const endTime = new Date(startTime.getTime() + duration * 60000);

                events.push({
                    id         : eventId++,
                    name       : `Meeting ${eventId}`,
                    startDate  : startTime,
                    endDate    : endTime,
                    resourceId : 'r1'
                });
            }
        }

        current.setDate(current.getDate() + 1);
    }

    return {
        responseText : JSON.stringify({
            success   : true,
            events    : { rows : events },
            resources : { rows : resources }
        }),
        delay : 300 // Simulate network delay
    };
});

// Mock the sync endpoint
AjaxHelper.mockUrl('/calendar/sync', () => {
    return {
        responseText : JSON.stringify({
            success : true
        }),
        delay : 200
    };
});
// end hide

Using recurring events

When using this feature when recurring events are in the database, all recurring events which started before the requested start date, and have not yet finished recurring MUST be sent as part of the return packet so that the Calendar is able to populate its UI.

Only the base recurring event definition is stored in the Calendar's EventStore.

When asked to yield a set of events for a certain date range for creating a UI, the EventStore automatically interpolates any occurrences of recurring events into the results. They do not occupy slots in the EventStore for every date in their repetition range (that would be very inefficient, and might be infinite).

Handling data load failures

If a network or server error is detected, the Calendar will fire a loadOnDemandFail event so that an application can produce an error UI and handle the situation.

A handler should return false to prevent the default provided error UI from showing.

If there is no handler, or the handler does not return false, a default error UI is shown using MessageDialog.

Using with showEvents in the sidebar date picker.

If you have configured the Calendar's datePicker to showEvents, the date picker will also initiate a request whenever it navigates forward or backward in time.

This could interfere with the current Calendar mode, so in this case, this feature extends the requested date range to include the date range which encapsulates both widgets' required ranges.

This may mean that a large block of events could be loaded if the date picker is navigated in time a long way while leaving the Calendar's main view date the same.

The alwaysLoadNewRange property must not be set in this use case because both widgets will initiate requests, and this would cause an infinite recursion of event requests.

This feature is disabled by default.

Configs

15

Common

disabledInstancePlugin
listenersEvents

Other

alwaysLoadNewRange: Boolean= false

By default, if a view requests a date range that we have already loaded, no network request is made, and the events will be loaded from the current content of the event store.

To make the feature load a new event block on every request for a new date range, configure this as true.

beforeRequest: function | String

A function, or name of a function in the ownership hierarchy which may be called to mutate the options packet that is passed to the CrudManager load method. One possible use of this function is to mutate the options.request.params object to add extra parameters for the server.

ParameterTypeDescription
optionsObject

The options parameter to be sent to the CrudManager load method.

options.dateRangeRequestedObject

An object containing the start and end dates of the range to load.

options.dateRangeRequested.startDateDate

The start date of the range to request.

options.dateRangeRequested.endDateDate

The end date of the range to request. Note that Dates are timestamps.

options.requestObject

A configuration object for the CrudManager load request

options.request.paramsObject

An object where the property name is the HTTP parameter name and the property value is the parameter value.

Returns: void
clearOnNewRange: Boolean= false

Configure this as true to clear the event store when a new date range has been requested instead of leaving it until the load of the new data to correct the store contents,

Setting this to true clears the event store prior to requesting the data load.

dateFormat: String= YYYY-MM-DD

The DateHelper format string to use to encode the start date and end date of the events to load when the view requires a new date range.

endDateParamName: String= endDate

The name of the HTTP parameter which contains the end date of the view requiring new data.

startDateParamName: String= startDate

The name of the HTTP parameter which contains the start date of the view requiring new data.

Misc

clientInstancePlugin
localeClassLocalizable
localizableLocalizable

Properties

16

Common

disabledInstancePlugin

Class hierarchy

isLoadOnDemand: Boolean= truereadonly
Identifies an object as an instance of LoadOnDemand class, or subclass thereof.
isLoadOnDemand: Boolean= truereadonlystatic
Identifies an object as an instance of LoadOnDemand class, or subclass thereof.
isCalendarFeatureCalendarFeature
isEventsEvents
isInstancePluginInstancePlugin
isLocalizableLocalizable

Lifecycle

configBase

Misc

clientInstancePlugin
localeHelperLocalizable
localeManagerLocalizable

Other

Functions

29

Other

Reloads the currently loaded date range.

If your app detects that the data may be stale, or needs to periodically refresh the data, this method may be used to issue a server request to reload the currently loaded date range.

LstaticLocalizable
onEvents
relayAllEvents
triggerEvents
unEvents

Configuration

applyDefaultsstaticBase

Events

Lifecycle

destroystaticBase

Misc

doDisableInstancePlugin
initClassstaticBase
isOfTypeNamestaticBase
mixinstaticBase
optionalLstaticLocalizable

Events

7

Fires when the LoadOnDemand feature has loaded a range of events.

// Adding a listener using the "on" method
loadOnDemand.on('dateRangeLoad', ({ response, options, startDate, endDate }) => {

});
ParameterTypeDescription
responseObject

The decoded JSON response.

optionsObject

The options object passed into the CrudManager CrudManager load method.

startDateDate

The start date of the range to request.

endDateDate

The end date of the range to request. Note that Dates are timestamps.

Fires when the LoadOnDemand feature detects that a request for data from the server has failed.

An event listener handler may produce an error UI.

If no handler returns false, then a default error UI is shown using MessageDialog.

// Adding a listener using the "on" method
loadOnDemand.on('loadOnDemandFail', ({ rawResponse, request, response }) => {

});
ParameterTypeDescription
rawResponseResponse

The HTTP fetch response object.

requestObject

The CrudManager load data block.

responseObject

The decoded JSON response.

catchAllEvents
destroyEvents
disableInstancePlugin
enableInstancePlugin

Event handlers

7

Called when the LoadOnDemand feature has loaded a range of events.

new LoadOnDemand({
    onDateRangeLoad({ response, options, startDate, endDate }) {

    }
});
ParameterTypeDescription
responseObject

The decoded JSON response.

optionsObject

The options object passed into the CrudManager CrudManager load method.

startDateDate

The start date of the range to request.

endDateDate

The end date of the range to request. Note that Dates are timestamps.

Called when the LoadOnDemand feature detects that a request for data from the server has failed.

An event listener handler may produce an error UI.

If no handler returns false, then a default error UI is shown using MessageDialog.

new LoadOnDemand({
    onLoadOnDemandFail({ rawResponse, request, response }) {

    }
});
ParameterTypeDescription
rawResponseResponse

The HTTP fetch response object.

requestObject

The CrudManager load data block.

responseObject

The decoded JSON response.

onDestroyEvents
onDisableInstancePlugin
onEnableInstancePlugin

Typedefs

1