Data binding in React Schedule component
30 Jan 202624 minutes to read
The Scheduler utilizes the DataManager, which supports both RESTful data service binding and JavaScript object array binding. The dataSource property of Scheduler can be assigned either an instance of DataManager or a JavaScript object array collection. Scheduler supports the following data binding methods:
- Local data
- Remote data
Binding local data
o bind local JSON data to the Scheduler, assign a JavaScript object array to the dataSource option of the Scheduler within the eventSettings property. The JSON object dataSource can also be provided as an instance of DataManager and assigned to the Scheduler dataSource property.
import * as React from 'react';
import * as ReactDOM from "react-dom";
import { ScheduleComponent, Day, Week, WorkWeek, Month, Agenda, Inject } from '@syncfusion/ej2-react-schedule';
const App = () => {
let data = [{
Id: 1,
Subject: 'Explosion of Betelgeuse Star',
StartTime: new Date(2018, 1, 15, 9, 30),
EndTime: new Date(2018, 1, 15, 11, 0)
}, {
Id: 2,
Subject: 'Thule Air Crash Report',
StartTime: new Date(2018, 1, 12, 12, 0),
EndTime: new Date(2018, 1, 12, 14, 0)
}, {
Id: 3,
Subject: 'Blue Moon Eclipse',
StartTime: new Date(2018, 1, 13, 9, 30),
EndTime: new Date(2018, 1, 13, 11, 0)
}, {
Id: 4,
Subject: 'Meteor Showers in 2018',
StartTime: new Date(2018, 1, 14, 13, 0),
EndTime: new Date(2018, 1, 14, 14, 30)
}];
const eventSettings = { dataSource: data };
return (<ScheduleComponent height='550px' selectedDate={new Date(2018, 1, 15)} eventSettings={eventSettings}>
<Inject services={[Day, Week, WorkWeek, Month, Agenda]} />
</ScheduleComponent>);
}
;
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);import * as React from 'react';
import * as ReactDOM from "react-dom";
import { ScheduleComponent, Day, Week, WorkWeek, Month, Agenda, Inject, EventSettingsModel } from '@syncfusion/ej2-react-schedule';
const App = () => {
let data: Object[] = [{
Id: 1,
Subject: 'Explosion of Betelgeuse Star',
StartTime: new Date(2018, 1, 15, 9, 30),
EndTime: new Date(2018, 1, 15, 11, 0)
}, {
Id: 2,
Subject: 'Thule Air Crash Report',
StartTime: new Date(2018, 1, 12, 12, 0),
EndTime: new Date(2018, 1, 12, 14, 0)
}, {
Id: 3,
Subject: 'Blue Moon Eclipse',
StartTime: new Date(2018, 1, 13, 9, 30),
EndTime: new Date(2018, 1, 13, 11, 0)
}, {
Id: 4,
Subject: 'Meteor Showers in 2018',
StartTime: new Date(2018, 1, 14, 13, 0),
EndTime: new Date(2018, 1, 14, 14, 30)
}];
const eventSettings: EventSettingsModel = { dataSource: data };
return (
<ScheduleComponent height='550px' selectedDate={new Date(2018, 1, 15)}
eventSettings={eventSettings}>
<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/32.1.19/ej2-base/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-buttons/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-calendars/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-dropdowns/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-inputs/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-navigations/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-popups/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/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>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='schedule'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>By default,
DataManageruses theJsonAdaptorfor binding local data.
You can also map different field names to the default event fields, as well as include additional
custom fieldsin the event object collection. For details, refer to event fields.
Binding remote data
The Scheduler supports binding to various remote data services. To configure this, create an instance of DataManager, supply the remote service URL to the url option, and assign it to thedataSource property within eventSettings.
Using ODataV4Adaptor
ODataV4 is a standardized protocol for creating and consuming data. The following example demonstrates how to retrieve data from an ODataV4 service using DataManager. To connect with ODataV4 service endpoints, utilize the ODataV4Adaptor within DataManager.
import { useState, useEffect } 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 { DataManager, ODataV4Adaptor } from '@syncfusion/ej2-data';
const App = () => {
const [dataManager, setDataManager] = useState(null);
useEffect(() => {
const fetchData = async () => {
const manager = new DataManager({
url: 'https://services.odata.org/V4/Northwind/Northwind.svc/Orders/',
adaptor: new ODataV4Adaptor()
});
await manager.ready;
setDataManager(manager);
};
fetchData();
}, []);
const fieldsData = {
id: 'Id',
subject: { name: 'ShipName' },
location: { name: 'ShipCountry' },
description: { name: 'ShipAddress' },
startTime: { name: 'OrderDate' },
endTime: { name: 'RequiredDate' },
recurrenceRule: { name: 'ShipRegion' }
}
const eventSettings = { dataSource: dataManager, fields: fieldsData }; return (
<ScheduleComponent height='550px' selectedDate={new Date(1996, 6, 9)} readonly={true} eventSettings={eventSettings}>
<Inject services={[Day, Week, WorkWeek, Month, Agenda]} />
</ScheduleComponent>
);
}
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);import { useState, useEffect } 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 { DataManager, ODataV4Adaptor, EventSettingsModel } from '@syncfusion/ej2-data';
const App = () => {
const [dataManager, setDataManager] = useState(null);
useEffect(() => {
const fetchData = async () => {
const manager = new DataManager({
url: 'https://services.odata.org/V4/Northwind/Northwind.svc/Orders/',
adaptor: new ODataV4Adaptor()
});
await manager.ready;
setDataManager(manager);
};
fetchData();
}, []);
const fieldsData = {
id: 'Id',
subject: { name: 'ShipName' },
location: { name: 'ShipCountry' },
description: { name: 'ShipAddress' },
startTime: { name: 'OrderDate' },
endTime: { name: 'RequiredDate' },
recurrenceRule: { name: 'ShipRegion' }
}
const eventSettings: EventSettingsModel = { dataSource: dataManager, fields: fieldsData };
return (
<ScheduleComponent height='550px' selectedDate={new Date(1996, 6, 9)} readonly={true} eventSettings={eventSettings}>
<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/32.1.19/ej2-base/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-buttons/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-calendars/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-dropdowns/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-inputs/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-navigations/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-popups/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/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>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='schedule'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>Filter events using the in-built query
To enable server-side filtering operations based on specific conditions, set the includeFiltersInQuery API to true. This allows the filter query to include the start date, end date, and recurrence rule, enabling the request to retrieve only the relevant data from the server.
This method greatly improves the component’s performance by reducing the data that needs to be transferred to the client side. As a result, the component’s efficiency and responsiveness are significantly enhanced, resulting in a better user experience. However, it is important to consider the possibility of longer query strings, which may cause issues with the maximum URL length or server limitations on query string length.
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 { DataManager, ODataV4Adaptor } from '@syncfusion/ej2-data';
const App = () => {
let dataManager = new DataManager({
url: 'https://services.odata.org/V4/Northwind/Northwind.svc/Orders/',
adaptor: new ODataV4Adaptor()
});
const fieldsData = {
id: 'Id',
subject: { name: 'ShipName' },
location: { name: 'ShipCountry' },
description: { name: 'ShipAddress' },
startTime: { name: 'OrderDate' },
endTime: { name: 'RequiredDate' },
recurrenceRule: { name: 'ShipRegion' }
}
const eventSettings = { includeFiltersInQuery: true, dataSource: dataManager, fields: fieldsData }
return (<ScheduleComponent height='550px' currentView='Month' selectedDate={new Date(1996, 6, 9)} readonly={true} eventSettings={eventSettings}>
<Inject services={[Day, Week, WorkWeek, Month, Agenda]} />
</ScheduleComponent>);
};
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);import * as React from 'react';
import * as ReactDOM from "react-dom";
import { ScheduleComponent, Day, Week, WorkWeek, Month, Agenda, Inject, EventSettingsModel } from '@syncfusion/ej2-react-schedule';
import { DataManager, ODataV4Adaptor, Query } from '@syncfusion/ej2-data';
const App = () => {
let dataManager: DataManager = new DataManager({
url: 'https://services.odata.org/V4/Northwind/Northwind.svc/Orders/',
adaptor: new ODataV4Adaptor()
});
const fieldsData = {
id: 'Id',
subject: { name: 'ShipName' },
location: { name: 'ShipCountry' },
description: { name: 'ShipAddress' },
startTime: { name: 'OrderDate' },
endTime: { name: 'RequiredDate' },
recurrenceRule: { name: 'ShipRegion' }
}
const eventSettings: EventSettingsModel = { includeFiltersInQuery: true, dataSource: dataManager, fields: fieldsData }
return (
<ScheduleComponent height='550px' currentView='Month' selectedDate={new Date(1996, 6, 9)} readonly={true}
eventSettings={eventSettings}>
<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/32.1.19/ej2-base/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-buttons/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-calendars/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-dropdowns/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-inputs/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-navigations/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-popups/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/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>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='schedule'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>The image below illustrates how parameters are passed using an ODataV4 filter for remote data binding.

Using custom adaptor
You can create a custom adaptor by extending one of the built-in adaptors. The following example demonstrates how to use a custom adaptor and add a custom field, such as EventID, to the appointments by overriding the response processing using the processResponse method of the ODataV4Adaptor.
import { useState, useEffect } 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 { DataManager, ODataV4Adaptor, Query } from '@syncfusion/ej2-data';
const CustomAdaptor = () => {
ODataV4Adaptor.call(this);
}
CustomAdaptor.prototype = Object.create(ODataV4Adaptor.prototype);
CustomAdaptor.prototype.constructor = CustomAdaptor;
CustomAdaptor.prototype.processResponse = function () {
let i = 0;
let original = ODataV4Adaptor.prototype.processResponse.apply(this, arguments);
original.forEach((item) => (item['EventID'] = ++i));
return original;
};
const App = () => {
const [dataManager, setDataManager] = useState(null);
useEffect(() => {
const fetchData = async () => {
const manager = new DataManager({
url: 'https://services.odata.org/V4/Northwind/Northwind.svc/Orders/',
adaptor: new CustomAdaptor(),
});
const query = new Query().take(10); // Example query to limit the number of records
const data = await manager.executeQuery(query);
setDataManager(new DataManager(data));
};
fetchData();
}, []);
const fieldsData = {
id: 'Id',
subject: { name: 'ShipName' },
location: { name: 'ShipCountry' },
description: { name: 'ShipAddress' },
startTime: { name: 'OrderDate' },
endTime: { name: 'RequiredDate' },
recurrenceRule: { name: 'ShipRegion' }
}
const eventSettings = { dataSource: dataManager, fields: fieldsData };
return (
<ScheduleComponent
height='550px'
selectedDate={new Date(1996, 6, 9)}
readonly={true}
eventSettings={eventSettings}
>
<Inject services={[Day, Week, WorkWeek, Month, Agenda]} />
</ScheduleComponent>
);
}
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);import { useState, useEffect } from 'react';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { ScheduleComponent, Day, Week, WorkWeek, Month, Agenda, Inject, EventSettingsModel } from '@syncfusion/ej2-react-schedule';
import { DataManager, ODataV4Adaptor } from '@syncfusion/ej2-data';
function CustomAdaptor() {
ODataV4Adaptor.call(this);
}
CustomAdaptor.prototype = Object.create(ODataV4Adaptor.prototype);
CustomAdaptor.prototype.constructor = CustomAdaptor;
CustomAdaptor.prototype.processResponse = function () {
let i = 0;
let original = ODataV4Adaptor.prototype.processResponse.apply(this, arguments);
original.forEach((item: any) => (item['EventID'] = ++i));
return original;
};
const App = () => {
const [dataManager, setDataManager] = useState<DataManager | null>(null);
useEffect(() => {
const fetchData = async () => {
const manager = new DataManager({
url: 'https://services.odata.org/V4/Northwind/Northwind.svc/Orders/',
adaptor: new CustomAdaptor(),
crossDomain: true
});
await manager.ready;
setDataManager(manager);
};
fetchData();
}, []);
const fieldsData = {
id: 'Id',
subject: { name: 'ShipName' },
location: { name: 'ShipCountry' },
description: { name: 'ShipAddress' },
startTime: { name: 'OrderDate' },
endTime: { name: 'RequiredDate' },
recurrenceRule: { name: 'ShipRegion' }
}
const eventSettings: EventSettingsModel = { dataSource: dataManager, fields: fieldsData };
return (
<ScheduleComponent
height='550px'
selectedDate={new Date(1996, 6, 9)}
readonly={true}
eventSettings={eventSettings}
>
<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/32.1.19/ej2-base/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-buttons/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-calendars/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-dropdowns/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-inputs/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-navigations/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-popups/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/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>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='schedule'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>Loading data via AJAX post
You can bind the event data through external ajax request and assign it to the dataSourceproperty of Scheduler. In the following code example, we have retrieved the data from server with the help of ajax request and assigned the resultant data to the dataSource property of Scheduler within the onSuccess event of Ajax.
[src/app/app.tsx]
import * as React from 'react';
import { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';
import { Ajax } from '@syncfusion/ej2-base';
import {
ScheduleComponent, Day, Week, WorkWeek, Month, Agenda, Inject, EventSettingsModel
} from '@syncfusion/ej2-react-schedule';
import { DataManager } from '@syncfusion/ej2-data';
const App = () => {
const [dataManager, setDataManager] = useState<DataManager | null>(null);
useEffect(() => {
const ajax = new Ajax('Home/GetData', 'GET', false);
ajax.send();
ajax.onSuccess = function (value: DataManager) {
setDataManager(value);
};
}, []);
const eventSettings: EventSettingsModel = { dataSource: dataManager };
return (
<ScheduleComponent height='550px' selectedDate={new Date(2017, 5, 11)} eventSettings={eventSettings}>
<Inject services={[Day, Week, WorkWeek, Month, Agenda]} />
</ScheduleComponent>
);
}
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);[src/app/app.ts]
Definition for the controller method
GetDatacan be referred here.
Passing additional parameters to the server
To send additional custom parameters in the server-side request, use the addParams method of Query. Assign this Query object with the custom parameters to the query property of Scheduler.
import { useState, useEffect } 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 { DataManager, ODataV4Adaptor, Query } from '@syncfusion/ej2-data';
const App = () => {
const [dataManager, setDataManager] = useState(null);
useEffect(() => {
const fetchData = async () => {
const manager = new DataManager({
url: 'https://services.odata.org/V4/Northwind/Northwind.svc/Orders/',
adaptor: new ODataV4Adaptor()
});
await manager.ready;
const query = new Query().addParams('readOnly', 'true');
const data = await manager.executeQuery(query);
setDataManager(manager);
};
fetchData();
}, []);
const fieldsData = {
id: 'Id',
subject: { name: 'ShipName' },
location: { name: 'ShipCountry' },
description: { name: 'ShipAddress' },
startTime: { name: 'OrderDate' },
endTime: { name: 'RequiredDate' },
recurrenceRule: { name: 'ShipRegion' }
}
const eventSettings = { dataSource: dataManager, fields: fieldsData };
return (
<ScheduleComponent
height='550px'
readonly={true}
eventSettings={eventSettings}
selectedDate={new Date(1996, 6, 9)}
>
<Inject services={[Day, Week, WorkWeek, Month, Agenda]} />
</ScheduleComponent>
);
}
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);import { useState, useEffect } from 'react';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { ScheduleComponent, Day, Week, WorkWeek, Month, Agenda, Inject, EventSettingsModel } from '@syncfusion/ej2-react-schedule';
import { DataManager, ODataV4Adaptor, Query } from '@syncfusion/ej2-data';
const App = () => {
const [dataManager, setDataManager] = useState<DataManager | null>(null);
useEffect(() => {
const fetchData = async () => {
const manager = new DataManager({
url: 'https://services.odata.org/V4/Northwind/Northwind.svc/Orders/',
adaptor: new ODataV4Adaptor()
});
await manager.ready;
const query = new Query().addParams('readOnly', 'true');
const data = await manager.executeQuery(query) as any;
setDataManager(manager);
};
fetchData();
}, []);
const fieldsData = {
id: 'Id',
subject: { name: 'ShipName' },
location: { name: 'ShipCountry' },
description: { name: 'ShipAddress' },
startTime: { name: 'OrderDate' },
endTime: { name: 'RequiredDate' },
recurrenceRule: { name: 'ShipRegion' }
}
const eventSettings: EventSettingsModel = { dataSource: dataManager, fields: fieldsData };
return (
<ScheduleComponent
height='550px'
readonly={true}
eventSettings={eventSettings}
selectedDate={new Date(1996, 6, 9)}
>
<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/32.1.19/ej2-base/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-buttons/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-calendars/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-dropdowns/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-inputs/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-navigations/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-popups/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/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>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='schedule'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>Parameters added using the
queryproperty are sent with the data request to the server on every Scheduler action.
Handling failure actions
When Scheduler interacts with the server, server-side exceptions may occur. These error messages or exception details can be accessed client-side using the actionFailure event of Scheduler.
The argument passed to the actionFailure event contains all error details returned from the server.
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 { DataManager } from '@syncfusion/ej2-data';
const App = () => {
const scheduleRef = useRef(null);
const dataManager = useRef(new DataManager({
url: 'http://some.com/invalidUrl'
}));
const eventSettings = { dataSource: dataManager.current };
const onActionFailure = () => {
const span = document.createElement('span');
scheduleRef.current?.element.parentNode?.insertBefore(span, scheduleRef.current?.element);
if (span.style) {
span.style.color = '#FF0000';
}
span.innerHTML = 'Server exception: 404 Not found';
};
return (
<ScheduleComponent height='550px' ref={scheduleRef} selectedDate={new Date(2017, 5, 11)} actionFailure={onActionFailure} eventSettings={eventSettings} >
<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, EventSettingsModel } from '@syncfusion/ej2-react-schedule';
import { DataManager } from '@syncfusion/ej2-data';
const App = () => {
const scheduleRef = useRef<ScheduleComponent>(null);
const dataManager = useRef<DataManager>(new DataManager({
url: 'http://some.com/invalidUrl'
}));
const eventSettings: EventSettingsModel = { dataSource: dataManager.current };
const onActionFailure = (): void => {
const span = document.createElement('span');
scheduleRef.current.element.parentNode.insertBefore(span, scheduleRef.current.element);
if (span.style) {
span.style.color = '#FF0000';
}
span.innerHTML = 'Server exception: 404 Not found';
};
return (
<ScheduleComponent height='550px' ref={scheduleRef} selectedDate={new Date(2017, 5, 11)} actionFailure={onActionFailure} eventSettings={eventSettings} >
<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/32.1.19/ej2-base/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-buttons/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-calendars/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-dropdowns/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-inputs/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-navigations/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-popups/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/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>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='schedule'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>The
actionFailureevent is triggered not only when the server returns errors, but also when an exception occurs during Scheduler CRUD operations.
Scheduler CRUD actions
The CRUD (Create, Read, Update, and Delete) actions can be performed on Scheduler appointments using the adaptors available within the DataManager. Typically, the UrlAdaptor is used for CRUD operations on scheduler appointments.
import { Schedule, Day, Week, WorkWeek, Month, Agenda } from '@syncfusion/ej2-schedule';
import { DataManager, UrlAdaptor } from '@syncfusion/ej2-data';
Schedule.Inject(Day, Week, WorkWeek, Month, Agenda);
let dataManager: DataManager = new DataManager({
url: 'Home/GetData', // 'controller/actions'
crudUrl: 'Home/UpdateData',
adaptor: new UrlAdaptor
});
let scheduleObj: Schedule = new Schedule({
height: '550px',
selectedDate: new Date(2017, 5, 5),
eventSettings: { dataSource: dataManager }
});
scheduleObj.appendTo('#Schedule');The server-side controller code to handle the CRUD operations are as follows.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ScheduleSample.Models;
namespace ScheduleSample.Controllers
{
public class HomeController : Controller
{
ScheduleDataDataContext db = new ScheduleDataDataContext();
public ActionResult Index()
{
return View();
}
public JsonResult LoadData() // Here we get the Start and End Date and based on that can filter the data and return to Scheduler
{
var data = db.ScheduleEventDatas.ToList();
return Json(data, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public JsonResult UpdateData(EditParams param)
{
if (param.action == "insert" || (param.action == "batch" && param.added != null)) // this block of code will execute while inserting the appointments
{
var value = (param.action == "insert") ? param.value : param.added[0];
int intMax = db.ScheduleEventDatas.ToList().Count > 0 ? db.ScheduleEventDatas.ToList().Max(p => p.Id) : 1;
DateTime startTime = Convert.ToDateTime(value.StartTime);
DateTime endTime = Convert.ToDateTime(value.EndTime);
ScheduleEventData appointment = new ScheduleEventData()
{
Id = intMax + 1,
StartTime = startTime.ToLocalTime(),
EndTime = endTime.ToLocalTime(),
Subject = value.Subject,
IsAllDay = value.IsAllDay,
StartTimezone = value.StartTimezone,
EndTimezone = value.EndTimezone,
RecurrenceRule = value.RecurrenceRule,
RecurrenceID = value.RecurrenceID,
RecurrenceException = value.RecurrenceException
};
db.ScheduleEventDatas.InsertOnSubmit(appointment);
db.SubmitChanges();
}
if (param.action == "update" || (param.action == "batch" && param.changed != null)) // this block of code will execute while updating the appointment
{
var value = (param.action == "update") ? param.value : param.changed[0];
var filterData = db.ScheduleEventDatas.Where(c => c.Id == Convert.ToInt32(value.Id));
if (filterData.Count() > 0)
{
DateTime startTime = Convert.ToDateTime(value.StartTime);
DateTime endTime = Convert.ToDateTime(value.EndTime);
ScheduleEventData appointment = db.ScheduleEventDatas.Single(A => A.Id == Convert.ToInt32(value.Id));
appointment.StartTime = startTime.ToLocalTime();
appointment.EndTime = endTime.ToLocalTime();
appointment.StartTimezone = value.StartTimezone;
appointment.EndTimezone = value.EndTimezone;
appointment.Subject = value.Subject;
appointment.IsAllDay = value.IsAllDay;
appointment.RecurrenceRule = value.RecurrenceRule;
appointment.RecurrenceID = value.RecurrenceID;
appointment.RecurrenceException = value.RecurrenceException;
}
db.SubmitChanges();
}
if (param.action == "remove" || (param.action == "batch" && param.deleted != null)) // this block of code will execute while removing the appointment
{
if (param.action == "remove")
{
int key = Convert.ToInt32(param.key);
ScheduleEventData appointment = db.ScheduleEventDatas.Where(c => c.Id == key).FirstOrDefault();
if (appointment != null) db.ScheduleEventDatas.DeleteOnSubmit(appointment);
}
else
{
foreach (var apps in param.deleted)
{
ScheduleEventData appointment = db.ScheduleEventDatas.Where(c => c.Id == apps.Id).FirstOrDefault();
if (appointment != null) db.ScheduleEventDatas.DeleteOnSubmit(appointment);
}
}
db.SubmitChanges();
}
var data = db.ScheduleEventDatas.ToList();
return Json(data, JsonRequestBehavior.AllowGet);
}
public class EditParams
{
public string key { get; set; }
public string action { get; set; }
public List<ScheduleEventData> added { get; set; }
public List<ScheduleEventData> changed { get; set; }
public List<ScheduleEventData> deleted { get; set; }
public ScheduleEventData value { get; set; }
}
}
}Configuring Scheduler with Google API service
We have assigned our custom created Google Calendar url to the DataManager and assigned the same to the Scheduler dataSource. Since the events data retrieved from the Google Calendar will be in its own object format, therefore it needs to be resolved manually within the Scheduler’s dataBinding event. Within this event, the event fields needs to be mapped properly and then assigned to the result.
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 { DataManager, WebApiAdaptor } from '@syncfusion/ej2-data';
const App = () => {
let calendarId = 'en.usa%[email protected]';
let publicKey = 'AIzaSyBgbX_tgmVanBP4yafDPPXxWr70sjbKAXM';
const dataManger = new DataManager({
url: 'https://www.googleapis.com/calendar/v3/calendars/' + calendarId + '/events?key=' + publicKey,
adaptor: new WebApiAdaptor(),
crossDomain: true
});
const eventSettings = { dataSource: dataManger };
const onDataBinding = (e) => {
let items = e.result.items;
let scheduleData = [];
if (items.length > 0) {
for (let i = 0; i < items.length; i++) {
let event = items[i];
let when = event.start.dateTime;
let start = event.start.dateTime;
let end = event.end.dateTime;
if (!when) {
when = event.start.date;
start = event.start.date;
end = event.end.date;
}
scheduleData.push({
Id: event.id,
Subject: event.summary,
StartTime: new Date(start),
EndTime: new Date(end),
IsAllDay: !event.start.dateTime
});
}
}
e.result = scheduleData;
}
return (<ScheduleComponent width='100%' height='550px' selectedDate={new Date(2018, 10, 14)} readonly={true} eventSettings={eventSettings} dataBinding={onDataBinding}>
<Inject services={[Day, Week, WorkWeek, Month, Agenda]} />
</ScheduleComponent>);
}
;
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);import * as React from 'react';
import * as ReactDOM from "react-dom";
import { ScheduleComponent, Day, Week, WorkWeek, Month, Agenda, Inject, EventSettingsModel } from '@syncfusion/ej2-react-schedule';
import { DataManager, WebApiAdaptor, Query } from '@syncfusion/ej2-data';
const App = () => {
let calendarId: string = 'en.usa%[email protected]';
let publicKey: 'AIzaSyBgbX_tgmVanBP4yafDPPXxWr70sjbKAXM';
const dataManger: DataManager = new DataManager({
url: 'https://www.googleapis.com/calendar/v3/calendars/' + calendarId + '/events?key=' + publicKey,
adaptor: new WebApiAdaptor(),
crossDomain: true
});
const eventSettings: EventSettingsModel = { dataSource: dataManger };
const onDataBinding = (e: { [key: string]: Object }): void => {
let items: { [key: string]: Object }[] = (e.result as { [key: string]: Object }).items as { [key: string]: Object }[];
let scheduleData: Object[] = [];
if (items.length > 0) {
for (let i: number = 0; i < items.length; i++) {
let event: { [key: string]: Object } = items[i];
let when: string = (event.start as { [key: string]: Object }).dateTime as string;
let start: string = (event.start as { [key: string]: Object }).dateTime as string;
let end: string = (event.end as { [key: string]: Object }).dateTime as string;
if (!when) {
when = (event.start as { [key: string]: Object }).date as string;
start = (event.start as { [key: string]: Object }).date as string;
end = (event.end as { [key: string]: Object }).date as string;
}
scheduleData.push({
Id: event.id,
Subject: event.summary,
StartTime: new Date(start),
EndTime: new Date(end),
IsAllDay: !(event.start as { [key: string]: Object }).dateTime
});
}
}
e.result = scheduleData;
}
return (
<ScheduleComponent width='100%'
height='550px' selectedDate={new Date(2018, 10, 14)} readonly={true}
eventSettings={eventSettings} dataBinding={onDataBinding}>
<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/32.1.19/ej2-base/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-buttons/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-calendars/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-dropdowns/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-inputs/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-navigations/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/ej2-react-popups/styles/tailwind3.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/32.1.19/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>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='schedule'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>You can refer to our React Scheduler feature tour page for its groundbreaking feature representations. You can also explore our React Scheduler example to knows how to present and manipulate data.