Overview
Vue.js appointment calendar created using DayPilot JavaScript calendar component
How to create and configure the Vue.js calendar
How to load event/appointment data
How to add support for creating new appointment using drag and drop
This project was generated using Calendar UI Builder
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.
Vue.js Calendar Component
Let's start with a blank Vue.js project. We will create a new Vue.js component that displays an appointment calendar using DayPilot Vue.js Calendar.
The Vue.js Calendar component is included in the Vue.js package of DayPilot Pro for JavaScript. You can install it using a link from npm.daypilot.org:
yarn add https://npm.daypilot.org/daypilot-pro-vue/trial/2020.4.4807.tar.gz
First, we create a new Calendar
component using <DayPilotCalendar>
tag. Our calendar component will define the calendar appearance and behavior:
components/Calendar.vue
<template>
<DayPilotCalendar id="dp" />
</template>
<script>
import {DayPilotCalendar} from 'daypilot-pro-vue'
export default {
name: 'Calendar',
components: {
DayPilotCalendar
},
}
</script>
Now we can add the calendar to our Vue application:
App.vue
<template>
<div id="app">
<Calendar />
</div>
</template>
<script>
import Calendar from './components/Calendar.vue'
export default {
name: 'app',
components: {
Calendar
}
}
</script>
Vue.js Weekly Calendar Configuration
By default, the calendar display a day view. We want to switch it to a week view and this can be done by setting the viewType property to "Week"
.
The calendar properties can be specified using the :config
attribute of the component. We have set the value to "config"
which tells the calendar to look for config
object in the application data.
<template>
<DayPilotCalendar id="dp" :config="config" />
</template>
<script>
import {DayPilotCalendar} from 'daypilot-pro-vue'
export default {
name: 'Calendar',
data: function() {
return {
config: {
viewType: "Week",
},
}
},
components: {
DayPilotCalendar
},
}
</script>
You can use the config
object to set additional calendar properties and event handlers. Changes made to the config object using Vue.set()
method will be detected by Vue and the Calendar component will be updated automatically.
Loading Appointments
In order to load events we need to access the calendar object (DayPilot.Calendar class) and use its API. This object is saved as control
property of the Vue.js component.
To make it easily accessible, we will add a calendar
computed property to our Vue.js application. It finds the calendar Vue.js component using ref
attribute and returns the DayPilot.Calendar
object.
<template>
<DayPilotCalendar id="dp" :config="config" ref="calendar" />
</template>
<script>
import {DayPilotCalendar} from 'daypilot-pro-vue'
export default {
name: 'Calendar',
data: function() {
return {
config: {
viewType: "Week",
},
}
},
components: {
DayPilotCalendar
},
computed: {
calendar() {
return this.$refs.calendar.control;
}
},
}
</script>
The appointment data can be displayed using update() method. The update()
methods accepts an object with calendar properties to be updated. It loads the properties and redraws the calendar UI.
<template>
<DayPilotCalendar id="dp" :config="config" ref="calendar" />
</template>
<script>
import {DayPilot, DayPilotCalendar} from 'daypilot-pro-vue'
export default {
name: 'Calendar',
data: function() {
return {
config: {
viewType: "Week",
},
}
},
props: {
},
components: {
DayPilotCalendar
},
computed: {
calendar() {
return this.$refs.calendar.control;
}
},
methods: {
loadEvents() {
// placeholder for an AJAX call
var data = [
{
id: 1,
start: DayPilot.Date.today().addHours(10),
end: DayPilot.Date.today().addHours(11),
text: "Event 1"
},
{
id: 2,
start: DayPilot.Date.today().addHours(13),
end: DayPilot.Date.today().addHours(16),
text: "Event 2"
}
];
this.calendar.update({events: data});
},
},
mounted() {
this.loadEvents();
}
}
</script>
Creating New Appointments
The JavaScript calendar lets users users create new appointments using drag and drop time range selection.
To handle the user action, we'll add onTimeRangeSelected
event handler to the config object.
<script>
import {DayPilot, DayPilotCalendar} from 'daypilot-pro-vue'
export default {
name: 'Calendar',
data: function() {
return {
config: {
viewType: "Week",
onTimeRangeSelected: (args) => {
DayPilot.Modal.prompt("Create a new event:", "Event 1").then((modal) => {
var dp = args.control;
dp.clearSelection();
if (modal.canceled) {
return;
}
dp.events.add({
start: args.start,
end: args.end,
id: DayPilot.guid(),
text: modal.result
});
});
},
},
}
},
// ...
}
</script>
Calendar Appointment Context Menu
In order to allow additional actions to be performed we will add a context menu to the calendar appointments. It will let users delete the appointment or change the highlight color.
First, we need to define the context menu. It will display a “Delete” command, a separator, and four items that will allow color changes:
<script>
import {DayPilot, DayPilotCalendar} from 'daypilot-pro-vue'
export default {
name: 'Calendar',
data: function() {
return {
config: {
viewType: "Week",
contextMenu: new DayPilot.Menu({
items: [
{
text: "Delete",
onClick: (args) => {
var e = args.source;
this.calendar.events.remove(e);
this.calendar.message("Deleted.");
}
},
{
text: "-"
}, {
text: "Blue",
icon: "icon icon-blue",
color: "#1155cc",
onClick: (args) => {
this.updateColor(args.source, args.item.color);
}
},
{
text: "Green",
icon: "icon icon-green",
color: "#6aa84f",
onClick: (args) => {
this.updateColor(args.source, args.item.color);
}
},
{
text: "Yellow",
icon: "icon icon-yellow",
color: "#f1c232",
onClick: (args) => {
this.updateColor(args.source, args.item.color);
}
},
{
text: "Red",
icon: "icon icon-red",
color: "#cc0000",
onClick: (args) => {
this.updateColor(args.source, args.item.color);
}
},
]
})
},
}
},
// ...
}
</script>
The menu defined using contextMenu property will be linked to appointments. Our users can activate it by right-clicking the appointment.
However, it's not obvious that the context menu is available so we'll add a visual hint that will appear when the users hover over an appointment. We can add this hint using an active area - a custom object with predefined location and appearance that will appear on hover. We will add the active area using onBeforeEventRender event handler:
<template>
<DayPilotCalendar id="dp" :config="config" ref="calendar" />
</template>
<script>
import {DayPilot, DayPilotCalendar} from 'daypilot-pro-vue'
export default {
name: 'Calendar',
data: function() {
return {
config: {
viewType: "Week",
onBeforeEventRender: (args) => {
args.data.barColor = args.data.color;
args.data.areas = [
{
top: 6,
right: 2,
icon: "icon-triangle-down",
visibility: "Hover",
action: "ContextMenu",
style: "font-size: 12px; background-color: #f9f9f9; border: 1px solid #ccc; padding: 2px 2px 0px 2px; cursor:pointer;"
}
];
},
},
}
},
// ...
}
</script>
Complete Source Code of the Vue.js Calendar Component
components/Calendar.vue
<template>
<DayPilotCalendar id="dp" :config="config" ref="calendar" />
</template>
<script>
import {DayPilot, DayPilotCalendar} from 'daypilot-pro-vue'
export default {
name: 'Calendar',
data: function() {
return {
config: {
viewType: "Week",
timeRangeSelectedHandling: "Enabled",
onTimeRangeSelected: (args) => {
DayPilot.Modal.prompt("Create a new event:", "Event 1").then((modal) => {
var dp = args.control;
dp.clearSelection();
if (modal.canceled) {
return;
}
dp.events.add({
start: args.start,
end: args.end,
id: DayPilot.guid(),
text: modal.result
});
});
},
eventDeleteHandling: "Disabled",
onEventMoved: () => {
this.message("Event moved");
},
onEventResized: () => {
this.message("Event resized");
},
onBeforeEventRender: (args) => {
args.data.barColor = args.data.color;
args.data.areas = [
{
top: 6,
right: 2,
icon: "icon-triangle-down",
visibility: "Hover",
action: "ContextMenu",
style: "font-size: 12px; background-color: #f9f9f9; border: 1px solid #ccc; padding: 2px 2px 0px 2px; cursor:pointer;"
}
];
},
contextMenu: new DayPilot.Menu({
items: [
{
text: "Delete",
onClick: (args) => {
var e = args.source;
this.calendar.events.remove(e);
this.calendar.message("Deleted.");
}
},
{
text: "-"
}, {
text: "Blue",
icon: "icon icon-blue",
color: "#1155cc",
onClick: (args) => {
this.updateColor(args.source, args.item.color);
}
},
{
text: "Green",
icon: "icon icon-green",
color: "#6aa84f",
onClick: (args) => {
this.updateColor(args.source, args.item.color);
}
},
{
text: "Yellow",
icon: "icon icon-yellow",
color: "#f1c232",
onClick: (args) => {
this.updateColor(args.source, args.item.color);
}
},
{
text: "Red",
icon: "icon icon-red",
color: "#cc0000",
onClick: (args) => {
this.updateColor(args.source, args.item.color);
}
},
]
})
},
}
},
props: {
},
components: {
DayPilotCalendar
},
computed: {
// DayPilot.Calendar object - https://api.daypilot.org/daypilot-calendar-class/
calendar() {
return this.$refs.calendar.control;
}
},
methods: {
loadEvents() {
// placeholder for an AJAX call
var data = [
{
id: 1,
start: DayPilot.Date.today().addHours(10),
end: DayPilot.Date.today().addHours(11),
text: "Event 1"
},
{
id: 2,
start: DayPilot.Date.today().addHours(13),
end: DayPilot.Date.today().addHours(16),
text: "Event 2"
}
];
this.calendar.update({events: data});
},
updateColor(e, color) {
var dp = this.calendar;
e.data.color = color;
dp.events.update(e);
dp.message("Color updated");
}
},
mounted() {
this.loadEvents();
this.calendar.message("Welcome!");
}
}
</script>
History
December 16, 2020: Upgraded to DayPilot Pro for JavaScript 2020.4.4807. Using NPM package (daypilot-pro-vue).
September 18, 2019: Upgraded to DayPilot Pro for JavaScript 2019.3.4012. Context menu added.
April 11, 2018: Initial release