---
title: "Angular Timeline Prevent Event Overlap Example | Mobiscroll"
component: "Timeline"
framework: "Angular"
library_version: "6.1.5"
url: "https://demo.mobiscroll.com/angular/timeline/prevent-double-booking-events"
---

# Prevent Event Overlap - Angular Timeline demo

Prevent double booking on the Angular Timeline — block overlaps per event, per resource, or globally, and show a toast on conflict. For Angular 22 and Ionic 8.

- [Live demo](https://demo.mobiscroll.com/angular/timeline/prevent-double-booking-events)
- [View code on GitHub](https://github.com/acidb/mobiscroll-demos-angular/tree/main/src/demos/eventcalendar/timeline/prevent-double-booking-events)
- This demo in other frameworks: [JavaScript](https://demo.mobiscroll.com/javascript/timeline/prevent-double-booking-events.md), [jQuery](https://demo.mobiscroll.com/jquery/timeline/prevent-double-booking-events.md), [React](https://demo.mobiscroll.com/react/timeline/prevent-double-booking-events.md), [Vue](https://demo.mobiscroll.com/vue/timeline/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, per resource or globally on the instance.

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

If set to `false`, the [resource](https://demo.mobiscroll.com/angular/timeline/resource-data-structure) and the [event](https://demo.mobiscroll.com/angular/timeline/event-data-structure) settings have precedence over the global calendar [`eventOverlap`](https://mobiscroll.com/docs/angular/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.

## What this demo shows

- A desktop daily timeline where hours are arranged horizontally and resources are listed as rows on the left.
- **Header navigation** The month and year label opens date navigation, while the previous and next arrows move between days and the Today button returns to the current date.
- **Day view** The strip below the header shows the selected day, with the current date highlighted. The timeline displays hourly columns from 12 AM to 12 PM.
- **Current time** A vertical blue line with a time label marks the current time.
- **Hover behavior** Hovering over the time grid shows a time indicator that follows the cursor in 15-minute increments.
- **Resources** Four resources are displayed: Resource 1, Resource 2, Resource 3, and Resource 4 - no event overlap allowed.
- **Event-level restrictions** Resource 1 and Resource 2 contain events with per-event overlap restrictions. Event 2 on Resource 1 and Event 4 on Resource 2 have `overlap: false`, meaning those specific events cannot overlap with any other event. Other events on the same resources can still overlap when the global overlap setting allows it.
- **Resource-level restrictions** Resource 4 - no event overlap allowed has `eventOverlap: false`, which applies a no-overlap rule to every event on that resource.
- **Global overlap control** A switch under this title: `Control the interaction globally (all events/resources)` lets users enable `Events cannot overlap eventOverlap=false` to prevent overlaps across all the timeline, by default it's disabled. 
- **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.
- **Event cards** Events are shown as colored cards with a left color stripe, a bold title, a description, and a bold time range.
- **Date positioning** Events are positioned by their assigned resource and exact date range.
- **Event interaction** Events highlight on hover and show drag and resize handles for repositioning or changing duration.
- **Event selection** Clicking an event selects and highlights it.
- **Event creation** New events can be created by double-clicking the timeline or by clicking and dragging across a time range.
- **Scrolling** The timeline supports horizontal and vertical scrolling for navigating through time and resources.

## Best for

- **Work orders and field service** Preventing technicians, crews, or jobs from being booked into the same time slot.
- **Availability-sensitive booking** Handling internal planning or booking workflows where double booking must be prevented for specific event types, resources, or the entire calendar.
- **Shared resource scheduling** Managing rooms, equipment, vehicles, or other resources that can only be assigned to one event at a time.
- **Interactive planning tools** Giving users immediate feedback when an action would create a scheduling conflict.
- **Mixed scheduling policies** Combining global, resource-level, and event-level overlap rules within the same timeline.

## Tutorial

### Control the interaction globally (all events/resources)

- [ ] Events cannot overlap `eventOverlap=false`

```html
<mbsc-eventcalendar
    [view]="{ timeline: { type: 'day' }}"
    [data]="myData"
    [resources]="myResources"
    [dragToMove]="true"
    [dragToResize]="true"
    [eventOverlap]="true"
    [clickToCreate]="true"
    [dragToCreate]="true"
>
</mbsc-eventcalendar>
```

```ts
// relevant events
const myData = [{
    start: '2026-10-23T16:00',
    end: '2026-10-23T18:00',
    title: 'Event 2 (no event overlap)',
    overlap: false,
    resource: 1
},{
    start: '2026-10-23T08:00',
    end: '2026-10-23T10:00',
    title: 'Event 4 (no event overlap)',
    overlap: false,
    resource: 2
}];
// relevant resource
const myResources = [{
    id: 4,
    name: 'Resource 4 - no event overlap allowed',
    eventOverlap: false
}];
```

## API used in this demo

- [`theme`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-theme) - option
- [`themeVariant`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-themeVariant) - option
- [`clickToCreate`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-clickToCreate) - option
- [`dragToCreate`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-dragToCreate) - option
- [`dragToMove`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-dragToMove) - option
- [`dragToResize`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-dragToResize) - option
- [`eventOverlap`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-eventOverlap) - option
- [`onEventUpdateFailed`](https://mobiscroll.com/docs/angular/eventcalendar/api#event-onEventUpdateFailed) - event
- [`onEventCreateFailed`](https://mobiscroll.com/docs/angular/eventcalendar/api#event-onEventCreateFailed) - event
- [`data`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-data) - option
- [`resources`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-resources) - option
- [`view`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-view) - option

## Code

### Component

```ts
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import {
  MbscCalendarEvent,
  MbscEventcalendarOptions,
  MbscEventcalendarView,
  MbscModule,
  MbscResource,
  Notifications,
  setOptions,
} from '@mobiscroll/angular';

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

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

@Component({
  selector: 'app-root', 
  templateUrl: './app.component.html',
  providers: [Notifications],
  standalone: true,
  imports: [CommonModule, MbscModule],
})
export class AppComponent {
  constructor(private notify: Notifications) {}

  myOptions: MbscEventcalendarOptions = {
    clickToCreate: true,
    dragToCreate: true,
    dragToMove: true,
    dragToResize: true,
    eventOverlap: false,
    onEventUpdateFailed: () => {
      this.notify.toast({
        message: 'Make sure not to double book',
      });
    },
    onEventCreateFailed: () => {
      this.notify.toast({
        message: 'Make sure not to double book',
      });
    },
  };

  myEvents: MbscCalendarEvent[] = [
    {
      start: new Date(y, m, d, 11),
      end: new Date(y, m, d, 13),
      title: 'Event 1',
      resource: 1,
    },
    {
      start: new Date(y, m, d, 16),
      end: new Date(y, m, d, 17),
      title: 'Event 2 (no event overlap)',
      overlap: false,
      resource: 1,
    },
    {
      start: new Date(y, m, d, 14),
      end: new Date(y, m, d, 16),
      title: 'Event 3',
      resource: 2,
    },
    {
      start: new Date(y, m, d, 8),
      end: new Date(y, m, d, 10),
      title: 'Event 4 (no event overlap)',
      resource: 2,
      overlap: false,
    },
    {
      start: new Date(y, m, d, 10),
      end: new Date(y, m, d, 13),
      title: 'Event 5',
      resource: 3,
    },
    {
      start: new Date(y, m, d, 11),
      end: new Date(y, m, d, 16),
      title: 'Event 6',
      resource: 4,
    },
  ];

  myResources: MbscResource[] = [
    {
      id: 1,
      name: 'Resource 1',
    },
    {
      id: 2,
      name: 'Resource 2',
    },
    {
      id: 3,
      name: 'Resource 3',
    },
    {
      id: 4,
      name: 'Resource 4 - no event overlap allowed',
      eventOverlap: false,
    },
  ];

  myView: MbscEventcalendarView = {
    timeline: { type: 'day' },
  };
}
```

### Template

```html
<mbsc-eventcalendar [data]="myEvents" [resources]="myResources" [view]="myView" [options]="myOptions"></mbsc-eventcalendar>
```

## Implementation notes

- Use `timeline: { type: 'day' }` - a single-day view. Set `eventOverlap: true` globally so overlap is permitted by default; individual events and resources selectively restrict it.
- Define 4 resources. Resources 1-3 have no overlap restriction at the resource level. Resource 4 has `eventOverlap: false` - no event on this resource may overlap with another, regardless of per-event settings.
- Add 6 events (all `new Date(y, m, d, hour)` for today). Two events carry `overlap: false` to restrict them individually: Event 2 on Resource 1 and Event 4 on Resource 2. The remaining events have no `overlap` property and can overlap freely unless their resource blocks it.
- Enable all interactions: `clickToCreate: true`, `dragToCreate: true`, `dragToMove: true`, `dragToResize: true`.
- `onEventCreateFailed` fires when a new event (click/drag-to-create) would violate the overlap rule; `onEventUpdateFailed` fires when a drag or resize would cause overlap. In both cases the calendar automatically rejects and reverts the action - no manual revert is needed.
- **Precedence**: per-event `overlap: false` and per-resource `eventOverlap: false` both override the global `eventOverlap` option.

## 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-angular.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 angular
   ```

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

   ```
   npm install
   ```

6. Run the project:

   ```
   ng serve
   ```

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

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

## Related demos

- Previous: [Cross-Instance Drag and Drop](https://demo.mobiscroll.com/angular/timeline/drag-drop-between-calendar-instances.md) - Drag and drop events between two Angular Timeline views to reassign resources or coordinate schedules — enable cross-timeline transfers.
- Next: [Schedule & Unschedule from External Lists](https://demo.mobiscroll.com/angular/timeline/external-drag-drop-sortable-dragula.md) - Connect SortableJS or Dragula lists to the Angular Timeline — drag items onto the timeline to schedule them, drag them back off to unschedule.
