Categories
Vue

Add a Calendar into a Vue App with Vue-Simple-Calendar

Spread the love

A calendar is something that is hard to create from scratch.

Therefore, there’re many calendar components created for Vue apps.

In this article, we’ll look at how to add a calendar with Vue-Simple-Calendar.

Installation

We can install the plugin by running:

npm i --save vue-simple-calendar

Usage

Once we installed it, we can use the calendar by writing:

<template>
  <div id="app">
    <calendar-view
      :show-date="showDate"
      class="theme-default holiday-us-traditional holiday-us-official"
    >
      <calendar-view-header
        slot="header"
        slot-scope="t"
        :header-props="t.headerProps"
        @input="setShowDate"
      />
    </calendar-view>
  </div>
</template>
<script>
import { CalendarView, CalendarViewHeader } from "vue-simple-calendar";
import "vue-simple-calendar/static/css/default.css";
import "vue-simple-calendar/static/css/holidays-us.css";

export default {
  name: "app",
  data() {
    return { showDate: new Date() };
  },
  components: {
    CalendarView,
    CalendarViewHeader,
  },
  methods: {
    setShowDate(d) {
      this.showDate = d;
    },
  },
};
</script>

We set the show-date prop to set the default date.

Then we populate the header slot to show the render the header with the calendar-view-header component.

This lets us navigate to different months.

We can set the show the displayPeriodUom prop to show the different kinds of periods in the calendar.

We can set it to year to show years and week to show weeks.

The default is month .

We can also set the starting day of the week with the startingDayOfWeek prop.

dateClasses is an object with different date classes for different dates.

We can add more options by adding more props:

<template>
  <div id="app">
    <div class="calendar-controls">
      <div v-if="message" class="notification is-success">{{ message }}</div>

      <div class="box">
        <div class="field">
          <label class="label">Period UOM</label>
          <div class="control">
            <div class="select">
              <select v-model="displayPeriodUom">
                <option>month</option>
                <option>week</option>
                <option>year</option>
              </select>
            </div>
          </div>
        </div>
        <div class="field">
          <label class="label">Period Count</label>
          <div class="control">
            <div class="select">
              <select v-model="displayPeriodCount">
                <option :value="1">1</option>
                <option :value="2">2</option>
                <option :value="3">3</option>
              </select>
            </div>
          </div>
        </div>
        <div class="field">
          <label class="checkbox">
            <input v-model="useTodayIcons" type="checkbox" />
            Use icon for today's period
          </label>
        </div>
        <div class="field">
          <label class="checkbox">
            <input v-model="displayWeekNumbers" type="checkbox" />
            Show week number
          </label>
        </div>
        <div class="field">
          <label class="checkbox">
            <input v-model="showTimes" type="checkbox" />
            Show times
          </label>
        </div>
        <div class="field">
          <label class="label">Themes</label>
          <label class="checkbox">
            <input v-model="useDefaultTheme" type="checkbox" />
            Default
          </label>
        </div>
        <div class="field">
          <label class="checkbox">
            <input v-model="useHolidayTheme" type="checkbox" />
            Holidays
          </label>
        </div>
      </div>

      <div class="box">
        <div class="field">
          <label class="label">Title</label>
          <div class="control">
            <input v-model="newItemTitle" class="input" type="text" />
          </div>
        </div>
        <div class="field">
          <label class="label">Start date</label>
          <div class="control">
            <input v-model="newItemStartDate" class="input" type="date" />
          </div>
        </div>
        <div class="field">
          <label class="label">End date</label>
          <div class="control">
            <input v-model="newItemEndDate" class="input" type="date" />
          </div>
        </div>
        <button class="button is-info" @click="clickTestAddItem">
          Add Item
        </button>
      </div>
    </div>
    <div class="calendar-parent">
      <calendar-view
        :items="items"
        :show-date="showDate"
        :time-format-options="{ hour: 'numeric', minute: '2-digit' }"
        :enable-drag-drop="true"
        :disable-past="disablePast"
        :disable-future="disableFuture"
        :show-times="showTimes"
        :date-classes="myDateClasses"
        :display-period-uom="displayPeriodUom"
        :display-period-count="displayPeriodCount"
        :starting-day-of-week="startingDayOfWeek"
        :period-changed-callback="periodChanged"
        :current-period-label="useTodayIcons ? 'icons' : ''"
        :displayWeekNumbers="displayWeekNumbers"
        :enable-date-selection="true"
        :selection-start="selectionStart"
        :selection-end="selectionEnd"
        @date-selection-start="setSelection"
        @date-selection="setSelection"
        @date-selection-finish="finishSelection"
        @click-date="onClickDay"
        @click-item="onClickItem"
      >
        <calendar-view-header
          slot="header"
          slot-scope="{ headerProps }"
          :header-props="headerProps"
          @input="setShowDate"
        />
      </calendar-view>
    </div>
  </div>
