Overview
Use Vue templates to create custom layouts and content for Scheduler cells.
Display reservation prices for each Scheduler slot dynamically.
Assign each resource to one of three pricing plans (Bronze, Silver, or Gold).
Define slot prices for each day of the week (Sunday to Saturday) in the pricing plans.
Calculate total reservation costs based on multi-day bookings using the
getPriceForSlot()
method.This Vue project includes a trial version of DayPilot Pro for JavaScript (see License below).
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. Buy a license.
Customize Cells using Vue Templates
The Vue Scheduler component lets you customize the grid cell content using Vue templates.
<template>
<DayPilotScheduler
:events="events"
:resources="resources"
...
>
<template #cell="args">
<div style="inset:0; position: absolute; display: flex; justify-content: center; align-items: center; color: #d0d0d0;">
${{ getPriceForSlot(args.cell.start, args.cell.end, args.cell.resource) }}
</div>
</template>
</DayPilotScheduler>
</template>
In addition to Vue templates, it is also possible to use the onBeforeCellRender event handler to customize the grid cells.
For example, in the PHP Tennis Court Reservation tutorial, the onBeforeCellRender
event is used to display slot prices for each hour of tennis court usage.
The args
object with cell details that is available in the Vue template uses the same structure as the args
parameter of the onBeforeCellRender
event.
Define Pricing Plans for Resource Usage
In our reservation scheduler view, we display the following resources:
const resources = ref([
{ name: "Resource 1", id: "R1", plan: "Bronze" },
{ name: "Resource 2", id: "R2", plan: "Bronze" },
{ name: "Resource 3", id: "R3", plan: "Bronze" },
{ name: "Resource 4", id: "R4", plan: "Silver" },
{ name: "Resource 5", id: "R5", plan: "Silver" },
{ name: "Resource 6", id: "R6", plan: "Silver" },
{ name: "Resource 7", id: "R7", plan: "Silver" },
{ name: "Resource 8", id: "R8", plan: "Gold" },
{ name: "Resource 9", id: "R9", plan: "Gold" }
]);
Each resource has an associated pricing plan (plan
property). The plans specify prices for each day of week:
const pricingPlans = {
// Sunday -> Saturday
"Bronze": [80, 80, 80, 80, 80, 100, 100],
"Silver": [110, 110, 110, 120, 120, 130, 130],
"Gold": [140, 150, 150, 160, 160, 180, 200]
};
Calculate Slot Prices
The price for slot usage is calculated using the getPriceForSlot()
function:
const getPriceForSlot = (start, end, resourceId) => {
const resource = resources.value.find(r => r.id === resourceId);
if (!resource) return 0;
const rates = pricingPlans[resource.plan];
if (!rates) return 0; // plan not found
let totalPrice = 0;
let current = new DayPilot.Date(start);
while (current < end) {
const dow = current.getDayOfWeek();
const dailyRate = rates[dow] || 0;
const dayEnd = current.addDays(1).getDatePart();
const segmentEnd = dayEnd < end ? dayEnd : end;
const hoursInSegment = new DayPilot.Duration(current, segmentEnd).totalHours();
totalPrice += dailyRate * (hoursInSegment / 24);
current = segmentEnd;
}
return Math.round(totalPrice);
};
This function loads the pricing plan associated with a resource and gets the price depending on the day of week.
This function is called for every slot, which has exactly one day. But the implementation is generic and it can be used for arbitrary time ranges. Later, we will use it to calculate the total price for reservations spanning multiple days.
Calculate Total Price for Reservations
In this step, we will use the getPriceForSlot()
function in an event Vue template to display the total price for each reservation.
A reservation can span multiple days, and the getPriceForSlot()
method adds the correct price for each day to the total. The total is then displayed on the right side of an event using a Vue template:
<template>
<DayPilotScheduler
:events="events"
:resources="resources"
...
>
...
<template #event="{event}">
<div style="display: flex; justify-content: space-between; align-items: center; position: absolute; inset:0; padding: 0px 5px;">
<!-- Left side -->
<span>{{ event.data.text }}</span>
<!-- Right side -->
<span style="font-weight: bold;">
${{ getPriceForSlot(event.start(), event.end(), event.resource()) }}
</span>
</div>
</template>
</DayPilotScheduler>
</template>
Full Source Code
Here is the full source code of our Vue Scheduler component that displays slot prices using Vue templates:
<template>
<DayPilotScheduler
:events="events"
:resources="resources"
:scale="'Day'"
:startDate="startDate"
:days="days"
:timeHeaders="[ { groupBy: 'Month' }, { groupBy: 'Day', format: 'd' } ]"
:durationBarVisible="false"
:eventBorderRadius="5"
:eventHeight="40"
:cellWidth="60"
:rowHeaderColumns="[
{ name: 'Resource', display: 'name' },
{ name: 'Plan', display: 'plan' }
]"
@timeRangeSelected="onTimeRangeSelected"
@beforeEventRender="onBeforeEventRender"
ref="schedulerRef"
>
<template #cell="args">
<div style="inset:0; position: absolute; display: flex; justify-content: center; align-items: center; color: #d0d0d0;">
${{ getPriceForSlot(args.cell.start, args.cell.end, args.cell.resource) }}
</div>
</template>
<template #event="{event}">
<div style="display: flex; justify-content: space-between; align-items: center; position: absolute; inset:0; padding: 0px 5px;">
<!-- Left side -->
<span>{{ event.data.text }}</span>
<!-- Right side -->
<span style="font-weight: bold;">
${{ getPriceForSlot(event.start(), event.end(), event.resource()) }}
</span>
</div>
</template>
</DayPilotScheduler>
</template>
<script setup>
import { DayPilot, DayPilotScheduler } from 'daypilot-pro-vue';
import { ref, onMounted } from 'vue';
const pricingPlans = {
// Sunday -> Saturday
"Bronze": [80, 80, 80, 80, 80, 100, 100],
"Silver": [110, 110, 110, 120, 120, 130, 130],
"Gold": [140, 150, 150, 160, 160, 180, 200]
};
const resources = ref([
{ name: "Resource 1", id: "R1", plan: "Bronze" },
{ name: "Resource 2", id: "R2", plan: "Bronze" },
{ name: "Resource 3", id: "R3", plan: "Bronze" },
{ name: "Resource 4", id: "R4", plan: "Silver" },
{ name: "Resource 5", id: "R5", plan: "Silver" },
{ name: "Resource 6", id: "R6", plan: "Silver" },
{ name: "Resource 7", id: "R7", plan: "Silver" },
{ name: "Resource 8", id: "R8", plan: "Gold" },
{ name: "Resource 9", id: "R9", plan: "Gold" }
]);
// sample events
const events = ref([]);
const startDate = ref("2026-01-01");
const days = ref(365);
const getPriceForSlot = (start, end, resourceId) => {
const resource = resources.value.find(r => r.id === resourceId);
if (!resource) return 0;
const rates = pricingPlans[resource.plan];
if (!rates) return 0; // plan not found
let totalPrice = 0;
let current = new DayPilot.Date(start);
while (current < end) {
const dow = current.getDayOfWeek();
const dailyRate = rates[dow] || 0;
const dayEnd = current.addDays(1).getDatePart();
const segmentEnd = dayEnd < end ? dayEnd : end;
const hoursInSegment = new DayPilot.Duration(current, segmentEnd).totalHours();
totalPrice += dailyRate * (hoursInSegment / 24);
current = segmentEnd;
}
return Math.round(totalPrice);
};
const onTimeRangeSelected = async (args) => {
const scheduler = args.control;
const modal = await DayPilot.Modal.prompt("Create a new event:", "Event 1");
scheduler.clearSelection();
if (modal.canceled) { return; }
scheduler.events.add({
start: args.start,
end: args.end,
id: DayPilot.guid(),
resource: args.resource,
text: modal.result
});
};
const onBeforeEventRender = (args) => {
args.data.backColor = "#f1c232cc";
args.data.borderColor = "darker";
};
const loadEvents = () => {
events.value = [
{
id: 1,
start: "2026-06-03T00:00:00",
end: "2026-06-09T00:00:00",
text: "Event A",
resource: "R5"
},
{
id: 2,
start: "2026-06-05T00:00:00",
end: "2026-06-07T00:00:00",
text: "Event B",
resource: "R2"
}
];
};
onMounted(() => {
loadEvents();
schedulerRef.value?.control.scrollTo("2026-06-01");
});
const schedulerRef = ref(null);
</script>
You can download the whole Vue project using the link at the top of the tutorial.