Recurrence editor in React Schedule component

The Recurrence editor is integrated into Scheduler’s editor window by default to process recurrence rule generation for events. It can also be used as a standalone component when you need to work with recurrence-related workflows outside the Scheduler editor.

Tip: The recurrence editor follows the iCalendar recurrence rule specification, so any valid RRULE string defined by the standard can be used.

Important: When using the recurrence editor independently, make sure the required Scheduler and recurrence editor modules are imported correctly.

Customizing the repeat type option in editor

By default, the recurrence editor provides five repeat options:

  • Never
  • Daily
  • Weekly
  • Monthly
  • Yearly

You can customize the recurrence editor to display only specific repeat options, such as Daily and Weekly, by setting the frequencies option.

Note: Limiting the available repeat types is useful when your application only supports a subset of recurrence patterns.

import { useRef } from 'react';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { ScheduleComponent, Day, Week, WorkWeek, Month, Agenda, Inject } from '@syncfusion/ej2-react-schedule';
import { scheduleData } from './datasource';
const App = () => {
    const scheduleObj = useRef(null);
    const eventSettings = { dataSource: scheduleData }
    const onPopupOpen = (args) => {
        if (args.type == 'Editor') {
            scheduleObj.current.eventWindow.recurrenceEditor.frequencies = ['none', 'daily', 'weekly'];
        }
    }
    return (<ScheduleComponent ref={scheduleObj} width='100%' height='550px' selectedDate={new Date(2018, 1, 15)} eventSettings={eventSettings} popupOpen={onPopupOpen.bind(this)}>
        <Inject services={[Day, Week, WorkWeek, Month, Agenda]} />
    </ScheduleComponent>);
}
;
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);
import { useRef } from 'react';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {
  ScheduleComponent, Day, Week, WorkWeek, Month, Agenda, Inject, PopupOpenEventArgs, EventSettingsModel
} from '@syncfusion/ej2-react-schedule';
import { scheduleData } from './datasource';
const App = () => {
  const scheduleObj = useRef<ScheduleComponent>(null);
  const eventSettings: EventSettingsModel = { dataSource: scheduleData }
  const onPopupOpen = (args: PopupOpenEventArgs): void => {
    if (args.type === 'Editor') {
      scheduleObj.current.eventWindow.recurrenceEditor.frequencies = ['none', 'daily', 'weekly'];
    }
  }
  return (<ScheduleComponent ref={scheduleObj} width='100%' height='550px' selectedDate={new Date(2018, 1, 15)} eventSettings={eventSettings}
    popupOpen={onPopupOpen.bind(this)}>
    <Inject services={[Day, Week, WorkWeek, Month, Agenda]} />
  </ScheduleComponent>)
};
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion React Schedule</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Essential JS 2 for React Components" />
    <meta name="author" content="Syncfusion" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-base/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-buttons/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-calendars/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-dropdowns/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-inputs/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-navigations/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-popups/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-schedule/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <link href="index.css" rel="stylesheet" />
    <script src="systemjs.config.js"></script>
    <style>
        #loader {
            color: #008cff;
            height: 40px;
            left: 45%;
            position: absolute;
            top: 45%;
            width: 30%;
        }

        .e-past-app {
            background-color: chocolate !important;
        }

        .custom-class.e-schedule .e-vertical-view .e-all-day-appointment-wrapper .e-appointment,
        .custom-class.e-schedule .e-vertical-view .e-day-wrapper .e-appointment,
        .custom-class.e-schedule .e-month-view .e-appointment {
            background: green;
        }
    </style>
</head>

<body>
    <div id='schedule'>
        <div id='loader'>Loading....</div>
    </div>
</body>

</html>

The other properties available in recurrence editor are tabulated below:

Property Type Description
firstDayOfWeek number Sets the first day of the week.
startDate Date Sets the start date.
dateformat string Sets the specific date format on the recurrence editor.
locale string Sets the locale to be applied on the recurrence editor.
cssClass string Allows styling with custom class names.
enableRtl boolean Allows the recurrence editor to render in RTL mode.
minDate Date Sets the minimum date on the recurrence editor.
maxDate Date Sets the maximum date on the recurrence editor.
value string Sets the recurrence rule output value.
selectedType number Sets the current repeat type in the recurrence editor.

