---
title: "Angular Popup Event creation modal Example | Mobiscroll"
component: "Popup"
framework: "Angular"
library_version: "6.2.0"
url: "https://demo.mobiscroll.com/angular/popup/add-event-modal"
---

# Event creation modal - Angular Popup demo

Use the Angular popup for event add/edit modals. Trigger within the event calendar component and load your own custom forms.

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

## Description

Use the popup to show a modal with an add/edit form for event creation and/or update. The popup can be easily set up to be shown right in the middle of the screen, top, bottom or anchored to the newly added event. Check out the [different display modes](https://demo.mobiscroll.com/angular/popup/mobile-desktop-display) and play around with the different configurations.

You have full control over what is shown within the popup. Use [Mobiscroll form elements](https://demo.mobiscroll.com/angular/forms) or any components that you are already using throughout your application.

**Interested in exploring the event calendar?** [Check out these examples →](https://demo.mobiscroll.com/angular/eventcalendar)

## What this demo shows

- Shows a full month calendar which displays events with a custom `Add new event` button above it.
- **Event creation** Clicking `Add new event` opens a popup containing an event form.
- **Event editing** The same popup supports updating an existing event.
- **Event form** The editor includes fields for the title, description, all-day setting, start and end dates, travel time, event color, and busy or free status.
- **Date selection** The start and end date inputs open a date picker with range selection.
- **Save and close behavior** Clicking outside the popup or selecting Cancel closes the editor without applying changes. Selecting Save applies the event changes.
- **Delete flow** The edit dialog includes a `Delete event` action that removes the event from the calendar.
- **Responsive behavior** The dialog adapts to the screen size and device type, with touch-optimized controls such as scrollers on smaller screens and touch devices.
- **Mobile presentation** On smaller screens, the dialog appears as a sheet instead of a popover.
- **Day cell states** Hovering over a day cell highlights the day number with a gray background. Clicking an empty area of the cell selects the day and highlights the day number with a blue background.

## Best for

- **Appointment scheduling** Collect event details, dates, travel time, and availability in a dedicated creation and editing form.
- **Field service calendars** Capture travel time and job details when scheduling work across different locations.
- **Team calendars** Use event colors and busy or free status to communicate event types and availability.
- **Responsive scheduling interfaces** Present the same event workflow as a popover on larger screens and a touch-friendly sheet on smaller screens.

## API used in this demo

- [`theme`](https://mobiscroll.com/docs/angular/popup/api#opt-theme) - option
- [`themeVariant`](https://mobiscroll.com/docs/angular/popup/api#opt-themeVariant) - option
- [`select`](https://mobiscroll.com/docs/angular/datepicker/api#opt-select) - option
- [`showRangeLabels`](https://mobiscroll.com/docs/angular/datepicker/api#opt-showRangeLabels) - option
- [`touchUi`](https://mobiscroll.com/docs/angular/datepicker/api#opt-touchUi) - option
- [`display`](https://mobiscroll.com/docs/angular/datepicker/api#opt-display) - option
- [`width`](https://mobiscroll.com/docs/angular/popup/api#opt-width) - option
- [`headerText`](https://mobiscroll.com/docs/angular/popup/api#opt-headerText) - option
- [`display`](https://mobiscroll.com/docs/angular/popup/api#opt-display) - option
- [`buttons`](https://mobiscroll.com/docs/angular/popup/api#opt-buttons) - option
- [`cssClass`](https://mobiscroll.com/docs/angular/popup/api#opt-cssClass) - option
- [`showOverlay`](https://mobiscroll.com/docs/angular/popup/api#opt-showOverlay) - option
- [`controls`](https://mobiscroll.com/docs/angular/datepicker/api#opt-controls) - option
- [`startInput`](https://mobiscroll.com/docs/angular/datepicker/api#opt-startInput) - option
- [`endInput`](https://mobiscroll.com/docs/angular/datepicker/api#opt-endInput) - option
- [`data`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-data) - option
- [`view`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-view) - option
- [`selectedDate`](https://mobiscroll.com/docs/angular/eventcalendar/api#opt-selectedDate) - option

## Code

### Component

```ts
import { CommonModule } from '@angular/common';
import { Component, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import {
  MbscCalendarEvent,
  MbscDatepickerOptions,
  MbscEventcalendarView,
  MbscModule,
  MbscPopup,
  MbscPopupOptions,
  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;

  myEvents: MbscCalendarEvent[] = [
    {
      id: 1,
      start: '2026-10-08T13:00',
      end: '2026-10-08T13:45',
      title: "Lunch @ Butcher's",
      description: '',
      allDay: false,
      bufferBefore: 15,
      free: true,
      color: '#009788',
    },
    {
      id: 2,
      start: '2026-10-30T15:00',
      end: '2026-10-30T16:00',
      title: 'Conference',
      description: '',
      allDay: false,
      bufferBefore: 30,
      free: false,
      color: '#ff9900',
    },
    {
      id: 3,
      start: '2026-10-29T18:00',
      end: '2026-10-29T22:00',
      title: 'Site Visit',
      description: '',
      allDay: false,
      bufferBefore: 60,
      free: true,
      color: '#3f51b5',
    },
    {
      id: 4,
      start: '2026-10-31T10:30',
      end: '2026-10-31T11:30',
      title: 'Stakeholder mtg.',
      description: '',
      allDay: false,
      free: false,
      color: '#f44437',
    },
  ];

  myView: MbscEventcalendarView = { calendar: { type: 'month' } };

  popupEventTitle: string | undefined;
  popupEventDescription = '';
  popupEventAllDay = true;
  popupEventDates: any;
  popupEventStatus = false;
  mySelectedDate: any;

  datePickerControls = ['calendar'];
  datetimePickerControls = ['calendar', 'time'];

  datePickerOptions: MbscDatepickerOptions = {
    select: 'range',
    showRangeLabels: false,
    touchUi: true,
    display: 'anchored',
  };

  popupOptions: MbscPopupOptions = {
    width: 400,
    contentPadding: false,
    headerText: 'Add new event',
    display: 'center',
    buttons: [
      'cancel',
      {
        text: 'Add',
        keyCode: 'enter',
        handler: () => {
          const newEvent = {
            title: this.popupEventTitle,
            description: this.popupEventDescription,
            allDay: this.popupEventAllDay,
            status: this.popupEventStatus,
            start: this.popupEventDates[0],
            end: this.popupEventDates[1],
          };

          this.myEvents = [...this.myEvents, newEvent];
          this.mySelectedDate = this.popupEventDates[0];

          this.popup.close();
          this.notify.toast({
            message: 'Event added',
          });
        },
        cssClass: 'mbsc-popup-button-primary',
      },
    ],
    showOverlay: false,
  };

  addEvent(): void {
    this.popupEventTitle = 'New Event';
    this.popupEventDescription = '';
    this.popupEventAllDay = false;
    this.popupEventStatus = false;
    this.popupEventDates = [new Date(), new Date()];
    this.popup.open();
  }
}
```

### Template

```html
<mbsc-page>
  <div class="mbsc-form-group">
    <div class="mbsc-button-group-block">
      <mbsc-button (click)="addEvent()">Add event</mbsc-button>
    </div>
  </div>

  <mbsc-popup #popup [options]="popupOptions">
    <div class="mbsc-form-group">
      <mbsc-input label="Title" [(ngModel)]="popupEventTitle"></mbsc-input>
      <mbsc-input label="Description" [(ngModel)]="popupEventDescription"></mbsc-input>
    </div>
    <div class="mbsc-form-group">
      <mbsc-switch label="All-day" [(ngModel)]="popupEventAllDay"></mbsc-switch>
      <mbsc-datepicker
        [(ngModel)]="popupEventDates"
        [options]="datePickerOptions"
        [controls]="popupEventAllDay ? datePickerControls : datetimePickerControls"
        [startInput]="startInput"
        [endInput]="endInput"
      ></mbsc-datepicker>
      <mbsc-input #startInput label="Starts"></mbsc-input>
      <mbsc-input #endInput label="Ends"></mbsc-input>
    </div>
    <mbsc-segmented-group [(ngModel)]="popupEventStatus">
      <mbsc-segmented value="busy">Show as busy</mbsc-segmented>
      <mbsc-segmented value="free">Show as free</mbsc-segmented>
    </mbsc-segmented-group>
    <div id="demo-event-date"></div>
  </mbsc-popup>
  <mbsc-eventcalendar [data]="myEvents" [view]="myView" [selectedDate]="mySelectedDate"></mbsc-eventcalendar>
</mbsc-page>
```

## Implementation notes

- `Popup` renders arbitrary content as children; the demo places `mbsc-form-group` blocks containing an `Input` (Title), an `Input`/`Textarea` (Description), a `Switch` (All-day), two more `Input`s (Starts/Ends) used as `startInput`/`endInput` for the date picker, and a `SegmentedGroup` with two segments (Show as busy/free).
- `width: 400`, `contentPadding: false`, `headerText: 'Add new event'`, `display: 'center'`, and `showOverlay: false` configure a fixed-width, centered popup with a header title, no default inner padding (so the form controls its own spacing), and no dimmed backdrop.
- `buttons` combines a plain `'cancel'` string entry with a custom button object - `{ text: 'Add', keyCode: 'enter', handler, cssClass: 'mbsc-popup-button-primary' }` - so pressing Enter or clicking the button runs `handler` (builds the new event from form state, appends it to the events array/data source, closes the popup, and shows a toast) without a separate `set`/`ok` default action.
- The nested `Datepicker` uses `select: 'range'`, `display: 'anchored'`, `touchUi: true`, and `showRangeLabels: false`; its `controls` toggles between `['calendar']` (all-day) and `['calendar', 'time']` (timed) based on the `Switch`'s checked state - in React/Vue this is a derived value recomputed on render/`v-model`; in Angular/JS it's reassigned via `[controls]` binding or `.setOptions({ controls })` in the `Switch`'s change handler.
- The date picker is wired to the two `Input`s via `startInput`/`endInput` (`[startInput]`/`[endInput]` in Angular, `:startInput`/`:endInput` in Vue, refs passed as props in React, element IDs as strings in JS/jQuery) so typing or picking updates those fields instead of rendering its own text field.
- Opening the popup is imperative in JS/jQuery and Angular, declarative in React/Vue: JS captures the popup instance directly from the return value of `mobiscroll.popup(...)`; jQuery instead calls `.mobiscroll('getInst')` on the popup element to get it; either way, the trigger button's click handler then resets all the field instances' values/checked state and calls `.open()`; Angular keeps a `@ViewChild` reference (`popup: MbscPopup`), resets the component's bound fields, and calls `popup.open()`; React and Vue instead bind the popup's `isOpen`/`:isOpen` prop to state that the trigger button's click handler resets and sets to `true`, and reset that state through an `onClose`/`@close` callback (or the custom Add button's `handler`).
- The `Eventcalendar`'s `data`/event array is updated by spreading in the new event object built inside the Add button's `handler`; `selectedDate` is then set to the new event's `start` so the calendar navigates to it (JS/jQuery instead call `calendar.addEvent(newEvent)` and `calendar.navigateToEvent(newEvent)` on the `Eventcalendar` instance).

## 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

- Next: [Using as a tooltip](https://demo.mobiscroll.com/angular/popup/show-hide-tooltip-hover-in-out.md) - Use the Angular popup with custom content on event hover within the various event calendar views.
