Overview
Vue.js appointment calendar created using DayPilot JavaScript calendar component from the free and open-source DayPilot Lite scheduling library (Apache License 2.0).
How to create and configure the Vue.js calendar
How to load event/appointment data
How to add support for adding new appointment using drag and drop
How to style calendar appointments using CSS
Vue.js Calendar Component
Let's start with a blank Vue project. We will create a new 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 Lite for JavaScript. You can install it using using yarn
:
yarn add @daypilot/daypilot-lite-vue
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/daypilot-lite-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>
Tip: If you want to display a calendar for multiple resources (displayed as columns), take a look at the Vue Resource Calendar (Open-Source) tutorial.
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/daypilot-lite-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 computed calendar
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/daypilot-lite-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/daypilot-lite-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
const events = [
{
id: 1,
start: "2022-02-28T10:00:00",
end: "2022-02-28T11:00:00",
text: "Event 1",
},
{
id: 2,
start: "2022-02-28T13:00:00",
end: "2022-02-28T16:00:00",
text: "Event 2",
},
];
this.calendar.update({events});
},
},
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/daypilot-lite-vue'
export default {
name: 'Calendar',
data: function() {
return {
config: {
viewType: "Week",
onTimeRangeSelected: async (args) => {
const modal = await DayPilot.Modal.prompt("Create a new event:", "Event 1");
const 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 CSS Styling
You can change the appointment appearance using CSS:
You can generate a custom CSS theme using the online theme designer. The theme designer lets you customize the appearance of the calendar component and also the styling of the appointments.
You can simply override selected styles of the built-in theme.
First, we turn off the duration bar using the configuration object:
Now we can add custom CSS styles. This CSS class will change the appointment background color to blue, text color to white, add a bit of transparency and apply rounded corners:
<style>
.calendar_default_event_inner {
background: #2e78d6;
color: white;
border-radius: 5px;
opacity: 0.9;
}
</style>
In addition to the global CSS settings, you can also set selected properties directly in the event properties or you can customize the appointments dynamically using onBeforeEventRender
event handler.
methods: {
loadEvents() {
// placeholder for an HTTP call
const events = [
{
id: 1,
start: "2022-02-28T10:00:00",
end: "2022-02-28T11:00:00",
text: "Event 1",
backColor: "#6aa84f",
borderColor: "#38761d",
},
{
id: 2,
start: "2022-02-28T13:00:00",
end: "2022-02-28T16:00:00",
text: "Event 2",
backColor: "#f1c232",
borderColor: "#bf9000",
},
{
id: 3,
start: "2022-03-01T13:30:00",
end: "2022-03-01T16:30:00",
text: "Event 3",
backColor: "#cc4125",
borderColor: "#990000",
},
{
id: 4,
start: "2022-03-01T10:30:00",
end: "2022-03-01T12:30:00",
text: "Event 4"
},
];
this.calendar.update({events});
},
},
Complete Source Code of the Vue.js Calendar Component
components/Calendar.vue
<template>
<div class="wrap">
<div class="left">
<DayPilotNavigator id="nav" :config="navigatorConfig" />
</div>
<div class="content">
<DayPilotCalendar id="dp" :config="config" ref="calendar" />
</div>
</div>
</template>
<script>
import {DayPilot, DayPilotCalendar, DayPilotNavigator} from '@daypilot/daypilot-lite-vue'
export default {
name: 'Calendar',
data: function() {
return {
events: [],
navigatorConfig: {
showMonths: 3,
skipMonths: 3,
selectMode: "Week",
startDate: "2022-03-01",
selectionDay: "2022-02-28",
onTimeRangeSelected: args => {
this.config.startDate = args.day;
}
},
config: {
viewType: "Week",
startDate: "2022-02-28",
durationBarVisible: false,
timeRangeSelectedHandling: "Enabled",
onTimeRangeSelected: async (args) => {
const modal = await DayPilot.Modal.prompt("Create a new event:", "Event 1");
const 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: () => {
console.log("Event moved");
},
onEventResized: () => {
console.log("Event resized");
},
},
}
},
props: {
},
components: {
DayPilotCalendar,
DayPilotNavigator
},
computed: {
// DayPilot.Calendar object - https://api.daypilot.org/daypilot-calendar-class/
calendar() {
return this.$refs.calendar.control;
}
},
methods: {
loadEvents() {
// placeholder for an HTTP call
const events = [
{
id: 1,
start: "2022-02-28T10:00:00",
end: "2022-02-28T11:00:00",
text: "Event 1",
backColor: "#6aa84f",
borderColor: "#38761d",
},
{
id: 2,
start: "2022-02-28T13:00:00",
end: "2022-02-28T16:00:00",
text: "Event 2",
backColor: "#f1c232",
borderColor: "#bf9000",
},
{
id: 3,
start: "2022-03-01T13:30:00",
end: "2022-03-01T16:30:00",
text: "Event 3",
backColor: "#cc4125",
borderColor: "#990000",
},
{
id: 4,
start: "2022-03-01T10:30:00",
end: "2022-03-01T12:30:00",
text: "Event 4"
},
];
this.calendar.update({events});
},
},
mounted() {
this.loadEvents();
}
}
</script>
<style>
.wrap {
display: flex;
}
.left {
margin-right: 10px;
}
.content {
flex-grow: 1;
}
.calendar_default_event_inner {
background: #2e78d6;
color: white;
border-radius: 5px;
opacity: 0.9;
}
</style>
History
January 4, 2022: Switched to the Vue Calendar component from the open-source DayPilot Lite library (version 2021.4.341). Date picker for changing dates integrated. Upgraded to Vue 3.
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