Customizing the Event, Schedule, and TimeAxis header menus
Bryntum Scheduler ships with built-in context menus for the locked grid cells and column headers, for events, and for the schedule zone and its header. All the context menu features are customizable. The Scheduler is built upon the Grid, so customization of the Cell menu and the Header menu can be found in the Grid docs.
Customization of the Event menu, the Schedule menu, and the TimeAxisHeader menu are similar to the context menus in Grid. and you will find more details about it in this guide.
Right-click an event, the schedule zone behind the event which is called "TimeAxis", and the header of the TimeAxis in the demo below to see it in action:
//<code-header>
fiddle.title = 'Basic menu';
//</code-header>
const scheduler = new Scheduler({
appendTo : targetElement,
autoHeight : true,
rowHeight : 40,
barMargin : 4,
startDate : new Date(2018, 4, 6),
endDate : new Date(2018, 4, 13),
viewPreset : {
base : 'dayAndWeek',
timeColumnWidth : 30
},
columns : [
{ field : 'name', text : 'Name', width : 100 }
],
resources : [
{ id : 1, name : 'Bernard' },
{ id : 2, name : 'Bianca' }
],
events : [
{ id : 1, resourceId : 1, name : 'Right click me, the area behind me, and the header of the timeaxis', startDate : '2018-05-07', endDate : '2018-05-12' }
]
});The menus can be customized, turned off or replaced with your own implementation (see the "Replace context menus" guide).
Turning the menus off entirely
The menus are supplied by corresponding features: EventMenu feature provides menu for events,
ScheduleMenu feature provides menu for the schedule zone,
TimeAxisHeaderMenu feature provides menu for the header of the schedule zone.
These features are enabled by default. To turn a feature off, configure it with false:
const scheduler = new Scheduler({
features : {
// Turn the Event menu off completely, will not be created
eventMenu : false,
// Turn the Schedule menu off completely, will not be created
scheduleMenu : false,
// Turn the TimeAxis Header menu off completely, will not be created
timeAxisHeaderMenu : false
}
});
Enabling or disabling the menus
You can also enable or disable any of the provided menus programmatically, perhaps depending on user rights:
const scheduler = new Scheduler({
features : {
eventMenu : {
// The Event menu is created, but starts disabled
disabled : true
},
scheduleMenu : {
// The Schedule menu is created, but starts disabled
disabled : true
},
timeAxisHeaderMenu : {
// The TimeAxis Header menu is created, but starts disabled
disabled : true
}
}
});
// To enable
scheduler.features.eventMenu.disabled = false;
scheduler.features.scheduleMenu.disabled = false;
scheduler.features.timeAxisHeaderMenu.disabled = false;
// To disable again
scheduler.features.eventMenu.disabled = true;
scheduler.features.scheduleMenu.disabled = true;
scheduler.features.timeAxisHeaderMenu.disabled = true;
Try it in the demo below:
//<code-header>
fiddle.title = 'Disable menu feature';
//</code-header>
const scheduler = new Scheduler({
appendTo : targetElement,
autoHeight : true,
rowHeight : 40,
barMargin : 4,
flex : 1,
tbar : [
{
text : 'Event menu',
toggleable : true,
icon : 'fa fa-square',
pressedIcon : 'fa fa-check-square',
onToggle({ pressed }) {
scheduler.features.eventMenu.disabled = !pressed;
}
},
{
text : 'Schedule menu',
style : 'margin-inline-start: 10px',
toggleable : true,
icon : 'fa fa-square',
pressedIcon : 'fa fa-check-square',
onToggle({ pressed }) {
scheduler.features.scheduleMenu.disabled = !pressed;
}
},
{
text : 'TimeAxis Header menu',
style : 'margin-inline-start: 10px',
toggleable : true,
icon : 'fa fa-square',
pressedIcon : 'fa fa-check-square',
onToggle({ pressed }) {
scheduler.features.timeAxisHeaderMenu.disabled = !pressed;
}
}
],
startDate : new Date(2018, 4, 6),
endDate : new Date(2018, 4, 13),
viewPreset : {
base : 'dayAndWeek',
timeColumnWidth : 30
},
columns : [
{ field : 'name', text : 'Name', width : 100 }
],
resources : [
{ id : 1, name : 'Bernard' },
{ id : 2, name : 'Bianca' }
],
events : [
{
id : 1,
resourceId : 1,
name : 'Right click me, the area behind me, and the header of the timeaxis',
startDate : '2018-05-07',
endDate : '2018-05-12'
}
],
features : {
eventMenu : {
disabled : true
},
scheduleMenu : {
disabled : true
},
timeAxisHeaderMenu : {
disabled : true
}
}
});Customizing the menu items
The menu items in the Event menu, in the Schedule menu, and in the TimeAxis Header menu can be customized,
existing items can be changed or removed, and new items can be added. This is handled using the items config of the features.
Default event menu items
Here is the list of menu items provided by the EventMenu feature and populated by the other features:
| Reference | Text | Weight | Feature | Description |
|---|---|---|---|---|
editEvent | Edit event | 100 | EventEdit | Edit in the event editor. Hidden when read-only |
copyEvent | Copy event | 110 | EventCopyPaste | Copy event or assignment. Hidden when read-only |
cutEvent | Cut event | 120 | EventCopyPaste | Cut event or assignment. Hidden when read-only |
deleteEvent | Delete event | 200 | EventMenu | Remove event. Hidden when read-only |
unassignEvent | Unassign event | 300 | EventMenu | Unassign event. Hidden when read-only, shown for multi-assignment |
splitEvent | Split event | 650 | Scheduler Pro only | Split an event into two segments at the mouse position |
renameSegment | Rename segment | 660 | Scheduler Pro only | Show an inline editor to rename the segment |
eventColor | Color | 400 | EventMenu | Choose background color for the event bar |
Default scheduler zone menu items
The ScheduleMenu feature provides only one item:
| Reference | Text | Weight | Feature | Description |
|---|---|---|---|---|
addEvent | Add event | 100 | ScheduleMenu | Add a new event for the hovered resource starting at the clicked point in time. Hidden if the Scheduler is read-only |
Default timeaxis header menu items
Here is the list of menu items provided by the TimeAxisHeaderMenu feature and populated by the other features:
| Reference | Text | Weight | Feature | Description |
|---|---|---|---|---|
eventsFilter | Filter tasks | 100 | EventFilter | Submenu for event filtering |
>nameFilter | By name | 110 | EventFilter | Filter by name |
zoomLevel | Zoom | 200 | TimeAxisHeaderMenu | Submenu for timeline zooming |
>zoomSlider | - | 210 | TimeAxisHeaderMenu | Changes current zoom level |
dateRange | Date range | 300 | TimeAxisHeaderMenu | Submenu for timeline range |
>startDateField | Start date | 310 | TimeAxisHeaderMenu | Start date for the timeline |
>endDateField | End date | 320 | TimeAxisHeaderMenu | End date for the timeline |
>leftShiftBtn | < | 330 | TimeAxisHeaderMenu | Shift backward |
>todayBtn | Today | 340 | TimeAxisHeaderMenu | Go to today |
>rightShiftBtn | > | 350 | TimeAxisHeaderMenu | Shift forward |
currentTimeLine | Show current timeline | 400 | TimeRanges | Show current time line |
- >
- first level of submenu
Removing default items
To remove a default item no matter if it is provided by a context menu feature, or it is provided by another feature,
configure it as false in the items config of the context menu feature:
const scheduler = new Scheduler({
features : {
eventMenu : {
items : {
// Remove "Edit event" item provided by EventEdit feature
editEvent : false
}
},
scheduleMenu : {
items : {
// Remove "Add event" default item
addEvent : false
}
},
timeAxisHeaderMenu : {
items : {
// Remove "Filter tasks" item provided by EventFilter feature
eventsFilter : false
}
}
}
});
Removing subitems of the TimeAxis Header Menu is not supported.
//<code-header>
fiddle.title = 'Disable menu items';
//</code-header>
const scheduler = new Scheduler({
appendTo : targetElement,
autoHeight : true,
rowHeight : 40,
barMargin : 4,
startDate : new Date(2018, 4, 6),
endDate : new Date(2018, 4, 13),
viewPreset : {
base : 'dayAndWeek',
timeColumnWidth : 30
},
columns : [
{ field : 'name', text : 'Name', width : 100 }
],
resources : [
{ id : 1, name : 'Bernard' },
{ id : 2, name : 'Bianca' }
],
events : [
{ id : 1, resourceId : 1, name : 'Right click me, the area behind me, and the header of the timeaxis', startDate : '2018-05-07', endDate : '2018-05-12' }
],
features : {
eventMenu : {
items : {
// Remove "Edit event" item provided by EventEdit feature
editEvent : false
}
},
scheduleMenu : {
items : {
// Remove "Add event" default item
addEvent : false
}
},
timeAxisHeaderMenu : {
items : {
// Remove "Filter tasks" item provided by EventFilter feature
eventsFilter : false
}
}
}
});Customize default items
The default items can be customized by supplying config objects for them in the items config of the menu feature.
These config objects will be merged with their default configs. Similar to removing default items, it does not matter,
if the item is provided by the menu feature or not.
The order of the default items is determined by the weight property. The higher the weight, the further down they are
displayed. See the table above for the default weights.
For example, to rename the "Date range" item and move it above the "Zoom" item:
const scheduler = new Scheduler({
features : {
timeAxisHeaderMenu : {
items : {
// Rename and move "Date range" item to be above "Zoom" item (200)
dateRange : {
text : 'Start/End',
weight : 190
}
}
}
}
});
Try it out in this demo:
//<code-header>
fiddle.title = 'Customize menu items';
//</code-header>
const scheduler = new Scheduler({
appendTo : targetElement,
autoHeight : true,
rowHeight : 40,
barMargin : 4,
startDate : new Date(2018, 4, 6),
endDate : new Date(2018, 4, 13),
viewPreset : {
base : 'dayAndWeek',
timeColumnWidth : 30
},
columns : [
{ field : 'name', text : 'Name', width : 100 }
],
resources : [
{ id : 1, name : 'Bernard' },
{ id : 2, name : 'Bianca' }
],
events : [
{ id : 1, resourceId : 1, name : 'Right click the header of the timeaxis', startDate : '2018-05-07', endDate : '2018-05-12' }
],
features : {
timeAxisHeaderMenu : {
items : {
// Rename and move "Date range" item to be above "Zoom" item (200)
dateRange : {
text : 'Start/End',
weight : 190
}
}
}
}
});Add custom items
Custom items are added in the same way as you customize the built-in ones, add new properties to the items
config of the menu feature to add new items. The key you choose to use for your item will be used as its ref,
through which it can be accessed later.
Here we add a custom item to the event menu to move the selected task 1 hour forward:
const scheduler = new Scheduler({
features : {
eventMenu : {
items : {
// Custom reference to the new menu item
moveForward : {
text : 'Move 1 hour ahead',
cls : 'b-separator', // Add a visual line above the item
weight : 400, // Add the item to the bottom
onItem : ({ eventRecord }) => {
eventRecord.shift(1, 'hour');
}
}
}
}
}
});
Try new custom items here:
//<code-header>
fiddle.title = 'Add menu items';
//</code-header>
const scheduler = new Scheduler({
appendTo : targetElement,
autoHeight : true,
rowHeight : 40,
barMargin : 4,
startDate : new Date(2018, 4, 6),
endDate : new Date(2018, 4, 13),
viewPreset : {
base : 'dayAndWeek',
timeColumnWidth : 30
},
columns : [{
field : 'name',
text : 'Name',
width : 100,
htmlEncode : false,
renderer : ({ record, value }) => value + (record.star ? '<i class="fa fa-star"></i>' : '')
}],
resourceStore : {
fields : [{ name : 'star', type : 'boolean', defaultValue : false }],
data : [
{ id : 1, name : 'Bernard' },
{ id : 2, name : 'Bianca' }
]
},
events : [
{ id : 1, resourceId : 1, name : 'Right click me', startDate : '2018-05-07', endDate : '2018-05-12' }
],
features : {
eventMenu : {
items : {
// Custom reference to the new menu item
moveForward : {
text : 'Move 1 hour ahead',
icon : 'fa fa-long-arrow-alt-right',
cls : 'b-separator', // Add a visual line above the item
weight : 400, // Add the item to the bottom
onItem : ({ eventRecord }) => {
eventRecord.shift(1, 'hour');
}
}
}
},
resourceTimeRanges : true,
scheduleMenu : {
items : {
// Custom reference to the new menu item
timeBreak : {
text : 'Add a day off',
icon : 'fa fa-shield-virus',
cls : 'b-separator', // Add a visual line above the item
weight : 200, // Add the item to the bottom
onItem : ({ date, resourceRecord }) => {
scheduler.resourceTimeRangeStore.add({
resourceId : resourceRecord.id,
name : 'Day off',
startDate : new Date(date.getFullYear(), date.getMonth(), date.getDate()),
duration : 1,
timeRangeColor : 'blue'
});
}
}
}
},
timeRanges : true,
timeAxisHeaderMenu : {
items : {
// Custom reference to the new menu item
ventilationBreak : {
text : 'Room ventilation',
icon : 'fa fa-shield-virus',
cls : 'b-separator', // Add a visual line above the item
weight : 500, // Add the item to the bottom
onItem : ({ event }) => {
const date = scheduler.getDateFromDomEvent(event);
scheduler.project.timeRangeStore.add({
startDate : new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours()),
duration : 2,
durationUnit : 'h'
});
}
}
}
},
cellMenu : {
items : {
// Custom reference to the new cell items
star : {
text : 'Give a star',
icon : 'fa fa-star',
cls : 'b-separator', // Add a visual line above the item
weight : 500, // Add the item to the bottom
onItem : ({ record }) => {
record.star = true;
}
},
removeStar : {
text : 'Remove star',
icon : 'fa fa-star-half-alt',
cls : 'b-separator', // Add a visual line above the item
weight : 500, // Add the item to the bottom
onItem : ({ record }) => {
record.star = false;
}
}
},
// Process cell items before showing the menu
processItems({ items, record }) {
// Hide either star or removeStar item
if (record.star) {
items.star = false;
}
else {
items.removeStar = false;
}
}
},
headerMenu : {
items : {
// Custom reference to the new cell items
star : {
text : 'Add a new guy',
icon : 'fa fa-plus',
weight : 10, // Add the item to the top
onItem : () => {
scheduler.resourceStore.add({
name : 'New employee'
});
}
}
}
}
}
});Runtime control of menu item visibility
If you need to control menu item visibility or text depending on a dynamic condition, for example user access rights,
you can mutate items in the processItems hook provided by the menu.
Here we disable "Edit event", "Delete event", "Unassign event", and "Add event" items based on a condition:
let accessGranted = false;
const scheduler = new Scheduler({
features : {
eventMenu : {
// Process event items before showing the menu
processItems({ items }) {
// Not possible to edit, delete, or change event assignments if there are no rights for it
if (!accessGranted) {
items.editEvent = false;
items.deleteEvent = false;
items.unassignEvent = false;
}
}
},
scheduleMenu : {
// Process schedule zone items before showing the menu
processItems({ items }) {
// Not possible to add new events if there are no rights for it
if (!accessGranted) {
items.addEvent = false;
}
}
}
}
});
See it in action in this demo:
//<code-header>
fiddle.title = 'Dynamic menu';
//</code-header>
let accessGranted = false;
const scheduler = new Scheduler({
appendTo : targetElement,
autoHeight : true,
rowHeight : 40,
barMargin : 4,
flex : 1,
startDate : new Date(2018, 4, 6),
endDate : new Date(2018, 4, 13),
viewPreset : {
base : 'dayAndWeek',
timeColumnWidth : 30
},
columns : [
{ field : 'name', text : 'Name', width : 100 }
],
resources : [
{ id : 1, name : 'Bernard' },
{ id : 2, name : 'Bianca' }
],
events : [
{
id : 1,
resourceId : 1,
name : 'Right click me and the area behind me',
startDate : '2018-05-07',
endDate : '2018-05-12'
}
],
features : {
eventMenu : {
// Process event items before showing the menu
processItems({ items, column, record }) {
// Not possible to edit, delete, or change event assignments if there are no rights for it
if (!accessGranted) {
items.editEvent = false;
items.deleteEvent = false;
items.unassignEvent = false;
}
}
},
scheduleMenu : {
// Process schedule zone items before showing the menu
processItems({ items }) {
// Not possible to add new events if there are no rights for it
if (!accessGranted) {
items.addEvent = false;
}
}
}
},
tbar : [
{
text : 'Limited rights',
toggleable : true,
pressed : !accessGranted,
icon : 'fa fa-square',
pressedIcon : 'fa fa-check-square',
onToggle({ pressed }) {
accessGranted = !pressed;
}
}
]
});