Tip: Use firstDayOfWeek, minDate, and maxDate together when you need to constrain the editor to a specific calendar range.

Customizing the end type option in editor

By default, the recurrence editor provides three end options:

  • Never
  • Until
  • Count

You can customize the recurrence editor to display only specific end options, such as Until and Count, by setting the endTypes property.

Note: Restricting the end types can simplify the UI when users only need a limited set of recurrence termination options.

import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { useRef, useEffect } from 'react';
import { RecurrenceEditorComponent }
  from '@syncfusion/ej2-react-schedule';

const App = () => {
  const recObject = useRef(null);
  useEffect(() => {
    recObject.current.endTypes = ['until', 'count'];
  }, []);
  return (<div className='content-wrapper recurrence-editor-wrap'>
    <div className='RecurrenceEditor'>
      <RecurrenceEditorComponent id='RecurrenceEditor' ref={recObject}></RecurrenceEditorComponent>
    </div>
  </div>)
};
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { useRef, useEffect } from 'react';
import { RecurrenceEditorComponent }
  from '@syncfusion/ej2-react-schedule';

const App = () => {
  const recObject = useRef<RecurrenceEditorComponent>(null);
  useEffect(() => {
    recObject.current.endTypes = ['until', 'count'];
  }, []);
  return (<div className='content-wrapper recurrence-editor-wrap'>
    <div className='RecurrenceEditor'>
      <RecurrenceEditorComponent id='RecurrenceEditor' ref={recObject}></RecurrenceEditorComponent>
    </div>
  </div>)
};
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion React Schedule</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Essential JS 2 for React Components" />
    <meta name="author" content="Syncfusion" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-base/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-buttons/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-calendars/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-dropdowns/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-inputs/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-navigations/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-popups/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-schedule/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
        #loader {
            color: #008cff;
            height: 40px;
            left: 45%;
            position: absolute;
            top: 45%;
            width: 30%;
        }
    </style>
</head>

<body>
    <div id='schedule'>
        <div id='loader'>Loading....</div>
    </div>
</body>

</html>

Accessing the recurrence rule string

The recurrence rule is usually generated based on the options selected from the recurrence editor and follows the iCalendar specification. The generated recurrence rule string is valid for use with the Scheduler event’s recurrence rule field.

A change event is available in the recurrence editor and triggers whenever the editor fields change. Within the event argument, you can access the generated recurrence value through the value property, as shown in the following code example.

Tip: Use the change event when you need to preview or persist the recurrence rule as users update the editor settings.

import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { useRef, useEffect } from 'react';
import { RecurrenceEditorComponent } from '@syncfusion/ej2-react-schedule';
const App = () => {
  const ruleOutput = useRef(null);
    useEffect(() => {
        let outputElement = ruleOutput.current;
        outputElement.innerText = 'Select Rule';
    }, []);
    const onChange = (args) => {
        let outputElement = ruleOutput.current;
        if (args.value == "") {
            outputElement.innerText = 'Select Rule';
        }
        else {
            outputElement.innerText = args.value;
        }
    }
    return (<div className='content-wrapper recurrence-editor-wrap'>
    <div style=>
      <label>Rule Output</label>
      <div className='rule-output-container'>
        <div ref={ruleOutput}></div>
      </div>
    </div>
    <div className='RecurrenceEditor'>
      <RecurrenceEditorComponent id='RecurrenceEditor' change={onChange}></RecurrenceEditorComponent>
    </div>
  </div>);
}
;
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { useRef, useEffect } from 'react';
import { RecurrenceEditorComponent, RecurrenceEditorChangeEventArgs }
  from '@syncfusion/ej2-react-schedule';

