Overview
Define custom JavaScript Scheduler event types
Customize the appearance depending on event type
Change event type using a context menu
Change event type using a modal dialog
License
This tutorial uses the open-source DayPilot Lite for JavaScript scheduling library.
Storing Event Type
The best place to store the event type (we are going to use type
property) is the tags
property of the event data object. Storing custom data under tags
avoids future conflicts with the reserved property names at the top level.
const events = [
{
id: 1,
text: "Event 1",
start: "2026-03-05T00:00:00",
end: "2026-03-09T00:00:00",
resource: "R2",
tags: {
type: "standard"
}
},
{
id: 2,
text: "Event 2",
start: "2026-03-07T00:00:00",
end: "2026-03-15T00:00:00",
resource: "R4",
tags: {
type: "important"
}
},
];
Appearance of Event Types
Now we need to define the appearance for the different event types. This can be done using onBeforeEventRender event handler. In this example, we use a custom background color (backColor
property) but you can add your own text/HTML, icons, CSS classes and so on.
onBeforeEventRender: args => {
const type = args.data.tags?.type;
switch (type) {
case "standard":
args.data.backColor = "#6aa84faa";
args.data.fontColor = "#fff";
break;
case "important":
args.data.backColor = "#f18832aa";
args.data.fontColor = "#fff";
break;
}
args.data.borderColor = "darker";
}
Changing Event Type using Context Menu
In this step, we will add an option to change the Scheduler event type using context menu. The context menu will display all event types and the current one will be highlighted using a checkmark icon.
Normally, the context menu items are pre-defined using the items property. But we need to generate the items from the list of event types and highlight the current type. We will use onShow event to modify the context menu items right before the menu is displayed:
contextMenu: new DayPilot.Menu({
items: [],
onShow: args => {
const e = args.source;
// generate menu items dynamically
scheduler.contextMenu.items = [
{text: "Edit...", onClick: async args => app.edit(args.source) },
{text: "-"}
];
app.types.forEach(type => {
const item = {
text: type.name,
onClick: args => app.changeType(args.source, type.id)
};
if (type.id === e.data.tags.type) {
item.symbol = "/icons/daypilot.svg#checkmark-2";
}
scheduler.contextMenu.items.push(item);
});
}
})
The changeType()
function changes the event data object and calls events.update()
to apply the changes:
changeType(e, type) {
e.data.tags.type = type;
scheduler.events.update(e);
},
Changing Event Type using Modal Dialog
First, we will configure the Scheduler to display a modal dialog with event details on click:
onEventClick: async args => app.edit(args.e),
The edit()
function opens a modal dialog using DayPilot.Modal.form(). You can design a custom modal dialog using DayPilot Modal Builder.
The modal form fields are mapped directly to the event data object (text
ang tags.type
properties).
const app = {
get form() {
return [
{ name: "Event name", id: "text" },
{ name: "Event type", id: "tags.type", type: "select", options: this.types },
];
},
types: [
{name: "Standard", id: "standard"},
{name: "Important", id: "important"},
],
async edit(e) {
const modal = await DayPilot.Modal.form(app.form, e.data);
if (modal.canceled) {
return;
}
scheduler.events.update(modal.result);
},
// ...
};
Full Source Code
And here is the full source code of the JavaScript Scheduler component displaying custom event types:
import {DayPilot} from "@daypilot/daypilot-lite-javascript";
const scheduler = new DayPilot.Scheduler("scheduler", {
timeHeaders: [{groupBy: "Month"}, {groupBy: "Day", format: "d"}],
scale: "Day",
days: 31,
startDate: "2026-03-01",
eventBorderRadius: 20,
durationBarVisible: false,
eventPadding: 10,
onTimeRangeSelected: async args => {
const data = {
text: "Event 1",
start: args.start,
end: args.end,
resource: args.resource,
id: DayPilot.guid(),
tags: {
type: "standard"
}
};
const modal = await DayPilot.Modal.form(app.form, data);
scheduler.clearSelection();
if (modal.canceled) { return; }
scheduler.events.add(modal.result);
},
onEventClick: async args => app.edit(args.e),
onBeforeEventRender: args => {
const type = args.data.tags?.type;
switch (type) {
case "standard":
args.data.backColor = "#6aa84faa";
args.data.fontColor = "#fff";
break;
case "important":
args.data.backColor = "#f18832aa";
args.data.fontColor = "#fff";
break;
}
args.data.borderColor = "darker";
args.data.areas = [
{
right: 6,
top: 6,
height: 24,
width: 24,
symbol: "/icons/daypilot.svg#minichevron-down-2",
action: "ContextMenu",
padding: 2,
fontColor: "#666",
backColor: "#ffffffdd",
borderRadius: "50%"
}
]
},
contextMenu: new DayPilot.Menu({
items: [],
onShow: args => {
const e = args.source;
// generate menu items dynamically
scheduler.contextMenu.items = [
{text: "Edit...", onClick: async args => app.edit(args.source) },
{text: "-"}
];
app.types.forEach(type => {
const item = {
text: type.name,
onClick: args => app.changeType(args.source, type.id)
};
if (type.id === e.data.tags.type) {
item.symbol = "/icons/daypilot.svg#checkmark-2";
}
scheduler.contextMenu.items.push(item);
});
}
}),
});
scheduler.init();
const app = {
get form() {
return [
{ name: "Event name", id: "text" },
{ name: "Event type", id: "tags.type", type: "select", options: this.types },
];
},
types: [
{name: "Standard", id: "standard"},
{name: "Important", id: "important"},
],
async edit(e) {
const modal = await DayPilot.Modal.form(app.form, e.data);
if (modal.canceled) {
return;
}
scheduler.events.update(modal.result);
},
changeType(e, type) {
e.data.tags.type = type;
scheduler.events.update(e);
},
init() {
const events = [
{
id: 1,
text: "Event 1",
start: "2026-03-05T00:00:00",
end: "2026-03-09T00:00:00",
resource: "R2",
tags: {
type: "standard"
}
},
{
id: 2,
text: "Event 2",
start: "2026-03-07T00:00:00",
end: "2026-03-15T00:00:00",
resource: "R4",
tags: {
type: "important"
}
},
];
const resources = [
{name: "Resource 1", id: "R1"},
{name: "Resource 2", id: "R2"},
{name: "Resource 3", id: "R3"},
{name: "Resource 4", id: "R4"},
{name: "Resource 5", id: "R5"},
{name: "Resource 6", id: "R6"},
{name: "Resource 7", id: "R7"},
{name: "Resource 8", id: "R8"},
{name: "Resource 9", id: "R9"},
];
scheduler.update({resources, events});
}
};
app.init();