Overview

  • How to add Previous/Next buttons that change the month displayed by the Vue.js Scheduler component.

  • There are two ways to change the Scheduler properties: config object and direct access

  • This Vue.js project was generated using the online UI Builder application

Changing the Scheduler Properties in Vue

The current range date of the DayPilot Vue.js Scheduler component is defined using two properties:

  1. The startDate prop defines the timeline start.

  2. The days prop defines the timeline length.

<template>
  <DayPilotScheduler 
    :startDate="DayPilot.Date.today().firstDayOfMonth()"
    :days="DayPilot.Date.today().daysInMonth()"
    ...
  />
</template>

In this example, you will learn how to implement Next and Previous buttons that change the value of these props dynamically and switch the month displayed by the Scheduler component.

Change Vue Scheduler Date Range using "Next" Button

Change Vue Scheduler Date Range using Next Button

Any change to the startDate or days props is detected and applied automatically. To switch to the next month, we simply add one month to the current startDate value.

<template>
  <div class="buttons">
    <button id="next" @click="next">Next</button>
  </div>

  <DayPilotScheduler
    ref="schedulerRef"
    scale="Day"
    :days="days"
    :startDate="startDate"
    ...
  />
</template>

<script setup>
import { DayPilot, DayPilotScheduler } from '@daypilot/daypilot-lite-vue'
import { ref, computed } from 'vue'

const schedulerRef = ref(null)

const startDate = ref(DayPilot.Date.today().firstDayOfMonth())
const days = computed(() => startDate.value.daysInMonth())

const next = () => {
  startDate.value = startDate.value.addMonths(1)
}
</script>

You can also use the update() method of the DayPilot.Scheduler object to change the date range directly:

const next = () => {
  const scheduler = schedulerRef.value?.control;
  const startDate = scheduler.startDate.addMonths(1);
  const days = startDate.daysInMonth();
  scheduler.update({startDate, days});
};

Change Vue Scheduler Date Range using "Previous" Button

Change Vue Scheduler Date Range using Previous Button

The “Previous” button logic is similar, we just subtract one month:

<template>
  <div class="buttons">
    <button id="previous" @click="previous">Previous</button>
  </div>

  <DayPilotScheduler
    ref="schedulerRef"
    scale="Day"
    :days="days"
    :startDate="startDate"
    ...
  />
</template>

<script setup>
import { DayPilot, DayPilotScheduler } from '@daypilot/daypilot-lite-vue'
import { ref, computed } from 'vue'

const schedulerRef = ref(null)

const startDate = ref(DayPilot.Date.today().firstDayOfMonth())
const days = computed(() => startDate.value.daysInMonth())

const previous = () => {
  startDate.value = startDate.value.addMonths(-1)
}
</script>

You can also set the properties using the update() method:

const previous = () => {
  const scheduler = schedulerRef.value?.control;
  const startDate = scheduler.startDate.addMonths(-1);
  const days = startDate.daysInMonth();
  scheduler.update({startDate, days});
};

Full Source Code

Here is the source code of our Vue Scheduler example that shows how to change the visible date range using Previous and Next buttons.

It also includes some other basic config options (like event styling using onBeforeEventRender and drag-and-drop event creation using onTimeRangeSelected).

<template>
  <div class="buttons">
    <button id="previous" @click="previous">Previous</button>
    <button id="next" @click="next">Next</button>
  </div>

  <DayPilotScheduler
      ref="schedulerRef"
      :timeHeaders="timeHeaders"
      scale="Day"
      :days="days"
      :startDate="startDate"
      timeRangeSelectedHandling="Enabled"
      :durationBarVisible="false"
      :eventBorderRadius="20"
      :treeEnabled="true"
      :events="events"
      :resources="resources"
      @timeRangeSelected="onTimeRangeSelected"
      @beforeEventRender="onBeforeEventRender"
  />
</template>