const App = () => {
  const ruleOutput = useRef(null);
  useEffect(() => {
    let outputElement: HTMLElement = ruleOutput.current
    outputElement.innerText = 'Select Rule';
  }, []);

  const onChange = (args: RecurrenceEditorChangeEventArgs): void => {
    let outputElement: HTMLElement = ruleOutput.current;
    if (args.value === "") {
      outputElement.innerText = 'Select Rule';
    } else {
      outputElement.innerText = args.value;
    }
  }
  return (<div className='content-wrapper recurrence-editor-wrap'>
    <div style=>
      <label>Rule Output</label>
      <div className='rule-output-container'>
        <div ref={ruleOutput}></div>
      </div>
    </div>
    <div className='RecurrenceEditor'>
      <RecurrenceEditorComponent id='RecurrenceEditor' change={onChange}></RecurrenceEditorComponent>
    </div>
  </div>)
};
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion React Schedule</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Essential JS 2 for React Components" />
    <meta name="author" content="Syncfusion" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-base/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-buttons/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-calendars/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-dropdowns/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-inputs/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-navigations/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-popups/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-schedule/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
     <style>
        #loader {
            color: #008cff;
            height: 40px;
            left: 45%;
            position: absolute;
            top: 45%;
            width: 30%;
        }
    </style>
</head>

<body>
        <div id='schedule'>
            <div id='loader'>Loading....</div>
        </div>
</body>

</html>

Set specific value on recurrence editor

It is possible to display the recurrence editor with specific options loaded initially based on the rule string that you provide. The fields of the recurrence editor will update accordingly when you pass a recurrence rule through the setRecurrenceRule method.

Important: The value passed to setRecurrenceRule must be a valid recurrence rule string that conforms to the iCalendar RRULE format.

import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { useRef, useEffect } from 'react';
import { RecurrenceEditorComponent, RecurrenceEditorChangeEventArgs }
  from '@syncfusion/ej2-react-schedule';
const App = () => {
  const recObject = useRef(null);
  const ruleOutput = useRef(null);
  useEffect(() => {
    let outputElement = ruleOutput.current;
    recObject.current.setRecurrenceRule('FREQ=DAILY;INTERVAL=2;COUNT=8');
    outputElement.innerText = recObject.current.value;
  }, []);
  const onChange = (args) => {
    let outputElement = ruleOutput.current;
    outputElement.innerText = args.value;
  }
  return (<div className='content-wrapper recurrence-editor-wrap'>
    <div style=>
      <label>Rule Output</label>
      <div className='rule-output-container'>
        <div ref={ruleOutput}></div>
      </div>
    </div>
    <div className='RecurrenceEditor'>
      <RecurrenceEditorComponent id='RecurrenceEditor' ref={recObject} change={onChange}></RecurrenceEditorComponent>
    </div>
  </div>)
};
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { useRef, useEffect } from 'react';
import { RecurrenceEditorComponent, RecurrenceEditorChangeEventArgs }
  from '@syncfusion/ej2-react-schedule';

const App = () => {
  const recObject = useRef<RecurrenceEditorComponent>(null);
  const ruleOutput = useRef(null);
  useEffect(() => {
    let outputElement: HTMLElement = ruleOutput.current;
    recObject.current.setRecurrenceRule('FREQ=DAILY;INTERVAL=2;COUNT=8');
    outputElement.innerText = recObject.current.value as string;
  }, []);
  const onChange = (args: RecurrenceEditorChangeEventArgs): void => {
    let outputElement: HTMLElement = ruleOutput.current;
    outputElement.innerText = args.value;
  }
  return (<div className='content-wrapper recurrence-editor-wrap'>
    <div style=>
      <label>Rule Output</label>
      <div className='rule-output-container'>
        <div ref={ruleOutput}></div>
      </div>
    </div>
    <div className='RecurrenceEditor'>
      <RecurrenceEditorComponent id='RecurrenceEditor' ref={recObject} change={onChange}></RecurrenceEditorComponent>
    </div>
  </div>)
};
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion React Schedule</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Essential JS 2 for React Components" />
    <meta name="author" content="Syncfusion" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-base/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-buttons/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-calendars/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-dropdowns/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-inputs/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-navigations/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-popups/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-schedule/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
     <style>
        #loader {
            color: #008cff;
            height: 40px;
            left: 45%;
            position: absolute;
            top: 45%;
            width: 30%;
        }
    </style>
