---
title: "Javascript Event calendar Drag-and-Drop Task Presets Example | Mobiscroll"
component: "Event calendar"
framework: "JavaScript"
library_version: "6.1.5"
url: "https://demo.mobiscroll.com/javascript/eventcalendar/external-event-presets"
---

# Drag-and-Drop Task Presets - JavaScript Event calendar demo

Drag preset task templates from an external list onto a Javascript event calendar — a popup form captures task details and technician at drop time. Plain JavaScript API.

- [Live demo](https://demo.mobiscroll.com/javascript/eventcalendar/external-event-presets)
- [View code on GitHub](https://github.com/acidb/mobiscroll-demos-javascript/tree/main/src/demos/eventcalendar/calendar-view/external-event-presets)
- This demo in other frameworks: [jQuery](https://demo.mobiscroll.com/jquery/eventcalendar/external-event-presets.md), [Angular](https://demo.mobiscroll.com/angular/eventcalendar/external-event-presets.md), [React](https://demo.mobiscroll.com/react/eventcalendar/external-event-presets.md), [Vue](https://demo.mobiscroll.com/vue/eventcalendar/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 a car wrapping shop where different jobs need to be set up depending on the type of vehicle.

Print a list of predefined tasks and initialize them as `draggable` elements. Enable [`externalDrop`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-externalDrop) for the calendar and set up the predefined event skeletons for the [draggable](https://mobiscroll.com/docs/javascript/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/javascript/eventcalendar/api#event-onEventCreate) lifecycle event. For failed drops (trying to schedule a task during lunch breaks or weekends) the [`onEventCreateFailed`](https://mobiscroll.com/docs/javascript/eventcalendar/api#event-onEventCreateFailed) event will be triggered.

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

## What this demo shows

- A desktop month view event calendar paired with an external list of predefined tasks that can be dragged onto the calendar.
- **Calendar layout** The main view shows a full month grid with no events.
- **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.
- **Invalid dates** Weekend days are disabled, so they cannot be used as drop targets for new tasks. When a user tries to drop an event in a restricted cell, a `Can't create event on this date` toast appears at the bottom center of the calendar.
- **External task list** A right-side panel titled `Available tasks` displays preset items: `Small wrap 2 day`, `Full-size wrap 3 days`, `Mid-size wrap 3 days`, `Roadster wrap 3 days`, `SUV wrap 4 days`, and `Hypercar wrap 5 days`.
- **External drag & drop** Tasks can be dragged from the external list and dropped onto a calendar day 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`.
- **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.
- **Gesture navigation** The month view can also be changed by clicking and dragging the calendar left or right.

## Best for

- **Service scheduling** Planning repeatable job types, such as vehicle wrapping tasks, from predefined task templates.
- **Template-based booking** Letting teams create new calendar events by dragging standard task presets onto available dates.
- **Technician assignment workflows** Capturing extra scheduling details, such as notes and technician selection, at the moment a task is placed.

## API used in this demo

- [`theme`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-theme) - option
- [`themeVariant`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-themeVariant) - option
- [`setVal`](https://mobiscroll.com/docs/javascript/select/api#method-setVal) - method
- [`setOptions`](https://mobiscroll.com/docs/javascript/popup/api#method-setOptions) - method
- [`anchor`](https://mobiscroll.com/docs/javascript/popup/api#opt-anchor) - option
- [`open`](https://mobiscroll.com/docs/javascript/popup/api#method-open) - method
- [`view`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-view) - option
- [`labels`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-labels) - option
- [`invalid`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-invalid) - option
- [`dragToMove`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-dragToMove) - option
- [`externalDrop`](https://mobiscroll.com/docs/javascript/eventcalendar/api#opt-externalDrop) - option
- [`onEventCreated`](https://mobiscroll.com/docs/javascript/eventcalendar/api#event-onEventCreated) - event
- [`onEventCreateFailed`](https://mobiscroll.com/docs/javascript/eventcalendar/api#event-onEventCreateFailed) - event
- [`onEventUpdateFailed`](https://mobiscroll.com/docs/javascript/eventcalendar/api#event-onEventUpdateFailed) - event
- [`inputElement`](https://mobiscroll.com/docs/javascript/select/api#opt-inputElement) - option
- [`display`](https://mobiscroll.com/docs/javascript/select/api#opt-display) - option
- [`touchUi`](https://mobiscroll.com/docs/javascript/select/api#opt-touchUi) - option
- [`display`](https://mobiscroll.com/docs/javascript/popup/api#opt-display) - option
- [`width`](https://mobiscroll.com/docs/javascript/popup/api#opt-width) - option
- [`touchUi`](https://mobiscroll.com/docs/javascript/popup/api#opt-touchUi) - option
- [`headerText`](https://mobiscroll.com/docs/javascript/popup/api#opt-headerText) - option
- [`buttons`](https://mobiscroll.com/docs/javascript/popup/api#opt-buttons) - option
- [`onClose`](https://mobiscroll.com/docs/javascript/popup/api#event-onClose) - event

## Code

### JS

```js
mobiscroll.setOptions({
  theme: 'ios',
  themeVariant: 'light'
});

var tasks = [
  {
    title: 'Small wrap',
    color: '#637e57',
    start: '2026-10-28T00:00',
    end: '2026-10-29T00:00',
  },
  {
    title: 'Full-size wrap',
    color: '#50789d',
    start: '2026-10-28T00:00',
    end: '2026-10-30T00:00',
  },
  {
    title: 'Mid-size wrap',
    color: '#6c5d45',
    start: '2026-10-28T00:00',
    end: '2026-10-30T00:00',
  },
  {
    title: 'Roadster wrap',
    color: '#9da721',
    start: '2026-10-28T00:00',
    end: '2026-10-30T00:00',
  },
  {
    title: 'SUV wrap',
    color: '#cd6957',
    start: '2026-10-28T00:00',
    end: '2026-10-31T00:00',
  },
  {
    title: 'Hypercar wrap',
    color: '#7a5886',
    start: '2026-10-28T00:00',
    end: '2026-11-01T00:00',
  },
];
var taskElm = document.querySelectorAll('.external-event-task');

function fillDialog(args) {
  mobiscroll.getInst(document.getElementById('external-event-job')).value = args.event.title;
  mobiscroll.getInst(document.getElementById('external-event-details')).value = args.event.details || '';
  technician.setVal();
  dialog.setOptions({ anchor: args.target });
  dialog.open();
}

mobiscroll.eventcalendar('#external-event-calendar', {
  view: {
    calendar: { labels: true },
  },
  invalid: [
    {
      recurring: {
        repeat: 'weekly',
        weekDays: 'SA,SU',
      },
    },
  ],
  dragToMove: true,
  externalDrop: true,
  onEventCreated: function (args) {
    fillDialog(args);
  },
  onEventCreateFailed: function () {
    mobiscroll.toast({
      message: "Can't create event on this date",
    });
  },
  onEventUpdateFailed: function () {
    mobiscroll.toast({
      message: "Can't add event on this date",
    });
  },
});

var technician = mobiscroll.select('#external-event-select', {
  inputElement: document.getElementById('external-event-select-input'),
  display: 'anchored',
  touchUi: false,
});

var dialog = mobiscroll.popup('#external-event-dialog', {
  display: 'anchored',
  width: 400,
  contentPadding: false,
  touchUi: false,
  headerText: 'Assign task',
  buttons: ['ok'],
  onClose: function () {
    mobiscroll.toast({
      message: 'New task added',
    });
  },
});

for (var i = 0; i < taskElm.length; i++) {
  mobiscroll.draggable(taskElm[i], { dragData: tasks[i] });
}
```

### HTML

```html
<div class="mbsc-grid mbsc-no-padding">
    <div class="mbsc-row">
        <div class="mbsc-col-sm-9 external-event-calendar">
            <div id="external-event-calendar"></div>
        </div>
        <div class="mbsc-col-sm-3">
            <div class="mbsc-form-group-title">Available tasks</div>

            <div class="external-event-task" style="background: #637e57;">
                <div>Small wrap</div>
                <div>2 days</div>
            </div>

            <div class="external-event-task" style="background: #50789d;">
                <div>Full-size wrap</div>
                <div>3 days</div>
            </div>

            <div class="external-event-task" style="background: #6c5d45;">
                <div>Mid-size wrap</div>
                <div>3 days</div>
            </div>

            <div class="external-event-task" style="background: #9da721;">
                <div>Roadster wrap</div>
                <div>3 days</div>
            </div>

            <div class="external-event-task" style="background: #cd6957;">
                <div>SUV wrap</div>
                <div>4 days</div>
            </div>

            <div class="external-event-task" style="background: #7a5886;">
                <div>Hypercar wrap</div>
                <div>5 days</div>
            </div>
        </div>
    </div>
</div>

<div id="external-event-dialog">
    <div class="mbsc-form-group">
        <label for="external-event-job">
            <input id="external-event-job" mbsc-input data-label="Task" readonly></input>
        </label>
        <label for="external-event-details">
            <textarea id="external-event-details" mbsc-textarea data-label="Details" placeholder="Add description..."></textarea>
        </label>
        <label>
           Technician
            <input mbsc-input id="external-event-select-input" placeholder="Please select..." data-dropdown="true" />
        </label>
        <select id="external-event-select">
           <option value="1">Roly Chester</option>
                <option value="2">Tucker Wayne</option>
                <option value="3">Baker Brielle</option>
                <option value="4">Jami Walter</option>
                <option value="5">Patrick Toby</option>
                <option value="6">Tranter Logan</option>
                <option value="7">Payton Sinclair</option>
        </select>
    </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

- Set `view: { calendar: { labels: true } }`. Enable `externalDrop: true` to accept drops from outside the calendar and `dragToMove: true` to allow moving already-placed events. Block weekends with `invalid: [{ recurring: { repeat: 'weekly', weekDays: 'SA,SU' } }]`.
- Define each preset task as an object with `title`, `color`, `start`, and `end` fields (where `start`/`end` represent today-relative offsets that set the event duration when dropped). Render the task list outside the calendar and initialize each item as a draggable element using the `Draggable` component with `dragData` set to the task object. Angular: use the `mbsc-draggable` directive with `[dragData]`. JS/jQuery: call `mobiscroll.draggable(element, { dragData: task })` for each task element.
- Handle `onEventCreated` (Vue: `@event-created`) after a successful drop: open an anchored `Popup` targeting `args.target` with `display="anchored"`. The popup contains a read-only `Input` prefilled with `args.event.title`, a `Textarea` for details, and a `Select` for technician assignment, with an `['ok']` button to confirm. Show a `Toast` with `'New task added'` when the popup closes. Angular: use `@ViewChild` to get the `MbscPopup` instance and call `.open()` imperatively.
- Handle `onEventCreateFailed` and `onEventUpdateFailed` (Vue: `@event-create-failed`, `@event-update-failed`) to show a `Toast` when a drop lands on a weekend or other invalid 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-javascript.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 javascript
   ```

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 javascript --trial`.

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

## Related demos

- Previous: [Double Booking Prevention](https://demo.mobiscroll.com/javascript/eventcalendar/prevent-double-booking-events.md) - Prevent overlapping events in a Javascript event calendar — block double bookings per event or across all events with in-calendar conflict alerts.
- Next: [Drag and Drop from External Lists](https://demo.mobiscroll.com/javascript/eventcalendar/external-drag-drop-sortable-dragula.md) - Drag items from external SortableJS or Dragula lists onto a Javascript event calendar to schedule events — or drag them out to unschedule.
