Docs
Calendar
Plugins
⭐ Interactive Event Modal

Interactive event modal

A plugin for displaying an interactive modal for adding, editing and removing events.

This is a premium plugin which requires an active license to be used. Learn more at Schedule-X premium.

Features & demo

  • Adding, updating and deleting events
  • Click to create
  • Recurring events
  • Validation

Go to Demo


2. Install the packages

2.1 Set up premium auth (only once)

Follow the instructions for setting up an .npmrc

2.2 Install

npm i @sx-premium/interactive-event-modal

Usage

import { createCalendar } from '@schedule-x/calendar'
import { createEventsServicePlugin } from "@schedule-x/events-service";
import { createInteractiveEventModal } from "@sx-premium/interactive-event-modal";
 
import '@sx-premium/interactive-event-modal/index.css'
 
const eventsService = createEventsServicePlugin()
 
const eventModal = createInteractiveEventModal({
  // dependency needed to add events
  eventsService,
 
  // (Optional): Available people for the event form
  availablePeople: ['John Doe', 'Jane Doe'],
 
  // (Optional): callback for when an event is added
  onAddEvent: (event) => {
    console.log(event)
  },
 
  // (Optional): callback for when an event is updated
  onDeleteEvent: (eventId) => {
    console.log(eventId)
  },
 
  // (Optional): callback for when an event start property is updated
  onStartUpdate(start) {
    console.log(start)
  },
 
  // (Optional): callback for when an event end property is updated
  onEndUpdate(end) {
    console.log(end)
  },
 
  // (Optional): callback which is invoked before opening the modal. Return false to prevent the modal from opening
  canOpenModal: (event) => {
    return event.calendarId === 'calendar-1';
  },
 
  // (Optional): configure the time picker to use 12-hour format
  has12HourTimeFormat: true,
 
  // (Optional): add a gray "move-bar" bar at the top of the modal, which can be used to move the modal
  movable: true,
 
  // (Optional): configure whether the title field should be hidden (is currently shown by default)
  hideTitle: false,
 
  // (Optional): configuration for the field "title"
  fields: {
    title: {
      label: 'Event Title',
      name: 'event-title',
      validator: (value) => {
        return {
          isValid: !!value && value.length >= 3,
          message: 'Title must be at least 3 characters long'
        }
      }
    },
    description: {},
  },
 
  // (Optional): date picker config
  datePicker: {
    min: '2025-01-01',
    max: '2025-12-31',
  }
})
 
const calendar = createCalendar({
  // ...other configuration
  plugins: [
    eventModal,
    eventsService,
  ],
 
  callbacks: {
    onDoubleClickDateTime(dateTime) {
      eventModal.clickToCreate(dateTime, {
        id: 'some-event-id',
      })
    }
  }
})
 
calendar.render(document.getElementById('your-calendar-wrapper'))

Public methods

openEventCreationModal(id: string | number, start?: string, otherEventProperties?: Partial<CalendarEvent>)

Method for programmatically opening the event creation modal. The id parameter is used for setting an id of the event that will be created, if the user chooses to click save.

Parameters

  • id - id of the event that will be created
  • start - start date or datetime of the event that will be created
  • otherEventProperties - additional properties that will be added to the event that will be created

clickToCreate: (start: string, otherEventProperties?: Partial<CalendarEvent>) => void

Method for adding an event and opening the event editing modal. Preferably used with the onDoubleClickDateTime and onDoubleClickDate callbacks, to add events by clicking.

fields configuration option

Please note, that by default, all fields are displayed.

If you, however, configure one of them, the rest will be hidden by default. Date and time pickers are an exception here, since these are required at least when adding an event. For adding a field but without custom configuration, simply add it with an empty object like so:

fields: {
  description: {}
  // other fields
}

Available fields

Field nameType
titleInputFieldWithValidation
descriptionInputFieldWithValidation
startDateInputField
startTimeInputField
endDateInputField
endTimeInputField
peopleInputFieldWithValidation
calendarIdInputFieldWithValidation
resourceIdInputFieldWithValidation
rruleFrequencyInputField
rruleUntilInputField
rruleCustomFrequencyInputField
rruleIntervalInputField
rruleCountInputField
rruleByDayInputField

Using the RRule fields

The rrule fields depend on one another. Therefore, you either need to configure all of them, or none. You can easily configure all of them at once like this, if you don't need any custom configuration of them.

export { rruleFields, createInteractiveEventModal } from '@sx-premium/interactive-event-modal'
 
const modal = createInteractiveEventModal({
  fields: {
    // your other fields
    ...rruleFields()
  }
})
 

Input field types

type InputField<T extends undefined | string | string[]> = {
  label?: string
  name?: string
  onChange?: (value: T) => void
  placeholder?: string
}
 
type InputFieldWithValidation<T extends undefined | string | string[]> =
  InputField<T> & {
    validator?: (fieldValue: T) => ValidationResult
  }
 
type CustomInputField<T extends undefined | string | string[]> =
  InputFieldWithValidation<T> & {
    type: 'text' | 'select' | 'textarea' | 'combobox'
    items?: SelectItem[]
  }
 
type ValidationResult = {
  isValid: boolean
  message?: string
}
 
export type SelectItem = { label: string; value: string }

Custom fields

Additional to the default fields, you can add custom fields to a customFields property. The fields of this property follow the same structure as the default fields, but additionally you need to add one of the supported types: text, textarea, select or combobox. For example:

import { createEventsServicePlugin } from "@schedule-x/events-service";
import { createInteractiveEventModal, createInputField, translations as modalTranslations } from "@sx-premium/interactive-event-modal";
import { translations, mergeLocales } from '@schedule-x/translations'
import { createCalendar } from '@schedule-x/calendar'
 
import '@schedule-x/theme-default/dist/calendar.css'
import '@sx-premium/interactive-event-modal/index.css'
 
const eventsService = createEventsServicePlugin()
 
const eventModal = createInteractiveEventModal({
  eventsService,
 
  fields: {
    title: {},
  },
 
  customFields: {
    additionalNotes: createInputField({ // will correspond to an event property "additionalNotes"
      label: 'Additional notes',
      name: 'additional-notes',
      type: 'textarea',
      validator: (value) => {
        return {
          isValid: !!value && value.length >= 3,
          message: 'Custom field must be at least 3 characters long'
        }
      }
    }),
 
    locationSelect: createInputField({ // will correspond to an event property "locationSelect"
      label: 'Location',
      type: 'select',
      items: [
        { label: 'Lake view office', value: 'lake-view' },
        { label: 'City center office', value: 'city-center' },
        { label: 'Home office', value: 'home' },
      ]
    }),
  }
})
 
const calendar = createCalendar({
  translations: mergeLocales(translations, modalTranslations),
  plugins: [
    eventModal,
    eventsService,
  ],
  // ...other configuration
})

If you need to display these custom fields in the view mode of the modal, you can write a custom component for interactiveModalAdditionalFields, which then receives calendarEvent as a prop. View the docs for your framework (Vue, React etc.) to learn how custom components work in Schedule-X.

Changelog

See changelog page.

Examples

These can be added on request. Please let us know if you need an example for a specific framework.

Last updated on

We use cookies for marketing purposes. By clicking "Accept", you consent to the use of all cookies. If you decline, we will only use functional cookies. You can read more about our cookie policy here.