</head>

<body>
        <div id='schedule'>
            <div id='loader'>Loading....</div>
        </div>
</body>

</html>

Recurrence date generation

You can parse the recurrenceRule of an event to generate the date instances on which that particular event is going to occur using the getRecurrenceDates method. It generates dates based on the recurrenceRule that you provide. The parameters to be provided for the getRecurrenceDates method are as follows.

Field name Type Description
startDate Date Appointment start date.
rule string Recurrence rule present in an event object.
excludeDate string Date collection (in ISO format) to be excluded. It is optional.
maximumCount number Number of dates to generate. It is optional.
viewDate Date Current view range’s first date. It is optional.

Note: Use maximumCount carefully when working with rules that do not have an end date to avoid generating unnecessary dates.

import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { useRef, useEffect } from 'react';
import { RecurrenceEditorComponent }
  from '@syncfusion/ej2-react-schedule';

const App = () => {
  const recObject = useRef(null);
  const ruleOutput = useRef(null);
  const today = new Date()
  useEffect(() => {
    let dates = recObject.current.getRecurrenceDates(new Date(today.getFullYear(), today.getMonth(), today.getDate(), 10, 0),
      'FREQ=DAILY;INTERVAL=1', '20180108T114224Z,20180110T114224Z', 4, new Date(today.getFullYear(), today.getMonth(), today.getDate()));
    let stringCollection = '';
    for (let index = 0; index < dates.length; index++) {
      stringCollection += new Date(dates[index]);
      if (index + 1 !== dates.length) {
        stringCollection += '\n';
      }
    }
    let outputElement = ruleOutput.current;
    outputElement.innerText = stringCollection;
  }, []);


  return (<div className='content-wrapper recurrence-editor-wrap'>
    <div style=>
      <label>Date Collections</label>
      <div className='rule-output-container'>
        <div ref={ruleOutput}></div>
      </div>
    </div>
    <div className='RecurrenceEditor' style=>
      <RecurrenceEditorComponent id='RecurrenceEditor' ref={recObject}></RecurrenceEditorComponent>
    </div>
  </div>)
};
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { useRef, useEffect } from 'react';
import { RecurrenceEditorComponent }
  from '@syncfusion/ej2-react-schedule';

const App = () => {
  const recObject = useRef<RecurrenceEditorComponent>(null);
  const ruleOutput = useRef(null);
  const today: Date = new Date()
  useEffect(() => {
    let dates: number[] = recObject.current.getRecurrenceDates(new Date(today.getFullYear(), today.getMonth(), today.getDate(), 10, 0),
      'FREQ=DAILY;INTERVAL=1', '20180108T114224Z,20180110T114224Z', 4, new Date(today.getFullYear(), today.getMonth(), today.getDate()));
    let stringCollection: string = '';
    for (let index: number = 0; index < dates.length; index++) {
      stringCollection += new Date(dates[index]);
      if (index + 1 !== dates.length) {
        stringCollection += '\n';
      }
    }
    let outputElement: HTMLElement = ruleOutput.current;
    outputElement.innerText = stringCollection;
  }, []);

  return (<div className='content-wrapper recurrence-editor-wrap'>
    <div style=>
      <label>Date Collections</label>
      <div className='rule-output-container'>
        <div ref={ruleOutput}></div>
      </div>
    </div>
    <div className='RecurrenceEditor' style=>
      <RecurrenceEditorComponent id='RecurrenceEditor' ref={recObject}></RecurrenceEditorComponent>
    </div>
  </div>)
};
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion React Schedule</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Essential JS 2 for React Components" />
    <meta name="author" content="Syncfusion" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-base/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-buttons/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-calendars/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-dropdowns/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-inputs/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-navigations/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-popups/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-schedule/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
     <style>
        #loader {
            color: #008cff;
            height: 40px;
            left: 45%;
            position: absolute;
            top: 45%;
            width: 30%;
        }
    </style>
