---
title: "Vue Scheduler Bulk Event Actions Example | Mobiscroll"
component: "Scheduler"
framework: "Vue"
library_version: "6.2.0"
url: "https://demo.mobiscroll.com/vue/scheduler/event-bulk-actions-edit-delete-update"
---

# Bulk Event Actions - Vue Scheduler demo

Add bulk event actions to Vue Scheduler — select multiple events via shortcuts or select-all, apply bulk actions, and use right-click for per-event actions. For Vue and Nuxt.

- [Live demo](https://demo.mobiscroll.com/vue/scheduler/event-bulk-actions-edit-delete-update)
- [View SFC JS code on GitHub](https://github.com/acidb/mobiscroll-demos-vue/tree/main/src/demos/eventcalendar/scheduler/event-bulk-actions-edit-delete-update)
- [View SFC TS code on GitHub](https://github.com/acidb/mobiscroll-demos-vue-ts/tree/main/src/demos/eventcalendar/scheduler/event-bulk-actions-edit-delete-update)
- This demo in other frameworks: [JavaScript](https://demo.mobiscroll.com/javascript/scheduler/event-bulk-actions-edit-delete-update.md), [jQuery](https://demo.mobiscroll.com/jquery/scheduler/event-bulk-actions-edit-delete-update.md), [Angular](https://demo.mobiscroll.com/angular/scheduler/event-bulk-actions-edit-delete-update.md), [React](https://demo.mobiscroll.com/react/scheduler/event-bulk-actions-edit-delete-update.md)

## Description

Multiple event selection can be turned on with the [`selectMultipleEvents`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-selectMultipleEvents) option. Selecting multiple events can be done through user interaction with `CTRL`/`SHIFT`/`CMD` + click or programmatically eg. click of a button or 'select all' checkbox.

Bulk operations like delete, update can be applied the selected events. Things like deleting with the `backspace` or `delete` buttons work out of the box but custom actions can be also applied. The selection can be easily retrieved and updated with the [`selectedEvents`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-selectedEvents) option and the [`selected-events-change`](https://mobiscroll.com/docs/vue/eventcalendar/api#event-onSelectedEventsChange) event.

Custom actions can be performed with external buttons or with context menu activated on right-click.

## 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 for the selected week.
- **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.
- **All-day events** All-day events appear in a dedicated row that stays fixed above the time grid.
- **Time grid** The scheduler grid scrolls vertically through the hours of the selected week.
- **Bulk action panel** A side panel next to the scheduler contains `Select all from view`, `Reset selection`, and `Update selected` actions.
- **Select all from view** Clicking this action selects all events currently visible and highlights thei titles in the week view and shows a bottom-centered toast message: `All events selected from the view`.
- **Reset selection** Clicking this action clears the current selection and shows a bottom-centered toast message: `Selection cleared`.
- **Update selected** Clicking this action changes the color of all selected events to orange and shows a bottom-centered toast message: `All selected event's color changed to orange`.
- **Currently selected** The side panel includes a `Currently selected` section that is empty by default and lists the titles of all selected events when one or more events are selected.
- **Multi-selection** Users can select multiple events with `CTRL`/`SHIFT`/`CMD` + click.
- **Context menu** Right-clicking an event opens a small popup with `Update` and `Delete` actions for that event.
- **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 creation** Double-clicking the time grid or clicking and dragging on it creates a new event.

## Best for

- **Scheduling tools** Scheduling interfaces where users need to review and manage many visible events in a week view.
- **Resource management** Resource planning workflows that require selecting and adjusting multiple bookings, assignments, or availability blocks together.
- **Operations teams** Internal tools for managing appointments, team shifts, project deadlines, or other time-based records in batches.
- **Mixed individual and batch actions** Use cases that need both multi-event actions and single-event actions from a contextual right-click menu.

## 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
- [`getEvents`](https://mobiscroll.com/docs/vue/eventcalendar/api#method-getEvents) - method
- [`data`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-data) - option
- [`view`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-view) - option
- [`clickToCreate`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-clickToCreate) - option
- [`selectMultipleEvents`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-selectMultipleEvents) - option
- [`selectedEvents`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-selectedEvents) - option
- [`event-delete`](https://mobiscroll.com/docs/vue/eventcalendar/api#event-onEventDelete) - event
- [`page-loading`](https://mobiscroll.com/docs/vue/eventcalendar/api#event-onPageLoading) - event
- [`selected-events-change`](https://mobiscroll.com/docs/vue/eventcalendar/api#event-onSelectedEventsChange) - event
- [`event-right-click`](https://mobiscroll.com/docs/vue/eventcalendar/api#event-onEventRightClick) - event
- [`display`](https://mobiscroll.com/docs/vue/select/api#opt-display) - option
- [`inputProps`](https://mobiscroll.com/docs/vue/select/api#opt-inputProps) - option
- [`touchUi`](https://mobiscroll.com/docs/vue/select/api#opt-touchUi) - option
- [`anchor`](https://mobiscroll.com/docs/vue/select/api#opt-anchor) - option
- [`data`](https://mobiscroll.com/docs/vue/select/api#opt-data) - option
- [`isOpen`](https://mobiscroll.com/docs/vue/select/api#opt-isOpen) - option
- [`change`](https://mobiscroll.com/docs/vue/select/api#event-onChange) - event
- [`close`](https://mobiscroll.com/docs/vue/select/api#event-onClose) - event
- [`close`](https://mobiscroll.com/docs/vue/notifications/confirm#event-onClose) - event
- [`close`](https://mobiscroll.com/docs/vue/notifications/toast#event-onClose) - event

## Code

### SFC JS

```vue
<script setup>
import {
  formatDate,
  getJson,
  MbscButton,
  MbscConfirm,
  MbscEventcalendar,
  MbscPage,
  MbscSelect,
  MbscToast,
  setOptions
} from '@mobiscroll/vue'
import { onMounted, ref } from 'vue'

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

const myView = {
  scheduler: {
    type: 'week'
  }
}

const contextMenu = [
  {
    text: 'Update',
    value: 'update'
  },
  {
    text: 'Delete',
    value: 'delete'
  }
]

const myEvents = ref([])
const mySelectedEvents = ref([])
const eventTitles = ref()
const firstDay = ref()
const lastDay = ref()
const menuAnchor = ref()
const menuOpen = ref()
const selected = ref()
const isConfirmOpen = ref()
const confirmMessage = ref()
const confirmCallback = ref()
const toastMessage = ref()
const isToastOpen = ref()
const calElm = ref()

function getSelectedEventTitles(events) {
  let titles = []

  for (const event of events) {
    titles = [...titles, event.title]
  }
  return titles
}

function refreshSelectedEvents(events) {
  mySelectedEvents.value = events
  eventTitles.value = getSelectedEventTitles(events)
}

function deleteSelectedEvents() {
  isConfirmOpen.value = true
  confirmMessage.value = getSelectedEventTitles(mySelectedEvents.value).join(', ')
  confirmCallback.value = function (result) {
    if (result) {
      let eventsToUpdate = [...myEvents.value]

      for (const event of mySelectedEvents.value) {
        if (event.recurring) {
          const origEvent = event.original
          let exc = origEvent.recurringException || []
          exc = [...exc, event.start]
          origEvent.recurringException = exc

          // Update the event in the list
          const index = eventsToUpdate.findIndex((x) => x.id === origEvent.id)
          eventsToUpdate.splice(index, 1, origEvent)
        } else {
          eventsToUpdate = eventsToUpdate.filter((ev) => ev.id !== event.id)
        }
      }

      myEvents.value = eventsToUpdate
      refreshSelectedEvents([])

      toastMessage.value = 'Deleted'
      isToastOpen.value = true
    }
    isConfirmOpen.value = false
  }
}

function updateSelectedEvents() {
  const events =
    mySelectedEvents.value.length === 0 ? [mySelectedEvents.value] : mySelectedEvents.value
  let eventsToUpdate = [...myEvents.value]

  for (const event of events) {
    if (event.recurring) {
      const origEvent = event.original
      let exc = origEvent.recurringException || []
      const newEvent = event

      newEvent.recurring = undefined
      newEvent.color = 'orange'
      newEvent.id += '_' + formatDate('YYYY-MM-DD', event.start)
      eventsToUpdate = [...eventsToUpdate, newEvent]

      exc = [...exc, event.start]
      origEvent.recurringException = exc

      // Update the event in the list
      const index = eventsToUpdate.findIndex((x) => x.id === origEvent.id)
      eventsToUpdate.splice(index, 1, origEvent)
    } else {
      const newEv = event
      newEv.color = 'orange'
      const index = eventsToUpdate.findIndex((x) => x.id === newEv.id)
      eventsToUpdate.splice(index, 1, newEv)
    }
  }

  toastMessage.value = "All selected event's color changed to orange"
  isToastOpen.value = true

  myEvents.value = eventsToUpdate
  refreshSelectedEvents([])
}

function selectAllEvents() {
  const selectedEvents = calElm.value.instance.getEvents(firstDay.value, lastDay.value)
  refreshSelectedEvents(selectedEvents)
  toastMessage.value = 'All events selected from view'
  isToastOpen.value = true
}

function resetSelection() {
  refreshSelectedEvents([])
  toastMessage.value = 'Selection cleared'
  isToastOpen.value = true
}

function handlePageLoading(args) {
  setTimeout(() => {
    firstDay.value = args.firstDay
    lastDay.value = args.lastDay
  })
}

function handleSelectedEventsChange(args) {
  if (args.events) {
    refreshSelectedEvents(args.events)
  }
}

function handleEventRightClick(args) {
  args.domEvent.preventDefault()
  menuAnchor.value = args.domEvent.target
  setTimeout(() => {
    menuOpen.value = true
  })
}

function handleEventDelete() {
  if (!isConfirmOpen.value) {
    deleteSelectedEvents()
    return false
  }
}

function handleSelectChange(args) {
  selected.value = args.value
  if (args.value === 'update') {
    updateSelectedEvents()
  } else if (args.value === 'delete') {
    deleteSelectedEvents()
  }
}

function handleMenuClose() {
  selected.value = ''
  menuOpen.value = false
}

function handleConfirmClose() {
  isConfirmOpen.value = false
}

function handleToastClose() {
  isToastOpen.value = false
}

onMounted(() => {
  getJson(
    'https://trial.mobiscroll.com/events/?vers=5',
    (events) => {
      myEvents.value = events
    },
    'jsonp'
  )

  document.querySelector('.md-bulk-operations').addEventListener('keydown', (ev) => {
    if (!isConfirmOpen.value && (ev.keyCode === 8 || ev.keyCode === 46)) {
      deleteSelectedEvents()
    }
  })
})
</script>

<template>
  <MbscPage className="md-bulk-operations">
    <div class="mbsc-grid mbsc-no-padding">
      <div class="mbsc-row">
        <div class="mbsc-col-sm-9 mbsc-push-sm-3">
          <MbscEventcalendar
            className="md-bulk-operations-border"
            ref="calElm"
            :data="myEvents"
            :view="myView"
            :clickToCreate="true"
            :selectMultipleEvents="true"
            :selectedEvents="mySelectedEvents"
            @event-delete="handleEventDelete"
            @page-loading="handlePageLoading"
            @selected-events-change="handleSelectedEventsChange"
            @event-right-click="handleEventRightClick"
          />
          <MbscSelect
            display="anchored"
            :inputProps="{ type: 'hidden' }"
            :touchUi="false"
            :anchor="menuAnchor"
            :data="contextMenu"
            :value="selected"
            :isOpen="menuOpen"
            @change="handleSelectChange"
            @close="handleMenuClose"
          />
        </div>
        <div class="mbsc-col-sm-3 mbsc-pull-sm-9">
          <div class="mbsc-form-group">
            <div class="mbsc-button-group-block">
              <MbscButton @click="selectAllEvents">Select all this month</MbscButton>
              <MbscButton @click="resetSelection">Reset selection</MbscButton>
              <MbscButton @click="updateSelectedEvents">Update selected</MbscButton>
            </div>
          </div>
          <div class="mbsc-form-group-title">Currently selected</div>
          <div class="mbsc-padding md-selected-event-list">
            <ul>
              <li v-for="title in eventTitles" :key="title">{{ title }}</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
    <MbscConfirm
      title="Are you sure you want to delete the following events?"
      okText="Delete"
      :message="confirmMessage"
      :callback="confirmCallback"
      :isOpen="isConfirmOpen"
      @close="handleConfirmClose"
    />
    <MbscToast :message="toastMessage" :isOpen="isToastOpen" @close="handleToastClose" />
  </MbscPage>
</template>

<style>
.md-bulk-operations {
  border-left: 1px solid #ccc;
}

.md-selected-event-list {
  height: 500px;
  overflow: auto;
  padding-top: 0;
  padding-bottom: 0;
}
</style>
```

### SFC TS

```vue
<script setup lang="ts">
import {
  formatDate,
  getJson,
  MbscButton,
  MbscConfirm,
  MbscEventcalendar,
  MbscPage,
  MbscSelect,
  MbscToast,
  setOptions
} from '@mobiscroll/vue'
import type {
  MbscCalendarEvent,
  MbscEventcalendarView,
  MbscEventClickEvent,
  MbscPageLoadingEvent,
  MbscSelectedEventsChangeEvent
} from '@mobiscroll/vue'
import { onMounted, ref } from 'vue'

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

const myView: MbscEventcalendarView = {
  scheduler: {
    type: 'week'
  }
}

const contextMenu = [
  {
    text: 'Update',
    value: 'update'
  },
  {
    text: 'Delete',
    value: 'delete'
  }
]

const myEvents = ref<MbscCalendarEvent[]>([])
const mySelectedEvents = ref<MbscCalendarEvent[]>([])
const eventTitles = ref<string[]>([])
const firstDay = ref<any>(null)
const lastDay = ref<any>(null)
const menuAnchor = ref<any>(null)
const menuOpen = ref<boolean>(false)
const selected = ref<string>('')
const isConfirmOpen = ref<boolean>(false)
const confirmMessage = ref<string>('')
const confirmCallback = ref<any>()
const toastMessage = ref<string>('')
const isToastOpen = ref<boolean>(false)
const calElm = ref<any>()

function getSelectedEventTitles(events: MbscCalendarEvent[]) {
  return events.map((e) => e.title || '')
}

function refreshSelectedEvents(events: MbscCalendarEvent[]) {
  mySelectedEvents.value = events
  eventTitles.value = getSelectedEventTitles(events)
}

function deleteSelectedEvents() {
  isConfirmOpen.value = true
  confirmMessage.value = getSelectedEventTitles(mySelectedEvents.value).join(', ')
  confirmCallback.value = (result: boolean) => {
    if (result) {
      let eventsToUpdate = [...myEvents.value]

      for (const event of mySelectedEvents.value) {
        if (event.recurring) {
          const origEvent = event.original!
          let exc: any = origEvent.recurringException || []
          exc = [...exc, event.start]
          origEvent.recurringException = exc

          // Update the event in the list
          const index = eventsToUpdate.findIndex((x) => x.id === origEvent.id)
          eventsToUpdate.splice(index, 1, origEvent)
        } else {
          eventsToUpdate = eventsToUpdate.filter((ev) => ev.id !== event.id)
        }
      }

      myEvents.value = eventsToUpdate
      refreshSelectedEvents([])

      toastMessage.value = 'Deleted'
      isToastOpen.value = true
    }
    isConfirmOpen.value = false
  }
}

function updateSelectedEvents() {
  const events: any =
    mySelectedEvents.value.length === 0 ? [mySelectedEvents.value] : mySelectedEvents.value
  let eventsToUpdate = [...myEvents.value]

  for (const event of events) {
    if (event.recurring) {
      const origEvent = event.original
      let exc = origEvent.recurringException || []
      const newEvent = event

      newEvent.recurring = undefined
      newEvent.color = 'orange'
      newEvent.id += '_' + formatDate('YYYY-MM-DD', event.start)
      eventsToUpdate = [...eventsToUpdate, newEvent]

      exc = [...exc, event.start]
      origEvent.recurringException = exc

      // Update the event in the list
      const index = eventsToUpdate.findIndex((x) => x.id === origEvent.id)
      eventsToUpdate.splice(index, 1, origEvent)
    } else {
      const newEv = event
      newEv.color = 'orange'
      const index = eventsToUpdate.findIndex((x) => x.id === newEv.id)
      eventsToUpdate.splice(index, 1, newEv)
    }
  }

  toastMessage.value = "All selected event's color changed to orange"
  isToastOpen.value = true

  myEvents.value = eventsToUpdate
  refreshSelectedEvents([])
}

function selectAllEvents() {
  const selectedEvents = calElm.value.instance.getEvents(firstDay.value, lastDay.value)
  refreshSelectedEvents(selectedEvents)
  toastMessage.value = 'All events selected from view'
  isToastOpen.value = true
}

function resetSelection() {
  refreshSelectedEvents([])
  toastMessage.value = 'Selection cleared'
  isToastOpen.value = true
}

function handlePageLoading(args: MbscPageLoadingEvent) {
  setTimeout(() => {
    firstDay.value = args.firstDay
    lastDay.value = args.lastDay
  })
}

function handleSelectedEventsChange(args: MbscSelectedEventsChangeEvent) {
  if (args.events) {
    refreshSelectedEvents(args.events)
  }
}

function handleEventRightClick(args: MbscEventClickEvent) {
  args.domEvent.preventDefault()
  menuAnchor.value = args.domEvent.target
  setTimeout(() => {
    menuOpen.value = true
  })
}

function handleEventDelete() {
  if (!isConfirmOpen.value) {
    deleteSelectedEvents()
    return false
  }
}

function handleSelectChange(args: any) {
  selected.value = args.value
  if (args.value === 'update') {
    updateSelectedEvents()
  } else if (args.value === 'delete') {
    deleteSelectedEvents()
  }
}

function handleMenuClose() {
  selected.value = ''
  menuOpen.value = false
}

function handleConfirmClose() {
  isConfirmOpen.value = false
}

function handleToastClose() {
  isToastOpen.value = false
}

onMounted(() => {
  getJson(
    'https://trial.mobiscroll.com/events/?vers=5',
    (events) => {
      myEvents.value = events
    },
    'jsonp'
  )

  document.querySelector('.md-bulk-operations')!.addEventListener('keydown', (ev: any) => {
    if (!isConfirmOpen.value && (ev.keyCode === 8 || ev.keyCode === 46)) {
      deleteSelectedEvents()
    }
  })
})
</script>

<template>
  <MbscPage className="md-bulk-operations">
    <div class="mbsc-grid mbsc-no-padding">
      <div class="mbsc-row">
        <div class="mbsc-col-sm-9 mbsc-push-sm-3">
          <MbscEventcalendar
            className="md-bulk-operations-border"
            ref="calElm"
            :data="myEvents"
            :view="myView"
            :clickToCreate="true"
            :selectMultipleEvents="true"
            :selectedEvents="mySelectedEvents"
            @event-delete="handleEventDelete"
            @page-loading="handlePageLoading"
            @selected-events-change="handleSelectedEventsChange"
            @event-right-click="handleEventRightClick"
          />
          <MbscSelect
            display="anchored"
            :inputProps="{ type: 'hidden' }"
            :touchUi="false"
            :anchor="menuAnchor"
            :data="contextMenu"
            :value="selected"
            :isOpen="menuOpen"
            @change="handleSelectChange"
            @close="handleMenuClose"
          />
        </div>
        <div class="mbsc-col-sm-3 mbsc-pull-sm-9">
          <div class="mbsc-form-group">
            <div class="mbsc-button-group-block">
              <MbscButton @click="selectAllEvents">Select all this month</MbscButton>
              <MbscButton @click="resetSelection">Reset selection</MbscButton>
              <MbscButton @click="updateSelectedEvents">Update selected</MbscButton>
            </div>
          </div>
          <div class="mbsc-form-group-title">Currently selected</div>
          <div class="mbsc-padding md-selected-event-list">
            <ul>
              <li v-for="title in eventTitles" :key="title">{{ title }}</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
    <MbscConfirm
      title="Are you sure you want to delete the following events?"
      okText="Delete"
      :message="confirmMessage"
      :callback="confirmCallback"
      :isOpen="isConfirmOpen"
      @close="handleConfirmClose"
    />
    <MbscToast :message="toastMessage" :isOpen="isToastOpen" @close="handleToastClose" />
  </MbscPage>
</template>

<style>
.md-bulk-operations {
  border-left: 1px solid #ccc;
}

.md-selected-event-list {
  height: 500px;
  overflow: auto;
  padding-top: 0;
  padding-bottom: 0;
}
</style>
```

## Implementation notes

- Use `view: { scheduler: { type: 'week' } }`. Set `selectMultipleEvents: true` to enable Ctrl/Shift/Cmd+click multi-selection. Load events from `https://trial.mobiscroll.com/events/?vers=5` via JSONP. React/Angular/Vue: assign the fetched array to the state/property bound to the `data` prop. JS/jQuery (imperative API): call `inst.setEvents(events)` on load.
- Use a two-column layout: the calendar occupies most of the space; the sidebar contains three action buttons and a scrollable list of selected event titles. Button labels: React/Vue use "Select all this month"; Angular/JS/jQuery use "Select all from view"; all frameworks use "Reset selection" and "Update selected".
- Track `firstDay` and `lastDay` via `onPageLoading` (`args.firstDay`, `args.lastDay`). `onSelectedEventsChange` → update the current selection and refresh the displayed titles list.
- **"Select all"**: call `inst.getEvents(firstDay, lastDay)` to retrieve visible events, then set them as selected; for the imperative API, call `inst.setSelectedEvents(events)`. Show toast.
- **"Reset selection"**: clear `selectedEvents`; for the imperative API, call `inst.setSelectedEvents([])`. Show toast.
- **"Update selected"**: iterate the selected events. For **recurring occurrences**: clear `recurring`, set `color = 'orange'`, append `'_' + formatDate('YYYY-MM-DD', event.start)` to the `id`, push `event.start` to `origEvent.recurringException`, then persist the detached event and the updated original. For **non-recurring**: set `color = 'orange'` and update in place. Update the events array in place; for the imperative API, call `inst.updateEvent(eventsToUpdate)` and `inst.addEvent(newEvents)`. Reset selection, show toast.
- **`deleteSelectedEvents()`**: show a confirm dialog ("Are you sure you want to delete the following events?" / okText: "Delete") with selected event titles joined by `', '`. On confirm: for **recurring** events push `event.start` to `origEvent.recurringException` and update the original; for **non-recurring**, remove from the events array; for the imperative API, call `inst.removeEvent(eventsToDelete)` and `inst.setSelectedEvents([])`. Reset selection, show "Deleted" toast.
- **Delete entry points**: (1) **`onEventDelete`** - `return false` (all frameworks); (2) **`onEventUpdate` with `args.isDelete === true`** - `return false` (React/Angular/JS/jQuery; Vue omits `onEventUpdate`); (3) **context menu "Delete"**. Use a `confirmOpen` flag to prevent double-triggering from (1) and (2).
- **Right-click context menu**: `onEventRightClick` → `args.domEvent.preventDefault()`, open an anchored `Select` popup with "Update" / "Delete" options. Imperative API: also store `selectedEvent = args.event` as a fallback - used in `deleteSelectedEvents` and `updateSelectedEvents` when `inst.getSelectedEvents()` returns an empty array.
- **Keyboard delete**: attach a `keydown` listener on the container; if Delete or Backspace is pressed and no confirm dialog is open, call `deleteSelectedEvents()`.

## 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: [Create, Edit and Delete Events](https://demo.mobiscroll.com/vue/scheduler/create-read-update-delete-CRUD.md) - Implement full event CRUD in a Vue Scheduler — drag or click to create events, confirm via a custom dialog, then drag to move, resize, or delete.
- Next: [Recurring Event Add & Edit](https://demo.mobiscroll.com/vue/scheduler/recurring-event-add-edit-dialog.md) - Add a recurrence editor to the Vue Scheduler event dialog — with daily, weekly, monthly, and custom presets plus an RRULE builder.
