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
Licensed for testing and evaluation purposes. Please see the license agreement included in the sample project. You can use the source code of the tutorial if you are a licensed user of DayPilot Pro for JavaScript.
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.
dp.events.list = [
{
id: 1,
text: "Event 1",
start: "2022-03-05T00:00:00",
end: "2022-03-09T00:00:00",
resource: "R2",
tags: {
type: "standard"
}
},
{
id: 2,
text: "Event 2",
start: "2022-03-07T00:00:00",
end: "2022-03-15T00:00:00",
resource: "R4",
tags: {
type: "important"
}
},
];
Appearance
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 duration bar color (barColor
property) but you can add your own text/HTML, icons, CSS classes and so on.
onBeforeEventRender: args => {
const type = args.data.tags && args.data.tags.type;
switch (type) {
case "standard":
args.data.barColor = "#38761d";
args.data.barBackColor = "#38761d";
break;
case "important":
args.data.barColor = "#cc0000";
args.data.barBackColor = "#cc0000";
break;
}
},
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
dp.contextMenu.items = [
{text: "Edit...", onClick: async args => edit(args.source) },
{text: "-"}
];
types.forEach(type => {
const item = {
text: type.name,
onClick: args => changeType(args.source, type.id)
};
if (type.id === e.data.tags.type) {
item.image = "svg/checkmark-17.svg";
}
dp.contextMenu.items.push(item);
});
}
}),
The changeType()
function changes the event data object and calls events.update()
to apply the changes:
function changeType(e, type) {
e.data.tags.type = type;
dp.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 => 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 types = [
{name: "Standard", id: "standard"},
{name: "Important", id: "important"},
];
const form = [
{name: "Event name", id: "text"},
{name: "Event type", id: "tags.type", type: "select", options: types}
];
async function edit(e) {
const modal = await DayPilot.Modal.form(form, e.data);
if (modal.canceled) {
return;
}
dp.events.update(modal.result);
}
Full Source Code
And here is the full source code of the JavaScript Scheduler component displaying custom event types:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>JavaScript Scheduler: Event Types</title>
<!-- DayPilot library -->
<script src="js/daypilot/daypilot-all.min.js"></script>
</head>
<body>
<div class="header">
<h1><a href='https://code.daypilot.org/96153/javascript-scheduler-event-types'>JavaScript Scheduler: Event Types</a></h1>
<div><a href="https://javascript.daypilot.org/">DayPilot for JavaScript</a> - HTML5 Calendar/Scheduling Components for JavaScript/Angular/React/Vue</div>
</div>
<div class="main">
<div id="dp"></div>
<div class="generated">Generated using <a href="https://builder.daypilot.org/">DayPilot UI Builder</a>.</div>
</div>
<script>
const types = [
{name: "Standard", id: "standard"},
{name: "Important", id: "important"},
];
const form = [
{name: "Event name", id: "text"},
{name: "Event type", id: "tags.type", type: "select", options: types}
];
const dp = new DayPilot.Scheduler("dp", {
timeHeaders: [{"groupBy":"Month"},{"groupBy":"Day","format":"d"}],
scale: "Day",
days: 31,
startDate: "2022-03-01",
timeRangeSelectedHandling: "Enabled",
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(form, data);
dp.clearSelection();
if (modal.canceled) { return; }
console.log("modal.result", modal.result);
dp.events.add(modal.result);
},
onBeforeEventRender: args => {
const type = args.data.tags && args.data.tags.type;
switch (type) {
case "standard":
args.data.barColor = "#38761d";
args.data.barBackColor = "#38761d";
break;
case "important":
args.data.barColor = "#cc0000";
args.data.barBackColor = "#cc0000";
break;
}
args.data.areas = [
{
right: 5,
top: 10,
height: 16,
width: 16,
symbol: "svg/daypilot.svg#minichevron-down-2",
action: "ContextMenu",
fontColor: "#ccc",
style: "border: 1px solid #ccc"
}
]
},
contextMenu: new DayPilot.Menu({
items: [],
onShow: args => {
const e = args.source;
// generate menu items dynamically
dp.contextMenu.items = [
{text: "Edit...", onClick: async args => edit(args.source) },
{text: "-"}
];
types.forEach(type => {
const item = {
text: type.name,
onClick: args => changeType(args.source, type.id)
};
if (type.id === e.data.tags.type) {
item.image = "svg/checkmark-17.svg";
}
dp.contextMenu.items.push(item);
});
}
}),
treeEnabled: true,
});
dp.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"},
];
dp.events.list = [
{
id: 1,
text: "Event 1",
start: "2022-03-05T00:00:00",
end: "2022-03-09T00:00:00",
resource: "R2",
tags: {
type: "standard"
}
},
{
id: 2,
text: "Event 2",
start: "2022-03-07T00:00:00",
end: "2022-03-15T00:00:00",
resource: "R4",
tags: {
type: "important"
}
},
];
dp.init();
async function edit(e) {
const modal = await DayPilot.Modal.form(form, e.data);
if (modal.canceled) {
return;
}
dp.events.update(modal.result);
}
function changeType(e, type) {
e.data.tags.type = type;
dp.events.update(e);
}
</script>
</body>
</html>