</head>

<body>
        <div id='schedule'>
            <div id='loader'>Loading....</div>
        </div>
</body>

</html>

The above example generates two dates January 7, 2018 & January 9 2018 by excluding the in between dates January 8 2018 & January 10 2018, since those dates were given in the exclusion list. Generated dates can then be utilized to create appointments.

Recurrence date generation in server-side

It is also possible to generate recurrence date instances on the server side by manually referring to the RecurrenceHelper class, which is designed to handle this date generation process in application code.

Tip: Use server-side recurrence parsing when you need to validate or expand recurrence rules before saving them to a database or sending them to another service.

Refer here for the step-by-step procedure to achieve date generation on the server side.

Restrict date generation with specific count

If the rule is in the “NEVER ENDS” category, you can specify a maximum count to stop date generation after a defined number of occurrences starting from the provided start date. To do so, provide the appropriate maximumCount value within the getRecurrenceDates method as shown in the following code example.

Important: Limiting recurrence generation is useful for performance and for preventing unbounded result sets in long-running schedules.

import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { useRef, useEffect } from 'react';
import { RecurrenceEditorComponent } from '@syncfusion/ej2-react-schedule';
const App = () => {
  const recObject = useRef(null);
  const ruleOutput = useRef(null);
  useEffect(() => {
    let dates = recObject.current.getRecurrenceDates(new Date(2018, 0, 7, 10, 0), 'FREQ=DAILY;INTERVAL=1', null, 10, null);
    let stringCollection = '';
    for (let index = 0; index < dates.length; index++) {
      stringCollection += new Date(dates[index]);
      if (index + 1 !== dates.length) {
        stringCollection += '\n';
      }
    }
    let outputElement = ruleOutput.current;
    outputElement.innerText = stringCollection;
  }, []);
  return (<div className='content-wrapper recurrence-editor-wrap'>
    <div style=>
      <label>Date Collections</label>
      <div className='rule-output-container'>
        <div ref={ruleOutput}></div>
      </div>
    </div>
    <div className='RecurrenceEditor' style=>
      <RecurrenceEditorComponent id='RecurrenceEditor' ref={recObject}></RecurrenceEditorComponent>
    </div>
  </div>)
};
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { useRef, useEffect } from 'react';
import { RecurrenceEditorComponent }
  from '@syncfusion/ej2-react-schedule';

const App = () => {
  const recObject = useRef<RecurrenceEditorComponent>(null);
  const ruleOutput = useRef(null);
  useEffect(() => {
    let dates: number[] = recObject.current.getRecurrenceDates(new Date(2018, 0, 7, 10, 0), 'FREQ=DAILY;INTERVAL=1', null, 10, null);
    let stringCollection: string = '';
    for (let index: number = 0; index < dates.length; index++) {
      stringCollection += new Date(dates[index]);
      if (index + 1 !== dates.length) {
        stringCollection += '\n';
      }
    }
    let outputElement: HTMLElement = ruleOutput.current;
    outputElement.innerText = stringCollection;
  }, []);
  return (<div className='content-wrapper recurrence-editor-wrap'>
    <div style=>
      <label>Date Collections</label>
      <div className='rule-output-container'>
        <div ref={ruleOutput}></div>
      </div>
    </div>
    <div className='RecurrenceEditor' style=>
      <RecurrenceEditorComponent id='RecurrenceEditor' ref={recObject}></RecurrenceEditorComponent>
    </div>
  </div>)
};
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion React Schedule</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Essential JS 2 for React Components" />
    <meta name="author" content="Syncfusion" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-base/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-buttons/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-calendars/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-dropdowns/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-inputs/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-navigations/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-popups/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/34.2.2/ej2-react-schedule/styles/tailwind3.css" rel="stylesheet" />
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
     <style>
        #loader {
            color: #008cff;
            height: 40px;
            left: 45%;
            position: absolute;
            top: 45%;
            width: 30%;
        }
    </style>
</head>

<body>
        <div id='schedule'>
            <div id='loader'>Loading....</div>
        </div>
</body>

</html>

See also