Overview

In this Vue Scheduler tutorial, you will learn how to work with holidays:

  • How to define global and per-resource holidays.

  • How to display the holidays using custom Scheduler cell background color.

  • How to disable drag and drop for the holiday cells.

The attached project includes a trial version of DayPilot Pro for JavaScript (see License below).

For an introduction to using the Vue Scheduler component, please see the following tutorial:

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.

How to display global holidays in the Vue Scheduler?

vue scheduler global holidays

First, you need to define the global holidays. We will use a new globalHolidays property which holds an array with holiday dates. Each item specifies a date range, defined using start and end dates. The end date specifies the last day of the holiday (we need to take it into account later when checking the date range, see below).

The following example defines a holiday for August 9, 2021:

globalHolidays: [
  { start: "2021-08-09", end: "2021-08-09", backColor: "#b6d7a8", headerColor: "#6aa84f"}
],

Now you need to configure the Vue Scheduler component to highlight the grid cells that overlap any of the holiday date ranges.

You can customize the Vue Scheduler cells using onBeforeCellRender event handler. This event handler is called once for each of the Scheduler cells. You can use it to set custom background color and other properties.

In the event handler, we will check if the cell date (args.cell.start and args.cell.end) overlaps with the global holidays.

const start = new DayPilot.Date(holiday.start);
const end = new DayPilot.Date(holiday.end).addDays(1);
const overlaps = DayPilot.Util.overlaps(start, end, args.cell.start, args.cell.end);

Note that we have added 1 day to the end date. The DayPilot.Util.overlaps() method works with exact time points. Our end date ("2021-08-09") is interpreted as the start of August 9, 2021 (ie. "2021-08-09T00:00:00"). In order to treat it as the end of August 9, 2021, you need to add one day using addDays(1). That will result in "2021-08-10T00:00:00" which is the time point we need.

If an overlap is detected, we set a custom background color using args.cell.backColor property.

The following code will highlight the holidays defined in the globalHolidays property:

<template>
  <DayPilotScheduler id="dp" :config="config" ref="scheduler" />
</template>

<script>
import {DayPilot, DayPilotScheduler} from 'daypilot-pro-vue'

export default {
  name: 'Scheduler',
  data: function() {
    return {
      globalHolidays: [
        { start: "2021-08-09", end: "2021-08-09", backColor: "#b6d7a8", headerColor: "#6aa84f"}
      ],
      config: {
        onBeforeCellRender: args => {
          this.highlightGlobalHolidays(args);
        }
      },
    }
  },
  components: {
    DayPilotScheduler
  },
  computed: {
    // DayPilot.Scheduler object - https://api.daypilot.org/daypilot-scheduler-class/
    scheduler: function () {
      return this.$refs.scheduler.control;
    }
  },
  methods: {
    highlightGlobalHolidays(args) {
      const item = this.globalHolidays.find(holiday => {
        const start = new DayPilot.Date(holiday.start);
        const end = new DayPilot.Date(holiday.end).addDays(1);
        return DayPilot.Util.overlaps(start, end, args.cell.start, args.cell.end);
      });

      if (item) {
        args.cell.backColor = item.backColor;
      }
    },
    // ...
  },
  // ...
}
</script>

How to highlight the global holidays in the time header?

You can also highlight the global holidays in the Vue Scheduler time header. Note the green bar displayed in the time header cell for August 9, 2021:

vue scheduler global holidays highlight time header

To highlight the holidays in the time header, you can use the onBeforeTimeHeaderRender event handler, which lets you customize the appearance of the time headers cells.

The logic is very similar - you need to check for overlaps of the time header cell start and end with the global holiday dates.

This time, we will not highlight the whole cell using the backColor property but we will add a small bar at the bottom of the time header cell using active areas:

config: {
  onBeforeTimeHeaderRender: args => {
    if (args.header.level === 1) {
      const item = this.globalHolidays.find(function (range) {
        const start = new DayPilot.Date(range.start);
        const end = new DayPilot.Date(range.end).addDays(1);
        return DayPilot.Util.overlaps(start, end, args.header.start, args.header.end);
      });

      if (item) {
        const start = new DayPilot.Date(item.start);
        const end = new DayPilot.Date(item.end).addDays(1);

        args.header.areas = [
          { start: start, end: end, bottom: 0, height: 5, backColor: item.headerColor}
        ];
      }
    }
  },
  // ...
}

