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

vue js appointment calendar component initialization open source

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

vue js weekly calendar component open source

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

vue js weekly calendar component open source loading events

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

vue js weekly calendar component open source create event

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

vue js weekly calendar component open source 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