---
title: "Angular Scheduler External Task Presets Example | Mobiscroll"
component: "Scheduler"
framework: "Angular"
library_version: "6.1.5"
url: "https://demo.mobiscroll.com/angular/scheduler/external-event-presets"
---

# External Task Presets - Angular Scheduler demo

Drag task templates from an external list onto the Angular Scheduler — schedule, assign a technician in a popup, and block drops on restricted slots.

- [Live demo](https://demo.mobiscroll.com/angular/scheduler/external-event-presets)
- [View code on GitHub](https://github.com/acidb/mobiscroll-demos-angular/tree/main/src/demos/eventcalendar/scheduler/external-event-presets)
- This demo in other frameworks: [JavaScript](https://demo.mobiscroll.com/javascript/scheduler/external-event-presets.md), [jQuery](https://demo.mobiscroll.com/jquery/scheduler/external-event-presets.md), [React](https://demo.mobiscroll.com/react/scheduler/external-event-presets.md), [Vue](https://demo.mobiscroll.com/vue/scheduler/external-event-presets.md)

## Description

Use external draggable events to create preset tasks that people can quickly copy and spawn events from. A great example is an auto repair shop where among others, mechanics have to perform the same predefined tasks.

Print a list of predefined tasks and initialize them as `draggable` elements. Enable [`externalDrop`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-externalDrop) for the scheduler and set up the predefined event skeletons for the [draggable](https://mobiscroll.com/docs/angular/eventcalendar/drag-and-drop#targeting-the-eventcalendar) component.

Whenever there is more information to be captured, like detailed task notes, customer information, the name of the technician... you can trigger a `popup` with the task form in the [`onEventCreate`](https://mobiscroll.com/docs/angular/eventcalendar/api#event-onEventCreate) lifecycle event. For failed drops (trying to schedule a task during lunch breaks or weekends) the [`event-create-failed`](https://mobiscroll.com/docs/angular/eventcalendar/api#event-onEventCreateFailed) [`onEventCreateFailed`](https://mobiscroll.com/docs/angular/eventcalendar/api#event-onEventCreateFailed) event will be triggered.

**Want to see how external presets look & feel for a calendar?** [Check out this example →](https://demo.mobiscroll.com/angular/eventcalendar/external-event-presets)

## What this demo shows

- A desktop weekly scheduler layout with a fixed week strip at the top, a fixed all-day row below it, and a scrollable scheduler time grid from 6 AM to 8 PM.
- **Header navigation** The month and year label in the top left opens date navigation, while the blue previous and next arrows and the Today button on the right make it easy to move between weeks and jump back to the current day.
- **Week view** The fixed strip below the header displays the days of the selected week, with the current date highlighted by a blue circle.
- **Time grid** The scheduler shows a 14-hour range from 6 AM to 8 PM and supports vertical scrolling.
- **Invalid dates** Weekends and lunch breasks from 12PM to 12:30PM are disabled, so they cannot be used as drop targets for new tasks. When a user tries to drop an event in a restricted date/time, a `Can't create event on this date` toast appears at the bottom center of the scheduler.
- **External task list** A right-side panel titled `Available tasks` displays preset items: `Tire change 0.5 h`, `Break maintenance 1.5 h`, `Fluid maintenance 2 h`, `Oil change 2 h`, `Electric inspection 2.5 h`, and `Engine inspection 4.5 h`.
- **External drag & drop** Tasks can be dragged from the external list and dropped onto the scheduler to schedule predefined events.
- **Created event display** Dropping the task opens a popup below the event label with the title `Assign task`.
- **Popup form** The popup includes a `Task` text field prefilled with the task title, a `Details` text field with the `Add description…` placeholder, and a `Technician` select with the `Please select…` placeholder.
- **Popup confirmation** The popup footer contains a blue `Ok` button in the bottom-right corner to confirm the event details.
- **Scheduled task** After a successful drop and confirmation the task label appears inside day cell and a confirmation toast appears on the bottom center part of the calendar with this message `New task added`.
- **Timed events** Timed events are displayed in the weekly scheduler grid as colored cards with a colored stripe on the left, the event title in bold, and the exact start and end time displayed above the title.
- **Event overlapping** If events overlap, the scheduler places them side by side without hiding any of them or causing other conflicts.
- **Current time** A blue current-time line appears across the time grid, with a small blue dot marking the current date.
- **Hover behavior** Hovering over the time grid shows a time indicator that follows the cursor in 15-minute increments.
- **Event interaction** Hovering over events highlights them and shows drag and resize handles for repositioning or changing duration.
- **Event selection** Clicking an event selects and highlights it.
- **Event creation** Double-clicking the time grid or clicking and dragging on it creates a new event.

## Best for

- **Service scheduling** Planning repeatable service tasks, such as auto repair or vehicle maintenance jobs, from predefined task templates.
- **Template-based booking** Letting teams create scheduler events by dragging standard task presets onto available dates and times.
- **Technician assignment workflows** Capturing extra scheduling details, such as task notes and technician selection, when a task is placed.
- **Restricted availability** Preventing task creation during blocked periods, such as weekends or lunch breaks.
- **Dense weekly planning** Managing timed tasks in a weekly scheduler where overlapping events, current-time tracking, and drag interactions need to stay visible.

## 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
- [`view`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-view) - option
- [`invalid`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-invalid) - option
- [`dragToMove`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-dragToMove) - option
- [`externalDrop`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-externalDrop) - option
- [`onEventCreated`](https://mobiscroll.com/docs/angular/eventcalendar/api#event-onEventCreated) - event
- [`onEventCreateFailed`](https://mobiscroll.com/docs/angular/eventcalendar/api#event-onEventCreateFailed) - event
- [`onEventUpdateFailed`](https://mobiscroll.com/docs/angular/eventcalendar/api#event-onEventUpdateFailed) - event
- [`anchor`](https://mobiscroll.com/docs/angular/popup/api#opt-anchor) - option
- [`display`](https://mobiscroll.com/docs/angular/popup/api#opt-display) - option
- [`width`](https://mobiscroll.com/docs/angular/popup/api#opt-width) - option
- [`touchUi`](https://mobiscroll.com/docs/angular/popup/api#opt-touchUi) - option
- [`headerText`](https://mobiscroll.com/docs/angular/popup/api#opt-headerText) - option
- [`buttons`](https://mobiscroll.com/docs/angular/popup/api#opt-buttons) - option
- [`onClose`](https://mobiscroll.com/docs/angular/popup/api#event-onClose) - event
- [`data`](https://mobiscroll.com/docs/angular/select/api#opt-data) - option
- [`label`](https://mobiscroll.com/docs/angular/select/api#opt-label) - option
- [`display`](https://mobiscroll.com/docs/angular/select/api#opt-display) - option
- [`touchUi`](https://mobiscroll.com/docs/angular/select/api#opt-touchUi) - option

## Code

### Component

```ts
import { CommonModule } from '@angular/common';
import { Component, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MbscEventcalendarOptions, MbscModule, MbscPopup, Notifications, setOptions } from '@mobiscroll/angular';

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

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

  @ViewChild('popup', { static: false })
  popup!: MbscPopup;

  calendarOptions: MbscEventcalendarOptions = {
    view: {
      scheduler: {
        type: 'week',
        allDay: false,
        startTime: '06:00',
        endTime: '20:00',
      },
    },
    invalid: [
      {
        recurring: {
          repeat: 'weekly',
          weekDays: 'SA,SU',
        },
      },
      {
        start: '12:00',
        end: '12:30',
        title: 'Lunch break',
        recurring: {
          repeat: 'weekly',
          weekDays: 'MO,TU,WE,TH,FR',
        },
      },
    ],
    dragToMove: true,
    externalDrop: true,
    onEventCreated: (args) => {
      setTimeout(() => {
        this.fillDialog(args);
      });
    },
    onEventCreateFailed: () => {
      this.notify.toast({
        message: "Can't create event on this date",
      });
    },
    onEventUpdateFailed: () => {
      this.notify.toast({
        message: "Can't add event on this date",
      });
    },
  };

  tasks = [
    {
      title: 'Tire change',
      color: '#7a5886',
      start: '08:00',
      end: '08:30',
      length: '0.5 h',
    },
    {
      title: 'Brake maintenance',
      color: '#9da721',
      start: '08:00',
      end: '09:30',
      length: '1.5 h',
    },
    {
      title: 'Fluid maintenance',
      color: '#cd6957',
      start: '08:00',
      end: '10:00',
      length: '2 h',
    },
    {
      title: 'Oil change',
      color: '#637e57',
      start: '08:00',
      end: '10:00',
      length: '2 h',
    },
    {
      title: 'Electrical inspection',
      color: '#50789d',
      start: '08:00',
      end: '10:30',
      length: '2.5 h',
    },
    {
      title: 'Engine inspection',
      color: '#6c5d45',
      start: '08:00',
      end: '12:30',
      length: '4.5 h',
    },
  ];

  myData = [
    { value: '1', text: 'Roly Chester' },
    { value: '2', text: 'Tucker Wayne' },
    { value: '3', text: 'Baker Brielle' },
    { value: '4', text: 'Jami Walter' },
    { value: '5', text: 'Patrick Toby' },
    { value: '6', text: 'Tranter Logan' },
    { value: '7', text: 'Payton Sinclair' },
  ];

  title = '';
  details = '';
  technician = '';
  anchor: HTMLElement | undefined;
  isOpen = false;

  fillDialog(args: any): void {
    this.title = args.event.title;
    this.details = args.event.details;
    this.technician = args.event.technician;
    this.anchor = args.target;
    this.popup.open();
  }

  onClose(): void {
    this.notify.toast({
      message: 'New task added',
    });
  }
}
```

### Template

```html
<div class="mbsc-grid mbsc-no-padding">
  <div class="mbsc-row">
    <div class="mbsc-col-sm-9 external-event-calendar">
      <mbsc-eventcalendar [options]="calendarOptions"></mbsc-eventcalendar>
    </div>
    <div class="mbsc-col-sm-3">
      <div class="mbsc-form-group-title">Available tasks</div>
      <div
        mbsc-draggable
        *ngFor="let task of tasks;let i = index"
        [dragData]="tasks[i]"
        class="external-event-task"
        [ngStyle]="{background: task.color}"
      >
        <div>{{task.title}}</div>
        <div>{{task.length}}</div>
      </div>
    </div>
    <mbsc-popup
      display="anchored"
      [width]="400"
      [contentPadding]="false"
      [touchUi]="false"
      headerText="Assign task"
      [buttons]="['ok']"
      [anchor]="anchor"
      (onClose)="onClose()"
      #popup
    >
      <div class="mbsc-form-group">
        <mbsc-input label="Task" [(ngModel)]="title" [readonly]="true"></mbsc-input>
        <mbsc-textarea label="Details" [(ngModel)]="details" placeholder="Add description..."></mbsc-textarea>
        <mbsc-select
          [(ngModel)]="technician"
          [data]="myData"
          label="Technician"
          display="anchored"
          [touchUi]="false"
          placeholder="Please select..."
        ></mbsc-select>
      </div>
    </mbsc-popup>
  </div>
</div>
```

### CSS

```css
.external-event-calendar {
  border-right: 1px solid #ccc;
}

.external-event-task {
  color: #fff;
  padding: 10px;
  margin: 20px;
  border-radius: 8px;
  font-family:
    -apple-system,
    Segoe UI,
    Roboto,
    sans-serif;
}

.demo-external-event-presets.demo-wrapper,
.demo-external-event-presets .mbsc-grid,
.demo-external-event-presets .mbsc-row,
.demo-external-event-presets .external-event-calendar {
  height: 100%;
}
```

## Implementation notes

- Use `view: { scheduler: { type: 'week', allDay: false, startTime: '06:00', endTime: '20:00' } }` - no all-day row, 6am-8pm. Enable `externalDrop: true`, `dragToMove: true`. The calendar starts with no events.
- Define an `invalid` array with two recurring ranges: weekends (`SA,SU`) and a lunch break (`12:00–12:30`, Mon-Fri).
- Define 6 static preset tasks, each with `title`, `color`, `start`, `end` (time strings that determine event duration when dropped), and `length` (display string): Tire change (0.5h), Brake maintenance (1.5h), Fluid maintenance (2h), Oil change (2h), Electrical inspection (2.5h), Engine inspection (4.5h).
- Render each task as a draggable item: wrap it with `Draggable` (Angular: `mbsc-draggable` directive, Vue: `MbscDraggable`) and pass `dragData` set to the task object. Tasks remain in the list after dropping - they are presets, not consumed items.
- On `onEventCreated`, open a `Popup` anchored to `args.target` with the title "Assign task". The popup contains a read-only `Input` pre-filled with the task title, a `Textarea` for details, and a `Select` for technician (7 names). On popup close, show a toast "New task added".
- On `onEventCreateFailed`, show a toast "Can't create event on this date". On `onEventUpdateFailed`, show a toast "Can't add event on this date".

## 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: [External Drag and Drop](https://demo.mobiscroll.com/angular/scheduler/external-drag-drop-sortable-dragula.md) - Connect SortableJS or Dragula lists to the Angular Scheduler — drag items in to schedule events and drag events out to unschedule them.