How to disable drag and drop operations for holidays?

vue scheduler disabled drag and drop for holidays

In the previous example, we have changed the background color of the Scheduler cells but we didn’t change the cell behavior.

If you want to disable the drag and drop operations for the cells marked as holidays, you need to use args.cell.disabled to mark the cell as disabled:

export default {
  name: 'Scheduler',
  data: function() {
    return {
      holidaysDisabled: true,
      globalHolidays: [
        { start: "2021-08-09", end: "2021-08-09", backColor: "#b6d7a8", headerColor: "#6aa84f"}
      ],
      config: {
        onBeforeCellRender: args => {
          this.highlightGlobalHolidays(args);
        }
      },
    }
  },
  // ...
  methods: {
    highlightGlobalHolidays(args) {

      // ...

      if (item) {

        if (this.holidaysDisabled) {
          args.cell.disabled = true;
        }

      }
    },
    // ...
  },
  // ...
}

How to display resource-specific holidays in the Vue Scheduler?

vue scheduler per resource holidays

You can also define holidays for specific resources. In this example, we define the holidays using a custom holidays property of the resources[] array:

const resources = [
  { name: "Resource A", id: "A"},
  { name: "Resource B", id: "B", holidays: [
      { start: "2021-08-04", end: "2021-08-06", backColor: "#dd7e6b"}
    ]},
  { name: "Resource C", id: "C"},
  { name: "Resource D", id: "D", holidays: [
      { start: "2021-08-02", end: "2021-08-06", backColor: "#ffe599"}
    ]},
  { name: "Resource E", id: "E"},
  { name: "Resource F", id: "F"},
  { name: "Resource G", id: "G"},
  { name: "Resource H", id: "H"},
  { name: "Resource I", id: "I"},
  { name: "Resource J", id: "J"},
];

Now it’s necessary to check the overlaps with the resource holidays in onBeforeCellRender event handler.

First, you need to get the holiday data. The resource ID is available in args.cell.resource. To find the resource data object, use the rows.find() method:

const row = this.scheduler.rows.find(args.cell.resource);
const holidays = row.data.holidays;

The next step is to check for overlaps with the resource holiday dates:

export default {
  name: 'Scheduler',
  data: function() {
    return {
      config: {
        onBeforeCellRender: args => {
          // ...
          this.highlightGlobalHolidays(args);
        }
      },
    }
  },
  // ...
  methods: {
    highlightResourceHolidays(args) {
      const row = this.scheduler.rows.find(args.cell.resource);
      const holidays = row.data.holidays;
      if (!holidays) {
        return;
      }
      const item = holidays.find(holiday => {
        const start = new DayPilot.Date(holiday.start);
        const end = new DayPilot.Date(holiday.end).addDays(1);
        return DayPilot.Util.overlaps(start, end, args.cell.start, args.cell.end);
      });

      if (item) {
        args.cell.backColor = item.backColor;

        if (this.holidaysDisabled) {
          args.cell.disabled = true;
        }
      }
    },


    loadResources() {
      const resources = [
        { name: "Resource A", id: "A"},
        { name: "Resource B", id: "B", holidays: [
            { start: "2021-08-04", end: "2021-08-06", backColor: "#dd7e6b"}
          ]},
        { name: "Resource C", id: "C"},
        { name: "Resource D", id: "D", holidays: [
            { start: "2021-08-02", end: "2021-08-06", backColor: "#ffe599"}
          ]},
        { name: "Resource E", id: "E"},
        { name: "Resource F", id: "F"},
        { name: "Resource G", id: "G"},
        { name: "Resource H", id: "H"},
        { name: "Resource I", id: "I"},
        { name: "Resource J", id: "J"},
      ];
      this.config.resources = resources;
    },

    // ...
  },
}
</script>