<script setup>
import { DayPilot, DayPilotScheduler } from '@daypilot/daypilot-lite-vue'
import { ref, computed, onMounted } from 'vue'

const schedulerRef = ref(null)

// headers
const timeHeaders = [
  { groupBy: 'Month' },
  { groupBy: 'Day', format: 'd' },
]

// date state
const startDate = ref(DayPilot.Date.today().firstDayOfMonth())
const days = computed(() => startDate.value.daysInMonth())

// data
const events = ref([])
const resources = ref([])

// handlers
const onTimeRangeSelected = async (args) => {
  const modal = await DayPilot.Modal.prompt('Create a new event:', 'Event 1')
  args.control.clearSelection()
  if (modal.canceled) return
  args.control.events.add({
    start: args.start,
    end: args.end,
    id: DayPilot.guid(),
    resource: args.resource,
    text: modal.result,
  })
}

const onBeforeEventRender = (args) => {
  args.data.areas = [
    {
      top: 8,
      right: 5,
      width: 20,
      height: 20,
      padding: 2,
      symbol: 'icons/daypilot.svg#x-2',
      style: 'cursor: pointer',
      fontColor: '#666',
      toolTip: 'Delete',
      onClick: (clickArgs) => {
        const e = clickArgs.source
        schedulerRef.value?.control.events.remove(e)
      },
    },
  ]
}

// navigation
const previous = () => {
  startDate.value = startDate.value.addMonths(-1)
}
const next = () => {
  startDate.value = startDate.value.addMonths(1)
}

// load data
const loadEvents = () => {
  const first = DayPilot.Date.today().firstDayOfMonth()
  events.value = [
    {
      id: 1,
      start: first.addDays(5),
      end: first.addDays(10),
      text: 'Event 1',
      resource: 'R3',
      backColor: 'var(--event-bg)',
      borderColor: 'var(--event-border)',
      fontColor: 'var(--event-text)',
    },
  ]
}

const loadResources = () => {
  resources.value = [
    { name: 'Resource 1', id: 'R1' },
    { name: 'Resource 2', id: 'R2' },
    { name: 'Resource 3', id: 'R3' },
    { name: 'Resource 4', id: 'R4' },
    { name: 'Resource 5', id: 'R5' },
    { name: 'Resource 6', id: 'R6' },
    { name: 'Resource 7', id: 'R7' },
    { name: 'Resource 8', id: 'R8' },
    { name: 'Resource 9', id: 'R9' },
  ]
}

onMounted(() => {
  loadResources()
  loadEvents()
})
</script>


<style>
:root{
  --btn-bg: #279864;
  --btn-hover: #1f7f53;
  --btn-selected: #166f44;

  --event-bg: #ECF9F1;
  --event-border: #279864;
  --event-text: #1b3c30;
}

/* Event inner padding */
body .scheduler_default_event_inner {
  padding-left: 10px;
}
</style>

<style scoped>
.buttons {
  margin-bottom: 10px;
  display: inline-flex;
}

.buttons button {
  background-color: var(--btn-bg);
  color: #ffffff;
  border: 0;
  padding: .5rem 1rem;
  width: 80px;
  cursor: pointer;
  margin-right: 1px;
  transition: all 0.2s;
  box-shadow: 0 4px 6px rgba(0,0,0,0.08);
  box-sizing: border-box;
}

.buttons button:last-child {
  margin-right: 0;
}

.buttons button.selected {
  background-color: var(--btn-selected);
  box-shadow: 0 3px 5px rgba(0,0,0,0.1);
}

.buttons button:first-child {
  border-top-left-radius: 30px;
  border-bottom-left-radius: 30px;
}

.buttons button:last-child {
  border-top-right-radius: 30px;
  border-bottom-right-radius: 30px;
}

.buttons button:hover {
  background-color: var(--btn-hover);
  box-shadow: 0 5px 7px rgba(0,0,0,0.1);
}

.buttons button:active {
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
</style>