Customizing the event editor

Bryntum Calendar ships with a built-in, themeable event editor, double-click the event in the demo below to see it in action:

Basic event editor
//<code-header>
fiddle.title = 'Basic event editor';
//</code-header>
const scheduler = new Calendar({
    appendTo : targetElement,
    height   : 600,

    // We have a little less width in our context, so reduce the responsive breakpoints
    responsive : {
        small : {
            when : 480
        },
        medium : {
            when : 640
        }
    },

    // Not enough space in this context for all modes
    modes : {
        agenda : null
    },

    // Hardcoded inline data - use for POC only.
    // Use CrudManager in implementation.
    resources : [
        { id : 1, name : 'Mr Boss' }
    ],
    events : [
        { resourceId : 1, startDate : '2020-08-31T09:00:00', duration : 3, durationUnit : 'h', name : 'Important meeting' }
    ],

    visibleStartTime : 7,

    // Start life looking at this date
    date : '2020-08-31',

    features : {
        // So as not to interfere with the editor
        eventTooltip : null
    }
});

The editor, and all the widgets within it are styled with SASS, and the values for all parts of the UI are determined by SASS variables so the editor can easily be styled to fit in with any existing design. The full replacement of the editor should not be needed.

The widgets inside the editor can all be reconfigured or removed very simply using the EventEditor feature's items config option.

See the Bryntum custom event editor example for how to theme and reconfigure an event editor.

As a final fallback, the editor can be replaced with your own editor (see the "Replace the event editor" guide).

Turning the editor off entirely

The event editor is supplied by a feature called EventEdit, which is enabled by default. To turn it off, configure the feature with false:

const calendar = new Calendar({
    features : {
        // Turn the editor off completely, won't be created
        eventEdit : false
    }
});

Enabling or disabling the editor

You can also enable or disable the editor programmatically, perhaps as a response to a login:

const calendar = new Calendar({
    features : {
        eventEdit : {
            // Start disabled
            disabled : true
        }
    }
});

// To enable
calendar.features.eventEdit.disabled = false;

// To disable again
calendar.features.eventEdit.disabled = true;

Try it in the demo below:

Disable event editor
//<code-header>
fiddle.title = 'Disable event editor';
//</code-header>
const scheduler = new Calendar({
    appendTo : targetElement,
    height   : 600,

    features : {
        eventEdit : {
            disabled : true
        }
    },

    // We have a little less width in our context, so reduce the responsive breakpoints
    responsive : {
        small : {
            when : 480
        },
        medium : {
            when : 640
        }
    },

    // Add an extra button which toggles availability of event editing
    tbar : {
        items : {
            toggleEditable : {
                text        : 'Disable editor',
                toggleable  : true,
                pressed     : true,
                icon        : 'fa fa-square',
                pressedIcon : 'fa fa-check-square',
                rendition   : 'filled',
                onToggle({ pressed }) {
                    scheduler.features.eventEdit.disabled = pressed;
                }
            }
        }
    },

    // Hardcoded inline data - use for POC only.
    // Use CrudManager in implementation.
    resources : [
        { id : 1, name : 'Mr Boss' }
    ],
    events : [
        { resourceId : 1, startDate : '2020-08-31T09:00:00', duration : 3, durationUnit : 'h', name : 'Important meeting' }
    ],

    // Start life looking at this date
    date : '2020-08-31',

    visibleStartTime : 7
});

Customizing the fields

The fields in the editor can be customized, existing fields can be changed or removed and new fields can be added. This is handled using the items config of the feature.

Default fields

By default, the editor contains the following fields:

Field refTypeWeightDescription
nameFieldTextField100Edit name
resourceFieldCombo200Pick calendar
allDaySlideToggle250Set/clear the all day boolean field
startDateFieldDateField300Edit startDate (date part)
startTimeFieldTimeField400Edit startDate (time part)
endDateFieldDateField500Edit endDate (date part)
endTimeFieldTimeField600Edit endDate (time part)
recurrenceComboCombo700Select recurrence rule (only visible if recurrence is used)
editRecurrenceButtonButton800Edit the recurrence rule (only visible if recurrence is used)

The resourceField is what assigns an event to a "calendar". Events are assigned to "resources". These may be for example rooms, or machines.

Customizing the default buttons

By default, the editor has the following buttons:

Widget refTypeWeightDescription
saveButtonButton100Save event button in the bottom toolbar
deleteButtonButton200Delete event button in the bottom toolbar
cancelButtonButton300Cancel event button in the bottom toolbar

The buttons can be customized using the bbar config in the editorConfig config of the feature.

Removing default fields

To remove default fields, configure them as null in the items config of the feature:

const calendar = new Calendar({
    features : {
        eventEdit : {
            items : {
                // Remove startTimeField and endTimeField
                startTimeField : null,
                endTimeField   : null
            }
        }
    }
});

This demo has the time fields removed:

Remove editor fields
//<code-header>
fiddle.title = 'Remove editor fields';
//</code-header>
const scheduler = new Calendar({
    appendTo : targetElement,
    height   : 600,

    // We have a little less width in our context, so reduce the responsive breakpoints
    features : {
        eventEdit : {
            // Our definition of its child items is merged over the provided one
            items : {
                startTimeField : null,
                endTimeField   : null
            }
        },

        // So as not to interfere with the editor
        eventTooltip : null
    },

    responsive : {
        small : {
            when : 480
        },
        medium : {
            when : 640
        }
    },

    // Hardcoded inline data - use for POC only.
    // Use CrudManager in implementation.
    resources : [
        { id : 1, name : 'Mr Boss' }
    ],
    events : [
        { resourceId : 1, startDate : '2020-08-31T09:00:00', duration : 3, durationUnit : 'h', name : 'Important meeting' }
    ],

    // Start life looking at this date
    date : '2020-08-31',

    visibleStartTime : 7
});

To remove fields related to recurring events configuration (such as recurrenceCombo), set showRecurringUI config to false.

Customize default fields

The default fields can be customized by supplying config objects for them in the items config of the feature. These config objects will be merged with their default configs.

The order of the default fields is determined by a weight. The higher the weight, the further down they are displayed. See the table above for the default weights.

For example to change the label of the nameField and move the calendar picker to the top:

const calendar = new Calendar({
    features : {
        eventEdit : {
            items : {
                // Change the label of the nameField
                nameField : {
                    label : 'Title'
                },
                // Move the calendar picker to the top
                // It's name is "resourceField" because Calendars are the assigned resources.
                resourceField : {
                    weight : 0
                }
            }
        }
    }
});

Try it out in this demo:

Custom editor labels
//<code-header>
fiddle.title = 'Custom editor labels';
//</code-header>
const scheduler = new Calendar({
    appendTo : targetElement,
    height   : 600,

    features : {
        eventEdit : {
            // Our definition of its child items is merged over the provided one
            items : {
                nameField : {
                    label : 'Title'
                },
                resourceField : {
                    weight : 0
                }
            }
        },

        // So as not to interfere with the editor
        eventTooltip : null
    },

    // We have a little less width in our context, so reduce the responsive breakpoints
    responsive : {
        small : {
            when : 480
        },
        medium : {
            when : 640
        }
    },

    // Hardcoded inline data - use for POC only.
    // Use CrudManager in implementation.
    resources : [
        { id : 1, name : 'Mr Boss' }
    ],
    events : [
        { resourceId : 1, startDate : '2020-08-31T09:00:00', duration : 3, durationUnit : 'h', name : 'Important meeting' }
    ],

    visibleStartTime : 7,

    // Start life looking at this date
    date : '2020-08-31'
});

Add custom fields

Custom fields are added in the same way as you use to customize the built-in ones, add new properties to the items config of the feature to add new fields. The key you choose to use for your field will be used as its ref, through which it can be accessed later.

Here we add a custom field to edit notes on the event to the editor:

const calendar = new Calendar({
    features : {
        eventEdit : {
            items : {
                // Custom field to edit notes about the event
                noteField : {
                    // Type of field to use
                    type : 'textarea',
                    // Label to show for the field
                    label : 'Notes',
                    // Name of the field in the event record to read/write data to
                    // NOTE: Make sure your EventModel has this field for this to link up correctly
                    name : 'note'
                }
            }
        }
    }
});

Update custom fields state and data

Event Editor uses items configuration only once during first initialization. If you need to refresh data in combobox or hide/show fields depending on your business logic on editor reopen, use beforeEventEditShow event:

const calendar = new Calendar({
    features : {
        eventEdit : {
            items : {
                equipment : {
                    // custom field configuration
                },
                volume : {
                    // custom field configuration
                }
            }
        }
    },
    listeners : {
        beforeEventEditShow({ editor, eventRecord }) {
            const
                equipmentCombo = editor.widgetMap.equipment,
                volumeField = editor.widgetMap.volume;

            // update data in combo list
            equipmentCombo.items = this.equipmentStore.getRange();
            // update field visibility state
            volumeField.hidden = !eventRecord.hasVolume;
        }
    }
});

Try the custom field here:

Custom editor field
//<code-header>
fiddle.title = 'Custom editor field';
//</code-header>
const scheduler = new Calendar({
    appendTo : targetElement,
    height   : 600,

    features : {
        eventEdit : {
            // Our definition of its child items is merged over the provided one
            items : {
                // Custom field to edit notes about the event
                noteField : {
                    // Type of field to use
                    type  : 'text',
                    // Label to show for the field
                    label : 'Notes',
                    // Name of the field in the event record to read/write data to.
                    // This name is matched with the name of the field in the event record.
                    // NOTE: Make sure your EventModel has this field for this to link up correctly
                    name  : 'note'
                }
            }
        },

        // So as not to interfere with the editor
        eventTooltip : null
    },

    // We have a little less width in our context, so reduce the responsive breakpoints
    responsive : {
        small : {
            when : 480
        },
        medium : {
            when : 640
        }
    },

    // Hardcoded inline data - use for POC only.
    // Use CrudManager in implementation.
    resources : [
        { id : 1, name : 'Mr Boss' }
    ],
    events : [
        { resourceId : 1, startDate : '2020-08-31T09:00:00', duration : 3, durationUnit : 'h', name : 'Important meeting', note : 'Wear a tie!' }
    ],

    // Start life looking at this date
    date : '2020-08-31',

    visibleStartTime : 7
});