# Appointments in React Scheduler

Appointments represent scheduled items for a specific time period within the Scheduler. Appointments can be created for various time ranges, with each appointment categorized according to its duration and recurrence. The Scheduler categorizes events as follows:

* Normal events
* Spanned events
* All-day events
* Recurring events

To see how to add appointments to the React Scheduler and utilize its advanced event-handling features, watch this overview video:

{% youtube "https://www.youtube.com/watch?v=lk-P4YV8xaw" %}

## Normal events

Represents an appointment that is created for any specific time interval within a day.

### Creating a normal event

The following example demonstrates defining a normal event in the Scheduler using event data loaded from JSON.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}
        


## Spanned events

Spanned events are appointments created for durations longer than 24 hours and are typically displayed in the all-day row. Another category includes events that span more than one day but less than 24 hours, which are displayed across the relevant days.

> For example, an appointment scheduled from May 25, 2026, 11:00 PM to May 26, 2026, 2:00 AM—spanning less than 24 hours—will be split and displayed on both days.

## All-day events

Represents an appointment that is created for an entire day such as holiday events. It is usually displayed separately in an all-day row, a separate row for all-day appointments below the date header section. In Timeline views, the all-day appointments displays in the working space area, and no separate all-day row is present in that view.

> To set a normal appointment as an all-day event, set the [`isAllDay`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#isallday) field to true.

### Hide all-day row events

Use CSS customization to hide all-day row appointments in the Scheduler UI.

```css
.e-schedule .e-all-day-row {
    display: none;
}
```

Alternatively, if you want to hide the entire all-day header:

```css
.e-schedule .e-date-header-wrap .e-schedule-table thead {
    display: none;
}
```

## Expanding all-day appointments view on load

To display all all-day appointments in expanded view when the Scheduler loads, use the [`dataBound`](https://ej2.syncfusion.com/react/documentation/api/schedule#databound) event. This eliminates the need to manually expand all-day events.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



## Customize the rendering of spanned events

By default, the Scheduler renders spanned events (appointments with a duration greater than 24 hours) in the all-day row using the `AllDayRow` placement.
You can customize this behavior by setting the [spannedEventPlacement](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings#spannedeventplacement) property within the [eventSettings](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings) configuration.
When spannedEventPlacement is set to TimeSlot, spanned events are displayed within the regular work cells instead of the all-day row.
The following example demonstrates how to render spanned events inside the work cells.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



## Recurring events

Recurring events are appointments scheduled to repeat at regular intervals (daily, weekly, monthly, or yearly) based on a recurrence rule. These events are marked with a repeat indicator at the lower-right corner.

### Creating a recurring event

The following example illustrates creating a recurring event using a specific recurrence rule. In this case, the event repeats daily and ends after five occurrences.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Adding exceptions

To exclude specific instances from a recurrence series, add exception dates to the [`recurrenceException`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#recurrenceexception) field in UTC format.

**Date-Time Format:** `YYYYMMDDTHHmmssZ`

**Format Rules:**
- Date portion: No hyphens (e.g., February 22, 2026 = `20260222`)
- Time portion: UTC format with "Z" suffix (e.g., 07:30:00 UTC = `073000Z`)
- Complete example: `20260222T073000Z`
- Multiple exceptions: Comma-separated (e.g., `20260222T073000Z,20260223T100000Z`)

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Editing an occurrence from a series

To dynamically edit a particular occurrence from an event series and display it on the initial load of Scheduler, the edited occurrence needs to be added as a new event to the dataSource collection, with an additional [`recurrenceID`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#recurrenceid) field defined to it. The [`recurrenceID`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#recurrenceid) field of edited occurrence usually maps the ID value of the parent event.

In this example, a recurring instance that displays on the date 18th May 2026 is edited with different timings. Therefore, this particular date is excluded from the parent recurring event that repeats from 18th May 2026 to 25th May 2026. This can be done by adding the [`recurrenceException`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#recurrenceexception) field with the excluded date value on the parent event. Also, the edited occurrence event which is created as a new event should carry the . The [`recurrenceID`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#recurrenceid) field pointing to the parent event's [`Id`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#id) value.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Edit only the current and following events

To edit only the current and following events enable the property [editFollowingEvents](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings#editfollowingevents) within the [eventSettings](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings) property. 
When modifying a recurring series in this way, the edited occurrence must be added as a new event in the dataSource. This new event should include an additional [followingID](https://ej2.syncfusion.com/react/documentation/api/schedule/field#followingid) field. The `followingID` value typically references the Id of the immediate parent event.

In this example, a recurring instance that occurs on 30th January 2018, along with all its subsequent occurrences, is updated with a different subject. As a result, this date and all following dates are excluded from the original recurring series, which spans from 28th January 2018 to 4th February 2018.
To achieve this:

* The parent event’s [`recurrenceRule`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#recurrencerule) is modified by setting an appropriate UNTIL value so that the series ends just before the edited occurrence.
* The modified occurrence and its subsequent events are created as a new event series.
* This new series includes the followingID field, which links it to the immediate parent event’s Id.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Recurrence options and rules

Events can be repeated on a daily, weekly, monthly or yearly basis based on the recurrence rule which accepts the string value. The following details should be assigned to the [`recurrenceRule`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#recurrencerule) property to generate the recurring instances.

* Repeat type - daily/weekly/monthly/yearly.
* How many times it needs to be repeated?
* The interval duration.
* The time period to render the appointment, etc.

There are four repeat types:

* **Daily** - Creates the recurring instances on daily basis.
* **Weekly** - Creates the recurring instances on weekly basis for the selected days.
* **Monthly** - Creates the recurring instances on monthly basis for the selected months and other provided recurrence criteria.
* **Yearly** - Creates the recurring instances on yearly basis.

### Recurrence properties

The following table summarizes the properties for creating recurring appointments.

 > Refer [`iCalendar`](https://tools.ietf.org/html/rfc5545#section-3.3.10) specifications for valid recurrence rule string.

| Property | Purpose | Example |
|-------|---------|---------|
| FREQ | Maintains the repeat type (Daily, Weekly, Monthly, Yearly) value of the appointment. | FREQ=DAILY;INTERVAL=1|
| INTERVAL | Maintains the interval value of the appointments. When you create the daily appointment at an interval of 2, the appointments are rendered on the days Monday, Wednesday and Friday (Creates an appointment on all days by leaving the interval of one day gap). | FREQ=DAILY;INTERVAL=2|
| COUNT | It holds the appointment’s count value. When the COUNT value is 10, then 10 instances of appointments are created in the recurrence series. | FREQ=DAILY;INTERVAL=1;COUNT=10|
| UNTIL | This property holds the end date value (in ISO format) denoting when the recurrence actually ends. | FREQ=DAILY;INTERVAL=1;UNTIL=20260530T041343Z;|
| BYDAY | It holds the day value(s), representing on which the appointments actually renders. Create the weekly appointment, and select the day(s) from the day options (Monday/Tuesday/Wednesday/Thursday/Friday/Saturday/Sunday). When Monday is selected, the first two letters of the selected day "MO" is saved in the BYDAY property. When multiple days are selected, the values are separated by commas. | FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE;COUNT=10|
| BYMONTHDAY | This property is used to store the date value of the Month, while creating the Month recurrence appointment. When you create a Monthly recurrence appointment for every 3rd day of the month, then BYMONTHDAY holds the value 3 and creates the appointment on 3rd day of every month. | FREQ=MONTHLY;BYMONTHDAY=3;INTERVAL=1;COUNT=10|
| BYMONTH | This property is used to store the index value of the selected Month while creating the yearly appointments. When you create the yearly appointment on June month, the index value of June month 6 will get stored in the BYMONTH field. The appointment is created on every 6th month of a year. | FREQ=YEARLY;BYMONTHDAY=16;BYMONTH=6;INTERVAL=1;COUNT=10|
| BYSETPOS | This property is used to store the index value of the week. When you create the monthly appointment in second week of a month, the index value of the second week (2) is stored in BYSETPOS. | FREQ=MONTHLY;BYDAY=MO;BYSETPOS=2;COUNT=10|

> The default recurrence related validation has been included for recurrence appointments similar to the one available in Outlook. The validation usually occurs during the recurrence appointment creation, editing, drag and drop or resizing of the recurrence appointments and also if any single occurrence changes.

### Daily Frequency

| Description | Example |
|-------------|---------|
| Daily recurring event that never ends | FREQ=DAILY; INTERVAL=1 |
| Daily recurring event that ends after 5 occurrences | FREQ=DAILY; INTERVAL=1; COUNT=5 |
| Daily recurring event that ends exactly on 12/05/2026 | FREQ=DAILY; INTERVAL=1; UNTIL=20260512T041343Z |
| Daily event that recurs on alternative days and repeats for 10 occurrences | FREQ=DAILY; INTERVAL=2; COUNT=10 |
| Daily recurring appointment ends on 12/05/2026 by excluding single occurrence on 12/10/2018 | FREQ=DAILY; INTERVAL=2; UNTIL=20260512T041343Z; |

### Weekly Frequency

| Description | Example |
|-------------|---------|
| Weekly recurring event that repeats on every Monday, Wednesday and Friday and never ends | FREQ=WEEKLY; INTERVAL=1; BYDAY=MO,WE,FR |
| Repeats every week Thursday and ends after 10 occurrences | FREQ=WEEKLY; INTERVAL=1; BYDAY=TH; COUNT=10 |
| Repeats every week Monday and ends on 12/05/2026 | FREQ=WEEKLY; INTERVAL=1; BYDAY=MO; UNTIL=20260512T041343Z |
| Repeats on Monday, Wednesday and Friday of alternative weeks and ends after 10 occurrences | FREQ=WEEKLY; INTERVAL=2; BYDAY=MO, WE, FR; COUNT=10 |
| Repeats every week on weekdays and ends after 12/05/2026 by excluding single occurrence on 12/10/2018 | FREQ=WEEKLY; BYDAY=MO, TU, WE, TH, FR; UNTIL=20260512T041343Z; |

### Monthly Frequency

| Description | Example |
|-------------|---------|
| Monthly recurring event that repeats on every 15th day of a month and never ends | FREQ=MONTHLY; BYMONTHDAY=15; INTERVAL=1 |
| Monthly recurring event that repeats on every 16th day of a month and ends after 10 occurrences | FREQ=MONTHLY; BYMONTHDAY=16; INTERVAL=1; COUNT=10 |
| Repeats every 17th day of a month and ends on 12/05/2026 | FREQ=MONTHLY; BYMONTHDAY=17; INTERVAL=1; UNTIL=20260512T041343Z |
| Repeats every 2nd Friday of a month and never ends | FREQ=MONTHLY; BYDAY=FR; BYSETPOS=2; INTERVAL=1 |
| Repeats every 4th Wednesday of a month and ends after 10 occurrences | FREQ=MONTHLY; BYDAY=WE; BYSETPOS=4; INTERVAL=1; COUNT=10 |
| Repeats every 4th Friday of a month and ends on 12/05/2026 | FREQ=MONTHLY; BYDAY=FR; BYSETPOS=4; INTERVAL=1; UNTIL=20260512T041343Z |

### Yearly Frequency

| Description | Example |
|-------------|---------|
| Yearly event that repeats on every 15th day of December month and never ends | FREQ=YEARLY; BYMONTHDAY=15; BYMONTH=12; INTERVAL=1 |
| Event that repeats on every 10th day of December month and ends after 10 occurrences | FREQ=YEARLY; BYMONTHDAY=10; BYMONTH=12; INTERVAL=1; COUNT=10 |
| Repeats on every 12th day of December month and ends on 12/05/2026 | FREQ=YEARLY; BYMONTHDAY=12; BYMONTH=12; INTERVAL=1; UNTIL=20260512T041343Z |
| Repeats on every 3rd Friday of December month and never ends | FREQ=YEARLY; BYDAY=FR; BYMONTH=12; BYSETPOS=3; INTERVAL=1 |
| Repeats on every 3rd Tuesday of December month and ends after 10 occurrences | FREQ=YEARLY; BYDAY=TU; BYMONTH=12; BYSETPOS=3; INTERVAL=1; COUNT=10 |
| Repeats on every 4th Wednesday of December month and ends on 12/05/2026 | FREQ=YEARLY; BYDAY=WE; BYMONTH=12; BYSETPOS=4; INTERVAL=1; UNTIL=20260512T041343Z |

### Recurrence Validation

The built-in validation support has been added by default for recurring appointments during its creation, edit, drag and drop or resize action. The following are the possible validation alerts that displays on Scheduler while creating or editing the recurring events.

| Validation messages | Description |
|-------|---------|
| The recurrence pattern is not valid. | This alert will raise, when the selected recurrence rule value is not a valid one. For example, when you try to select the end date value (using `Until` option) for a recurring event, which occurs before the start date, an alert will popup out saying that the chosen pattern is invalid. |
| The changes made to specific instances of this series will be cancelled and those events will match the series again. | This alert will raise, when you try to edit the whole series, whose occurrence might have been already edited. For example, If there are five occurrences and one of the occurrence is already edited. Now, when you try to edit the entire series, you will get this validation alert. |
| The duration of the event must be shorter than how frequently it occurs. Shorten the duration, or change the recurrence pattern in the recurrence event editor. | This validation occurs when event duration exceeds the recurrence interval. For example, a 2-day event with daily (1-day) recurrence would trigger this. **Solution:** Make the event duration shorter than the recurrence interval, or increase the recurrence interval (e.g., every 3 days). |
| Some months have fewer than the selected date. For these months, the occurrence will fall on the last date of the month. | When you try to create a recurring appointment on 31st of every month, where few months won’t have 31 days and in this scenario, you will get this alert. |
| Two occurrences of the same event cannot occur on the same day. | This validation will occur, when you try to edit or move any single occurrence to some other date, where another occurrence of the same event is already present. |

## Event fields

The Scheduler's dataSource usually holds the event instances, where each of the instance includes a collection of appropriate [`fields`](https://ej2.syncfusion.com/react/documentation/api/schedule/field). It is mandatory to map these fields with the equivalent fields of database, when remote data is bound to it. When the local JSON data is bound, then the field names defined within the instances needs to be mapped with the Scheduler event fields correctly.

> To create an event, both [`startTime`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#starttime) and [`endTime`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#endtime) are required. The [`id`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#id) field is mandatory for all CRUD actions.

### Built-in fields

The built-in fields available on Scheduler event object are as follows.

| Field name | Required | Description |
|-------|---------|---------|
| id | Yes | The [`id`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#id) field assigns a unique ID to each event. Required for all CRUD operations.|
| subject | No | The [`subject`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#subject) field assigns the summary text to each event. Optional but recommended.|
| startTime | Yes | The [`startTime`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#starttime) field defines when an event begins. Required for all valid event objects.|
| endTime | Yes | The [`endTime`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#endtime) field defines when an event ends. Required for all valid event objects.|
| startTimezone | No | The [`startTimezone`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#starttimezone) field accepts valid IANA timezone names and overrides the Scheduler's timezone for the event's start time. Example: "America/New_York". If not provided, the Scheduler's timezone is used.|
| endTimezone | No | The [`endTimezone`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#endtimezone) field accepts valid IANA timezone names and overrides the Scheduler's timezone for the event's end time. Example: "Europe/London". If not provided, the Scheduler's timezone is used.|
| location | No | The [`location`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#location) field stores the event location and is displayed on the appointment.|
| description | No | The [`description`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#description) field stores event details and is optional.|
| isAllDay | No | The [`isAllDay`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#isallday) field (boolean) marks an event as an all-day appointment. Set to `true` for full-day events (e.g., holidays).|
| recurrenceID | No | The [`recurrenceID`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#recurrenceid) field links an edited event occurrence to its parent recurring event. Only used for modified instances in a series.|
| recurrenceRule | No | The [`recurrenceRule`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#recurrencerule) field holds an iCalendar-formatted string (e.g., "FREQ=DAILY;INTERVAL=1;COUNT=5") that defines recurrence pattern.|
| recurrenceException | No | The [`recurrenceException`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#recurrenceexception) field stores exception dates (in UTC format without hyphens, e.g., "20260222") to exclude from a recurring series.|
| isReadonly | No | The [`isReadonly`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#isreadonly) field (boolean) prevents editing of an appointment when set to `true`.|
| isBlock | No | The [`isBlock`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#isblock) field (boolean) blocks time slots and prevents new events from being created in those time ranges. Often used for unavailable/busy times.|  

### Binding different field names

When the fields of event instances has the default mapping name, it is not mandatory to map them manually. If a Scheduler's dataSource holds the events collection with different field names, then it is necessary to map them with its equivalent field name within the [`eventSettings`](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings) property.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



> The [id](https://ej2.syncfusion.com/react/documentation/api/schedule/field#id) mapping is a string type with no extra validation, while other fields have object type and additional options.

### Event field settings

Each field of the Scheduler events are provided with additional settings such as options to set default value, to map with appropriate data source fields, to validate every event fields and to provide label values for those fields in the event window.

| Options | Description |
| ------- | ----------- |
| default | Accepts the default value to the applicable fields (Subject, Location and Description), when no values are provided to them from dataSource. |
| name | Accepts the field name to be mapped from the dataSource fields. |
| title | Accepts the label values to be displayed for the fields of event editor. |
| validation | Defines the validation rules to be applied on the event fields within the event editor. |

In following example, the Subject field in event editor will display its appropriate label as **Summary**. When no subject value is provided while saving an event, then the appointment will be saved with the default subject value as **Add Summary**.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



## Adding Custom fields

In addition to default fields, you can add any number of custom fields to Scheduler appointments. For example, the code below adds **Status** and **Priority**. Custom fields don't need to be mapped in [`eventSettings`](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings).

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Accessing custom fields

Custom fields can be accessed in various event handlers and templates:

**In event handlers:**
```typescript
scheduleRef.current.eventSettings.onActionBegin = (args: ActionEventArgs) => {
  if (args.data) {
    const customFieldValue = args.data.Status; // Access custom field
    console.log('Status:', customFieldValue);
  }
};
```

**In templates (event templates, tooltips):**
```typescript
// Custom fields are available in the event object passed to template functions
const eventTemplate = (props: any) => (
  <div>
    <span>{props.Subject}</span>
    <span>{props.Status}</span> {/* Custom field */}
  </div>
);
```

**In resource grouping and custom rendering:**
Custom fields are available on all event objects obtained from the dataSource and can be used for sorting, filtering, or custom UI rendering.

## Customize the order of the overlapping events

By default, the Scheduler renders overlapping events based on their start and end times. You can customize the rendering order by using the [sortComparer](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings#sortcomparer) property in [eventSettings](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings).

**sortComparer Function Signature:**
```typescript
sortComparer(event1: any, event2: any): number
```
Returns: 
- Negative number if event1 should be rendered before event2
- Positive number if event1 should be rendered after event2
- 0 if they have equal priority

The following code example shows how to sort appointments based on a custom field (e.g., Priority):

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



## Preventing Overlapping Events

By default, the Scheduler displays overlapping events according to their start and end times. To prevent overlapping, set the [`allowOverlap`](https://ej2.syncfusion.com/react/documentation/api/schedule#allowoverlap) property to `false`.

When `allowOverlap` is `false`:
- New or updated events that conflict with existing ones trigger an overlap alert
- Overlapping events are accessible via [`overlapEvents`](https://ej2.syncfusion.com/react/documentation/api/schedule/popupOpenEventArgs#overlapevents) in [`PopupOpenEventArgs`](https://ej2.syncfusion.com/react/documentation/api/schedule/popupOpenEventArgs)
- The Scheduler uses specific logic to handle conflicts (see behavior below)

### Scheduler behavior with allowOverlap set to false

**Initial Load Behavior:**  Upon initial loading, the Scheduler prioritizes non-overlapping events based on their duration and all-day status. Events with longer durations and those marked as all-day receive higher priority to ensure there are no overlaps.

**Recurring Appointments:**  If there are conflicts within a recurring appointment series during the initial load, the Scheduler will display all occurrences of the series, except for the conflicting instance.

**Event Modifications:**  When a user edits, saves, or removes appointments, the Scheduler checks for potential overlaps. If a conflict is detected, the action is blocked, and a conflict alert is displayed to the user to address the issue.

**Dynamic Recurrence Series Creation or Editing:**  When a user creates or edits a recurrence series dynamically, the Scheduler will prevent any occurrences of the series from being added if a conflict is found within the series.

The following code example demonstrates how to enable the [`allowOverlap`](https://ej2.syncfusion.com/react/documentation/api/schedule#allowoverlap) property.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Limitations

The [`allowOverlap`](https://ej2.syncfusion.com/react/documentation/api/schedule#allowoverlap) property has the following limitation:

**Visible date range limitation:** By default, overlap checks only apply to events within the currently visible date range. Events outside the rendered date range are not checked for conflicts.

**Workaround - Check overlaps across all events:**

To validate overlaps across the entire dataset (not just visible range), implement custom validation using the [`actionBegin`](https://ej2.syncfusion.com/react/documentation/api/schedule#actionbegin) event:

1. Access all events in the dataSource
2. Implement overlap logic in the [`actionBegin`](https://ej2.syncfusion.com/react/documentation/api/schedule#actionbegin) event
3. Assign the validation result (boolean) to the [`promise`](https://ej2.syncfusion.com/react/documentation/api/schedule/actionEventArgs#promise) field
   - `true` = proceed with action
   - `false` = block the action
4. Optionally use [`openOverlapAlert`](https://ej2.syncfusion.com/react/documentation/api/schedule#openoverlapalert) to display alert popup

The following code example demonstrates how to check for overlaps when an event is added. If an overlap is found, the event won't be added, and an alert will be shown.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



## Drag and drop appointments

Reschedule appointments by dragging and dropping them. To enable drag and drop:

1. **Inject the `DragAndDrop` module** in your Scheduler component:
   ```typescript
   import { Inject, DragAndDrop } from '@syncfusion/ej2-react-schedule';
   // In component: <Inject services={[DragAndDrop, ...otherServices]} />
   ```

2. **Set the property** [`allowDragAndDrop`](https://ej2.syncfusion.com/react/documentation/api/schedule#allowdraganddrop) to `true`

On mobile devices, tap and hold an event, then drag it to the desired location.

Learn more about dragging external items and advanced drag/resize options in this video:

{% youtube "https://www.youtube.com/watch?v=lk-P4YV8xaw" %}

> **Drag and drop support by view:**
> - **Supported:** Day, Week, Work Week, Timeline Day, Timeline Week, Timeline Month, Month
> - **Not supported:** Agenda, Month-Agenda, Year View

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Drag and drop multiple appointments

To drag and drop multiple appointments:

1. **Enable multiple drag:** Set [`allowMultiDrag`](https://ej2.syncfusion.com/react/documentation/api/schedule#allowmultidrag) to `true`
2. **Select events:** Hold **Ctrl** (Windows/Linux) or **Cmd** (Mac) and click events to select multiple
3. **Drag:** Release Ctrl/Cmd and drag the selected events to a new location

**Multi-resource drag:** When dragging multiple events from different resources to a single resource, all events move to the target resource.

> **Limitation:** Multiple event drag is not supported on mobile devices.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Disable the drag action

By default, you can drag and drop the events within any of the applicable Scheduler views, and to disable it, set `false` to the [`allowDragAndDrop`](https://ej2.syncfusion.com/react/documentation/api/schedule#allowdraganddrop) property.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Preventing drag and drop on specific targets

Use the [`excludeSelectors`](https://ej2.syncfusion.com/react/documentation/api/schedule/dragEventArgs#excludeselectors) property within the [`dragStart`](https://ej2.syncfusion.com/react/documentation/api/schedule#dragstart) event to prevent dragging on specific targets, such as the all-day row.

In this example, we have prevented the drag action on all-day row.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Disable scrolling on drag action

By default, while dragging an appointment to the edges, either top or bottom of the Scheduler, scrolling action takes place automatically. To prevent this scrolling, set `false` to the [`scroll`](https://ej2.syncfusion.com/react/documentation/api/schedule/dragEventArgs#scroll) value within the [`dragStart`](https://ej2.syncfusion.com/react/documentation/api/schedule#dragstart) event arguments.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Controlling scroll speed while dragging an event

The speed of the scrolling action while dragging an appointment to the Scheduler edges, can be controlled within the [`dragStart`](https://ej2.syncfusion.com/react/documentation/api/schedule#dragstart) event by setting the desired value to the [`scrollBy`](https://ej2.syncfusion.com/react/documentation/api/schedule/scrollOptions#scrollby) and [`timeDelay`](https://ej2.syncfusion.com/react/documentation/api/schedule/scrollOptions#timedelay) option whereas its default value is 30 minutes and 100ms.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Auto navigation of date ranges on dragging an event

When an event is dragged either to the left or right extreme edges of the Scheduler and kept hold for few seconds without dropping, the auto navigation of date ranges will be enabled allowing the Scheduler to navigate from current date range to back and forth respectively. This action is set to `false` by default and to enable it, you need to set [`navigation`](https://ej2.syncfusion.com/react/documentation/api/schedule/dragEventArgs#navigation) to true within the [`dragStart`](https://ej2.syncfusion.com/react/documentation/api/schedule#dragstart) event.

By default, the navigation delay is set to 2000ms. The navigation delay decides how long the user needs to drag and hold the appointments at the extremities. You can also set your own delay value for letting the users to navigate based on it, using the [`timeDelay`](https://ej2.syncfusion.com/react/documentation/api/schedule/scrollOptions#timedelay) within the [`dragStart`](https://ej2.syncfusion.com/react/documentation/api/schedule#dragstart) event.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Setting drag time interval

By default, while dragging an appointment, it moves at an interval of 30 minutes. To change the dragging time interval, pass the appropriate values to the [`interval`](https://ej2.syncfusion.com/react/documentation/api/schedule/dragEventArgs#interval) option within the [`dragStart`](https://ej2.syncfusion.com/react/documentation/api/schedule#dragstart) event.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Drag and drop items from an external source

It is possible to drag and drop the unplanned items from any of the external source into the Scheduler, by manually saving those dropped item as a new appointment data through [`addEvent`](https://ej2.syncfusion.com/react/documentation/api/schedule#addevent) method of Scheduler.

In this example, we have used the tree view control as an external source and the child nodes from the tree view component are dragged and dropped onto the Scheduler. Therefore, it is necessary to make use of the [`nodeDragStop`](https://ej2.syncfusion.com/react/documentation/api/treeview#nodedragstop) event of the TreeView component, where we can form an event object and save it using the [`addEvent`](https://ej2.syncfusion.com/react/documentation/api/schedule#addevent) method.

Learn how to drag an external item into the React Scheduler by watching this video:

{% youtube "https://www.youtube.com/watch?v=lk-P4YV8xaw" %}

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Opening the editor window on drag stop

There are scenarios where you want to open the editor filled with data on newly dropped location and may need to proceed to save it, only when `Save` button is clicked on the editor. On clicking the cancel button should revert these changes. This can be achieved using the [`dragStop`](https://ej2.syncfusion.com/react/documentation/api/schedule#dragstop) event of Scheduler.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



## Inline Appointment

In Scheduler, another easier way for `adding` or `editing` the appointment’s subject alone can be achieved by using the inline Add/Edit support. It allows the user to add and edit the appointments inline. To get familiar with the inline Add mode, single click on any of the Scheduler cells or press enter key on the selected cells.

When the inline adding mode is ON, a text box will get created within the clicked Scheduler cells with a blinking cursor in it, requiring the user to enter the subject of an appointment. Once the subject is entered, the appointment will be saved on pressing the enter key.

To enable the inline edit mode, single click on any of the existing appointment’s subject, so that the user can edit the subject of that appointment. The edited subject of that appointment will be updated on pressing the enter key.

The inline option can be enabled/disabled on the Scheduler by using the allowInline API, whereas its default value is set to false.

While using the [`allowInline`](https://ej2.syncfusion.com/react/documentation/api/schedule#allowinline) the [`showQuickInfo`](https://ej2.syncfusion.com/react/documentation/api/schedule#showquickinfo)  will be turned off. The `quickPopup` will not show on clicking the work cell or clicking the appointment when the `allowInline` property is set to `true`.
In work cells, select multiple cells using keyboard, and then press enter key. The appointment wrapper will be created, and focus will be on the subject field. Also, consider the overlapping scenarios when creating an inline event.

### Normal Event

While editing appointments, single-click the appointment subject, the `editable` option will be enabled in UI and the cursor will focus at the end of the text. Inline editing will be considered for all possible views.

### Recurrence Event

While editing the occurrence from the recurrence series, it is only possible to edit a `single occurrence`, not an entire series.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



## Appointment Resizing

Another way to reschedule an appointment can be done by resizing it through either of its handlers. To work with resizing functionality, it is necessary to inject the module `Resize` and make sure that [`allowResizing`](https://ej2.syncfusion.com/react/documentation/api/schedule#allowresizing) property is set to true.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Disabling resize action

Resize is enabled by default except in Agenda and Month-Agenda views. To disable, set [`allowResizing`](https://ej2.syncfusion.com/react/documentation/api/schedule#allowresizing) to `false`.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Disabling scrolling on resize action

By default, while resizing an appointment, when its handler reaches the extreme edges of the Scheduler, scrolling action will take place along with event resizing. To prevent this scrolling action, set `false` to [scroll](https://ej2.syncfusion.com/react/documentation/api/schedule/resizeEventArgs#scroll) value within the [`resizeStart`](https://ej2.syncfusion.com/react/documentation/api/schedule#resizestart) event.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Controlling scroll speed while resizing an event

The speed of the scrolling action while resizing an appointment to the Scheduler edges, can be controlled within the [`resizeStart`](https://ej2.syncfusion.com/react/documentation/api/schedule#resizestart) event by setting the desired value to the `scrollBy` option.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Setting resize time interval

By default, while resizing an appointment, it extends or shrinks at an interval of 30 minutes. To change this default resize interval, set appropriate values to [`interval`](https://ej2.syncfusion.com/react/documentation/api/schedule/resizeEventArgs#interval) option within the [`resizeStart`](https://ej2.syncfusion.com/react/documentation/api/schedule#resizestart) event.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



## Appointment customization

The look and feel of the Scheduler events can be customized using any one of the following ways.
* [Using event templates](#using-template)
* [Using the eventRendered event](#using-eventrendered-event)
* [Using custom CSS class](#using-cssclass)

### Using template

Any kind of text, images and links can be added to customize the look of the events. The user can format and change the default appearance of the events by making use of the [`template`](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings#template) option available within the [`eventSettings`](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings) property. The following code example customizes the appointment's default color and time format.

Learn how easily you can customize the basic look and feel of React Scheduler appointments using template from this video:

{% youtube "https://www.youtube.com/watch?v=lk-P4YV8xaw" %}

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



> All the built-in fields that are mapped to the appropriate field properties within the [`eventSettings`](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings), as well as custom mapped fields from the Scheduler dataSource can be accessed within the template code.

### Using eventRendered event

The  [`eventRendered`](https://ej2.syncfusion.com/react/documentation/api/schedule#eventrendered) event triggers before the appointment renders on the Scheduler. Therefore, this client-side event can be utilized to customize the look of events based on any specific criteria, before rendering them on the Scheduler.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Using cssClass

The customization of events can also be achieved using [`cssClass`](https://ej2.syncfusion.com/react/documentation/api/schedule#cssclass) property of the Scheduler. In the following example, the background of appointments has been changed using the cssClass.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



## Setting minimum height

It is possible to set minimal height for appointments on Scheduler using [`eventRendered`](https://ej2.syncfusion.com/react/documentation/api/schedule#eventrendered) event, when its start and end time duration is less than the default duration of a single slot.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



## Block Dates and Times

It is possible to block a set of dates or a particular time range on the Scheduler. To do so, define an appointment object within [`eventSettings`](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings) along with the required time range to block and set the  [`isBlock`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#isblock)  field to true. Usually, the event objects defined with isBlock field set to true will block the entire time cells lying within the appropriate time ranges specified through [`startTime`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#starttime) and [`endTime`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#endtime) fields.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



Block events can also be defined to repeat on several days as shown in the following code example.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



## Readonly

An interaction with the appointments of Scheduler can be enabled/disabled using the [`readonly`](https://ej2.syncfusion.com/react/documentation/api/schedule#readonly) property. With this property enabled, you can simply navigate between the Scheduler dates, views and can be able to view the appointment details in the quick info window. Most importantly, the users are not allowed to perform any CRUD actions on Scheduler, when this property is set to true. By default, it is set as `false`.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



## Make specific events readonly

There are scenarios where you need to restrict the CRUD action on specific appointments alone based on certain conditions. In the following example, the events that has occurred on the past hours from the current date of the Scheduler are made as read-only and the CRUD actions has been prevented only on those appointments. This can be achieved by setting [`isReadonly`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#isreadonly) field of read-only events to `true`.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



> By default, the event editor is prevented to open on the read-only events when [`isReadonly`](https://ej2.syncfusion.com/react/documentation/api/schedule/field#isreadonly) field is set to `true`.

## Restricting event creation on specific time slots

You can restrict the users to create and update more than one appointment on specific time slots. Also, you can disable the CRUD action on those time slots if it is already occupied, which can be achieved using Scheduler's public method [`isSlotAvailable`](https://ej2.syncfusion.com/react/documentation/api/schedule#isslotavailable).

>Note: The **isSlotAvailable** is centered around verifying appointments within the present view's date range. Yet, it does not encompass an evaluation of availability for recurrence occurrences that fall beyond this particular date range.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



## Differentiate the past time events

To differentiate the appearance of the appointments based on specific criteria such as displaying the past hour appointments with different colors on Scheduler,  [`eventRendered`](https://ej2.syncfusion.com/react/documentation/api/schedule#eventrendered) event can be used which triggers before the appointment renders on the Scheduler.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



## Appointments occupying the entire cell

The Scheduler allows the event to occupy the full height of the cell without its header part by setting `true` for [`enableMaxHeight`](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings#enablemaxheight) property.

We can show more indicator if more than one appointment is available in a same cell by setting `true` to [`enableIndicator`](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings#enableindicator)  property whereas its default value is `false`.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



## Limiting maximum number of events displayed

In the Scheduler, you can limit the number of concurrent events displayed in each time slot to improve the quality of the presentation and prevent visual overcrowding. This can be accomplished using the following properties based on the view type:

### Limiting events in month and timeline views

In the Scheduler, the default behavior is to display concurrent events based on cell height, with each new event represented as 
`+n more` characters. However, you may want to improve the quality of the presentation by limiting the number of concurrent events. This can be accomplished by using the [`maxEventsPerRow`](https://ej2.syncfusion.com/react/documentation/api/schedule/views#maxeventsperrow) property, which is defaulted to the [`views`](https://ej2.syncfusion.com/react/documentation/api/schedule/views) property.

The [`maxEventsPerRow`](https://ej2.syncfusion.com/react/documentation/api/schedule/views#maxeventsperrow) property is specific to the month, timeline month, and timeline year views, allowing you to view events visually in these rows. Below is a code example that demonstrates how to use this constraint and the events displayed in a cell have been created:

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



> The property [`maxEventsPerRow`](https://ej2.syncfusion.com/react/documentation/api/schedule/views#maxeventsperrow) will be applicable only when [`rowAutoHeight`](https://ej2.syncfusion.com/react/documentation/api/schedule#rowautoheight) feature is disabled in the Scheduler.

### Limiting events in vertical views

The `maxEventStack` property on the [views](https://ej2.syncfusion.com/react/documentation/api/schedule/views) allows you to limit the number of overlapping events displayed in each time slot. This feature prevents visual overcrowding when multiple events overlap in the same time slot. When the number of overlapping events exceeds the specified limit, a `+N` indicator appears, indicating how many additional events exist. Users can click this indicator to view all remaining events in a popup window. By default, the Scheduler shows all overlapping events without any restrictions. The default value of `maxEventStack` is `0`.

Below is a code example that demonstrates how to use this constraint:

{% tabs %}
{% highlight ts tabtitle="App.tsx" %}
import { ScheduleComponent, Day, Week, WorkWeek, Inject, type EventSettingsModel } from '@syncfusion/ej2-react-schedule';

function App () {
  const eventsData = [
    { Id: 1, Subject: "Board Meeting", StartTime: new Date(2026, 5, 15, 9, 30, 0), EndTime: new Date(2026, 5, 15, 11, 0, 0) },
    { Id: 2, Subject: "Annual Conference", StartTime: new Date(2026, 5, 15, 10, 0, 0), EndTime: new Date(2026, 5, 15, 11, 0, 0) },
    { Id: 3, Subject: "Tech Symposium", StartTime: new Date(2026, 5, 15, 10, 30, 0), EndTime: new Date(2026, 5, 15, 11, 30, 0) },
    { Id: 4, Subject: "Client Meeting", StartTime: new Date(2026, 5, 15, 12, 0, 0), EndTime: new Date(2026, 5, 15, 14, 0, 0) },
    { Id: 5, Subject: "Project Review", StartTime: new Date(2026, 5, 15, 13, 0, 0), EndTime: new Date(2026, 5, 15, 15, 0, 0) }
  ];

  const eventSettings: EventSettingsModel = { dataSource: eventsData };

  return (
    <ScheduleComponent height ='550px' eventSettings={eventSettings} selectedDate={new Date(2026, 5, 15)}>
      <ViewsDirective>
		<ViewDirective option='Day' maxEventStack={2} />
		<ViewDirective option='Week' maxEventStack={2} />
		<ViewDirective option='WorkWeek' maxEventStack={2} />
	  </ViewsDirective>
      <Inject services={[Day, Week, WorkWeek]} />
    </ScheduleComponent>
  );
};

export default App;
{% endhighlight %}
{% highlight js tabtitle="App.jsx" %}
import { ScheduleComponent, Day, Week, WorkWeek, Inject } from '@syncfusion/ej2-react-schedule';

function App () {
  const eventsData = [
    { Id: 1, Subject: "Board Meeting", StartTime: new Date(2026, 5, 15, 9, 30, 0), EndTime: new Date(2026, 5, 15, 11, 0, 0) },
    { Id: 2, Subject: "Annual Conference", StartTime: new Date(2026, 5, 15, 10, 0, 0), EndTime: new Date(2026, 5, 15, 11, 0, 0) },
    { Id: 3, Subject: "Tech Symposium", StartTime: new Date(2026, 5, 15, 10, 30, 0), EndTime: new Date(2026, 5, 15, 11, 30, 0) },
    { Id: 4, Subject: "Client Meeting", StartTime: new Date(2026, 5, 15, 12, 0, 0), EndTime: new Date(2026, 5, 15, 14, 0, 0) },
    { Id: 5, Subject: "Project Review", StartTime: new Date(2026, 5, 15, 13, 0, 0), EndTime: new Date(2026, 5, 15, 15, 0, 0) }
  ];

  const eventSettings = { dataSource: eventsData };

  return (
    <ScheduleComponent height ='550px' eventSettings={eventSettings} selectedDate={new Date(2026, 5, 15)}>
      <ViewsDirective>
		<ViewDirective option='Day' maxEventStack={2} />
		<ViewDirective option='Week' maxEventStack={2} />
		<ViewDirective option='WorkWeek' maxEventStack={2} />
	  </ViewsDirective>
      <Inject services={[Day, Week, WorkWeek]} />
    </ScheduleComponent>
  );
};

export default App;
{% endhighlight %}
{% endtabs %}

**How it works:** In this example, `maxEventStack` is set to `2` for all three views. When you have three or more overlapping events in the same time slot:

* The Scheduler displays only the first two events
* A "+N" indicator appears to show how many additional events exist (for example, "+1" if there are 3 total events)
* Users can click the indicator to open a popup displaying all remaining events for that time slot

![Scheduler with MaxEventStack](https://help.syncfusion.com/scheduler-sdk/react/schedule/images/scheduler-max-event-stack.png)

> The `maxEventStack` property is applicable only with **Day**, **Week**, and **WorkWeek** views when the [`timeScale`](https://ej2.syncfusion.com/react/documentation/api/schedule#timescale) option is enabled.

## Display tooltip for appointments

The tooltip shows the Scheduler appointment's information in a formatted style by making use of the tooltip related options.

### Show or hide built-in tooltip

The tooltip can be displayed for appointments by setting `true` to the [`enableTooltip`](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings#enabletooltip) option within the [`eventSettings`](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings) property.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



### Customizing event tooltip using template

After enabling the default tooltip, it is possible to customize the display of needed event information on tooltip by making use of the [`tooltipTemplate`](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings#tooltiptemplate) option within the [`eventSettings`](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings).

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



> All the field names that are mapped from the Scheduler dataSource to the appropriate field properties such as subject, description, location, startTime and endTime within the [`eventSettings`](https://ej2.syncfusion.com/react/documentation/api/schedule/eventSettings) can be accessed within the template.

### How to prevent the tooltip for specific events

By using the [`tooltipOpen`](https://ej2.syncfusion.com/react/documentation/api/schedule#tooltipOpen) event, you can selectively control when tooltips appear, based on appointment data or other custom conditions.

To prevent a tooltip from appearing for certain events, you can set the `cancel` property to `true` within the [`tooltipOpen`](https://ej2.syncfusion.com/react/documentation/api/schedule#tooltipOpen) event. This ensures that tooltips are only displayed for the relevant appointments, improving user experience by minimizing unnecessary distractions.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% endtabs %}



## Appointment selection

Select appointments with mouse or keyboard. Selected events are visually highlighted with a box shadow.

| Action | Description |
|-------|---------|
| Mouse click or Single tap on appointments | Selects single appointment. |
| Ctrl + [Mouse click] or [Single tap] on appointments | Selects multiple appointments.|

## Deleting multiple appointments

With the options available to select multiple appointments, it is also possible to delete the multiple selected appointments simply by pressing the `delete` key. In case of deleting multiple selected occurrences of an event series, only those occurrences will be deleted and not the entire series.

## Retrieve event details from the UI of an event

It is possible to access the information about the event fields of an appointment element displayed on the Scheduler UI. This can be achieved by passing an appointment element as argument to the public method [`getEventDetails`](https://ej2.syncfusion.com/react/documentation/api/schedule#geteventdetails).

In the following example, the subject of the appointment clicked has been displayed.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% highlight html tabtitle="index.html" %}

{% endhighlight %}
{% endtabs %}



## Get the current view appointments

To retrieve the appointments present in the current view of the Scheduler, you can make use of the [`getCurrentViewEvents`](https://ej2.syncfusion.com/react/documentation/api/schedule#getcurrentviewevents)  public method. In the following example, the count of current view appointment collection rendered has been traced in [`dataBound`](https://ej2.syncfusion.com/react/documentation/api/schedule#databound) event.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% highlight html tabtitle="index.html" %}

{% endhighlight %}
{% endtabs %}



## Get the entire appointment collections

The entire collection of appointments rendered on the Scheduler can be accessed using the [`getEvents`](https://ej2.syncfusion.com/react/documentation/api/schedule#getevents) public method. In the following example, the count of entire appointment collection rendered on the Scheduler has been traced in [`dataBound`](https://ej2.syncfusion.com/react/documentation/api/schedule#databound) event.

{% tabs %}
{% highlight js tabtitle="App.jsx" %}

{% endhighlight %}
{% highlight ts tabtitle="App.tsx" %}

{% endhighlight %}
{% highlight html tabtitle="index.html" %}

{% endhighlight %}
{% endtabs %}



## Refresh appointments

To refresh events only (without re-rendering the Scheduler UI), call the [`refreshEvents`](https://ej2.syncfusion.com/react/documentation/api/schedule#refreshevents) public method.

```ts
this.scheduleObj.refreshEvents();
```

> You can refer to our [React Scheduler](https://www.syncfusion.com/scheduler-sdk/react-scheduler) feature tour page for its groundbreaking feature representations. You can also explore our [React Scheduler example](https://ej2.syncfusion.com/react/demos/#/tailwind3/schedule/overview) to know how to present and manipulate data.