</template>
<script>
import { CalendarView, CalendarViewHeader } from "vue-simple-calendar";
import "vue-simple-calendar/static/css/default.css";
import "vue-simple-calendar/static/css/holidays-us.css";

export default {
  name: "app",
  components: {
    CalendarView,
    CalendarViewHeader,
  },
  data() {
    return {
      showDate: this.thisMonth(1),
      message: "",
      startingDayOfWeek: 0,
      disablePast: false,
      disableFuture: false,
      displayPeriodUom: "month",
      displayPeriodCount: 1,
      displayWeekNumbers: false,
      showTimes: true,
      selectionStart: null,
      selectionEnd: null,
      newItemTitle: "",
      newItemStartDate: "",
      newItemEndDate: "",
      useDefaultTheme: true,
      useHolidayTheme: true,
      useTodayIcons: false,
      items: [
        {
          id: "e0",
          startDate: "2020-01-05",
        },
        {
          id: "e1",
          startDate: new Date(),
        },
        {
          id: "e2",
          startDate: new Date(2020, 11, 1),
          endDate: new Date(2020, 11, 10),
          title: "Multi-day item with a long title and times",
        },
      ],
    };
  },
  computed: {
    userLocale() {
      return this.getDefaultBrowserLocale;
    },
    myDateClasses() {
      const o = {
        ides: new Date().getDate() === 1,
      };
      return o;
    },
  },
  methods: {
    periodChanged() {},
    thisMonth(d, h, m) {
      const t = new Date();
      return new Date(t.getFullYear(), t.getMonth(), d, h || 0, m || 0);
    },
    onClickDay(d) {
      this.selectionStart = null;
      this.selectionEnd = null;
      this.message = `You clicked: ${d.toLocaleDateString()}`;
    },
    onClickItem(e) {
      this.message = `You clicked: ${e.title}`;
    },
    setShowDate(d) {
      this.message = `Changing calendar view to ${d.toLocaleDateString()}`;
      this.showDate = d;
    },
    setSelection(dateRange) {
      this.selectionEnd = dateRange[1];
      this.selectionStart = dateRange[0];
    },
    finishSelection(dateRange) {
      this.setSelection(dateRange);
      this.message = `You selected: ${this.selectionStart.toLocaleDateString()} -${this.selectionEnd.toLocaleDateString()}`;
    },
    clickTestAddItem() {
      this.items.push({
        startDate: this.newItemStartDate,
        endDate: this.newItemEndDate,
        title: this.newItemTitle,
        id: "e" + Math.random().toString(36).substr(2, 10),
      });
      this.message = "You added a calendar item!";
    },
  },
};
</script>

We add items to the items array with the clickTestAddItem method to add calendar events.

We also have select elements to change the period displayed and the number of periods displayed.

Conclusion

We can add the Vue-Simple-Calendar component to add an event calendar with many options in our Vue app.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *