---
title: "Vue Event calendar Double Booking Prevention Example | Mobiscroll"
component: "Event calendar"
framework: "Vue"
library_version: "6.1.5"
url: "https://demo.mobiscroll.com/vue/eventcalendar/prevent-double-booking-events"
---

# Double Booking Prevention - Vue Event calendar demo

Prevent overlapping events in a Vue event calendar — block double bookings per event or across all events with in-calendar conflict alerts.For Vue and Nuxt.

- [Live demo](https://demo.mobiscroll.com/vue/eventcalendar/prevent-double-booking-events)
- [View SFC JS code on GitHub](https://github.com/acidb/mobiscroll-demos-vue/tree/main/src/demos/eventcalendar/calendar-view/prevent-double-booking-events)
- [View SFC TS code on GitHub](https://github.com/acidb/mobiscroll-demos-vue-ts/tree/main/src/demos/eventcalendar/calendar-view/prevent-double-booking-events)
- This demo in other frameworks: [JavaScript](https://demo.mobiscroll.com/javascript/eventcalendar/prevent-double-booking-events.md), [jQuery](https://demo.mobiscroll.com/jquery/eventcalendar/prevent-double-booking-events.md), [Angular](https://demo.mobiscroll.com/angular/eventcalendar/prevent-double-booking-events.md), [React](https://demo.mobiscroll.com/react/eventcalendar/prevent-double-booking-events.md)

## Description

Sometimes it is necessary to guarantee that events don't overlap - eg. when scheduling workorders, interacting with a work calendar. You can reject the updates or additions and let the user know about it.

The event overlap can be turned on/off on an event basis or globally on the instance.

- On an [event](https://demo.mobiscroll.com/vue/eventcalendar/event-data-structure) basis - by setting the `overlap` property to `false` the specified event cannot overlap.
- Globally on the instance - by setting [`eventOverlap`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-eventOverlap) option to `false` overlap is disbled globally.

If set to `false`, the [event](https://demo.mobiscroll.com/vue/eventcalendar/event-data-structure) settings have precedence over the global calendar [`eventOverlap`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-eventOverlap) option.

Give feedback to the user - optionally, a toast can be displayed to explain why an event cannot be dropped, moved or created. For this we can use the `onEventCreateFailed` and `onEventUpdateFailed` lifecycle events.

**Looking to implement time off or block out ranges?** [Learn how to add lunch breaks, working hours and disable weekends →](https://demo.mobiscroll.com/vue/scheduler/time-off-blocked-ranges)

## What this demo shows

- A desktop month view event calendar where events can be allowed or prevented from overlapping, either per event or for the whole calendar.
- **Calendar header** The header shows the current month and year on the left, and blue month navigation arrows with a `Today` button between them on the right.
- **Month grid** Day cells display events, each label has a blue line on the left, the background of the event have the same color, the event title, and an `end` value that shows the event end time.
- **Event interaction** Hovering over or selecting an event label highlights it and shows resize handles on both sides, indicating that the event can be resized by clicking and dragging.
- **Per-event overlap prevention** Events titled `Event 2 (no event overlap)` and `Event 4 (no event overlap)` block new event creation in their occupied day cells.
- **Creation feedback** When a user tries to create an overlapping event in a restricted cell, a `Make sure not to overbook` toast appears at the bottom center of the calendar.
- **Global overlap control** A switch under this title: `Control the interaction globally (all events)` lets users enable `Events cannot overlap eventOverlap=false` to prevent overlaps across all events.
- **Day cell states** Hovering a day cell highlights the day number with a gray background, while clicking the empty part of the cell selects the day and highlights the day number with a blue background.
- **Event creation** Double-clicking or clicking and dragging on the empty area of a day cell creates a new event.

## Best for

- **Work orders and field service** Preventing technicians, crews, or jobs from being booked into the same time slot when overlap is not allowed.
- **Availability-sensitive booking** Handling internal planning or booking flows where double booking needs to be blocked for some event types or for the whole calendar.
- **Interactive planning UIs** Showing users immediately when an event cannot be created because it would overbook the selected date or time range.

## Tutorial

### Control the interaction globally (all events)

- [ ] Events cannot overlap `eventOverlap=false`

```vue
<script setup>
    // relevant events
    const myData = [{
        start: '2026-10-29T00:00',
        end: '2026-10-31T00:00',
        title: 'Event 2 (no event overlap)',
        overlap: false
    }, {
        start: '2026-11-03T00:00',
        end: '2026-11-05T00:00',
        title: 'Event 4 (no event overlap)',
        overlap: false
    }];
</script>
<template>
    <MbscEventcalendar
        :view="{calendar: {type: 'month', labels: 'all'}}"
        :data="myData"
        :clickToCreate="true"
        :dragToCreate="true"
        :dragToMove="true"
        :dragToResize="true"
        :eventOverlap="true"
        :exclusiveEndDates="true"
    />
</template>
```

## API used in this demo

- [`theme`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-theme) - option
- [`themeVariant`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-themeVariant) - option
- [`labels`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-labels) - option
- [`view`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-view) - option
- [`data`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-data) - option
- [`dragToMove`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-dragToMove) - option
- [`dragToResize`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-dragToResize) - option
- [`dragToCreate`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-dragToCreate) - option
- [`clickToCreate`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-clickToCreate) - option
- [`eventOverlap`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-eventOverlap) - option
- [`exclusiveEndDates`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-exclusiveEndDates) - option
- [`event-update-failed`](https://mobiscroll.com/docs/vue/eventcalendar/api#event-onEventUpdateFailed) - event
- [`event-create-failed`](https://mobiscroll.com/docs/vue/eventcalendar/api#event-onEventCreateFailed) - event
- [`close`](https://mobiscroll.com/docs/vue/notifications/toast#event-onClose) - event

## Code

### SFC JS

```vue
<script setup>
import { MbscEventcalendar, MbscToast, setOptions } from '@mobiscroll/vue'
import { ref } from 'vue'

setOptions({
  theme: 'ios',
  themeVariant: 'light'
})

const now = new Date()
const y = now.getFullYear()
const m = now.getMonth()
const d = now.getDate()

const toastMessage = 'Make sure not to double book'
const isToastOpen = ref(false)

function onEventFailed() {
  isToastOpen.value = true
}

function handleToastClose() {
  isToastOpen.value = false
}

const myView = {
  calendar: { type: 'month', labels: 'all' }
}

const myEvents = ref([
  {
    start: new Date(y, m, d - 3),
    end: new Date(y, m, d - 1),
    title: 'Event 1'
  },
  {
    start: new Date(y, m, d),
    end: new Date(y, m, d + 2),
    title: 'Event 2 (no event overlap)',
    overlap: false
  },
  {
    start: new Date(y, m, d + 3),
    end: new Date(y, m, d + 5),
    title: 'Event 3'
  },
  {
    start: new Date(y, m, d + 5),
    end: new Date(y, m, d + 7),
    title: 'Event 4 (no event overlap)',
    overlap: false
  }
])
</script>

<template>
  <MbscEventcalendar
    :view="myView"
    :data="myEvents"
    :dragToMove="true"
    :dragToResize="true"
    :dragToCreate="true"
    :clickToCreate="true"
    :eventOverlap="false"
    :exclusiveEndDates="true"
    @event-update-failed="onEventFailed"
    @event-create-failed="onEventFailed"
  />
  <MbscToast :message="toastMessage" :isOpen="isToastOpen" @close="handleToastClose" />
</template>
```

### SFC TS

```vue
<script setup lang="ts">
import { MbscEventcalendar, MbscToast, setOptions } from '@mobiscroll/vue'
import type { MbscCalendarEvent, MbscEventcalendarView } from '@mobiscroll/vue'
import { ref } from 'vue'

setOptions({
  theme: 'ios',
  themeVariant: 'light'
})

const now = new Date()
const y = now.getFullYear()
const m = now.getMonth()
const d = now.getDate()

const toastMessage = 'Make sure not to double book'
const isToastOpen = ref<boolean>(false)

function onEventFailed() {
  isToastOpen.value = true
}

function handleToastClose() {
  isToastOpen.value = false
}

const myView: MbscEventcalendarView = {
  calendar: { type: 'month', labels: 'all' }
}

const myEvents = ref<MbscCalendarEvent[]>([
  {
    start: new Date(y, m, d - 3),
    end: new Date(y, m, d - 1),
    title: 'Event 1'
  },
  {
    start: new Date(y, m, d),
    end: new Date(y, m, d + 2),
    title: 'Event 2 (no event overlap)',
    overlap: false
  },
  {
    start: new Date(y, m, d + 3),
    end: new Date(y, m, d + 5),
    title: 'Event 3'
  },
  {
    start: new Date(y, m, d + 5),
    end: new Date(y, m, d + 7),
    title: 'Event 4 (no event overlap)',
    overlap: false
  }
])
</script>

<template>
  <MbscEventcalendar
    :view="myView"
    :data="myEvents"
    :dragToMove="true"
    :dragToResize="true"
    :dragToCreate="true"
    :clickToCreate="true"
    :eventOverlap="false"
    :exclusiveEndDates="true"
    @event-update-failed="onEventFailed"
    @event-create-failed="onEventFailed"
  />
  <MbscToast :message="toastMessage" :isOpen="isToastOpen" @close="handleToastClose" />
</template>
```

## Implementation notes

- Set `view: { calendar: { type: 'month', labels: 'all' } }`. Enable `clickToCreate: true`, `dragToCreate: true`, `dragToMove: true`, and `dragToResize: true` so users can create and edit events interactively. Set `exclusiveEndDates: true` so that events touching at a boundary are not treated as overlapping.
- Set `eventOverlap: false` on the calendar to prevent any two events from overlapping across the whole instance. To prevent a specific event from overlapping regardless of the global setting, set `overlap: false` directly on that event data object.
- `onEventCreateFailed` and `onEventUpdateFailed` (Vue: `@event-create-failed`, `@event-update-failed`) fire whenever Mobiscroll blocks a creation or move due to an overlap violation.

## Run it in your project

1. If not signed up yet, or don't own a license, you can [start a free trial](https://mobiscroll.com/starttrial).

2. Clone the repository:

   ```
   git clone https://github.com/acidb/mobiscroll-demos-vue.git
   ```

3. If not installed yet, install the Mobiscroll CLI from NPM:

   ```
   npm install -g @mobiscroll/cli
   ```

4. Config Mobiscroll - open a terminal window in the root directory and run:

   ```
   mobiscroll config vue
   ```

5. Install dependencies - open a terminal window in the root directory and run:

   ```
   npm install
   ```

6. Run the project:

   ```
   npm run dev
   ```

On a trial, add `--trial` to the config command: `mobiscroll config vue --trial`.

Running a demo locally requires a Mobiscroll trial or a license; setup is per framework at https://mobiscroll.com/docs/vue/getting-started/installation

## Related demos

- Previous: [Blocked Days and Date Ranges](https://demo.mobiscroll.com/vue/eventcalendar/blocked-days-ranges.md) - Disable weekends and date ranges in a Vue event calendar — block dates and drag-and-drop, and choose between strict or permissive validation modes.
- Next: [Drag-and-Drop Task Presets](https://demo.mobiscroll.com/vue/eventcalendar/external-event-presets.md) - Drag preset task templates from an external list onto a Vue event calendar — a popup form captures task details and technician at drop time.
