Having trouble getting help?
Contact Support
Contact Support
Show quick info template in React Schedule component
28 Jul 202324 minutes to read
This demo showcases the quick popups for cells and appointments with the customized templates.
import { useRef } from 'react';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { ScheduleComponent, ResourcesDirective, ResourceDirective, Day, Week, WorkWeek, Month, Agenda, MonthAgenda, Inject } from '@syncfusion/ej2-react-schedule';
import { Internationalization } from '@syncfusion/ej2-base';
import { DropDownListComponent } from '@syncfusion/ej2-react-dropdowns';
import { TextBoxComponent } from '@syncfusion/ej2-react-inputs';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import { ScheduleData } from './datasource';
const App = () => {
const eventTypeObj = useRef(null);
const titleObj = useRef(null);
const notesObj = useRef(null);
const scheduleObj = useRef(null);
const intl = new Internationalization();
const roomData = [
{ Name: 'Jammy', Id: 1, Capacity: 20, Color: '#ea7a57', Type: 'Conference' },
{ Name: 'Tweety', Id: 2, Capacity: 7, Color: '#7fa900', Type: 'Cabin' },
{ Name: 'Nestle', Id: 3, Capacity: 5, Color: '#5978ee', Type: 'Cabin' },
{ Name: 'Phoenix', Id: 4, Capacity: 15, Color: '#fec200', Type: 'Conference' },
{ Name: 'Mission', Id: 5, Capacity: 25, Color: '#df5286', Type: 'Conference' },
{ Name: 'Hangout', Id: 6, Capacity: 10, Color: '#00bdae', Type: 'Cabin' },
{ Name: 'Rick Roll', Id: 7, Capacity: 20, Color: '#865fcf', Type: 'Conference' },
{ Name: 'Rainbow', Id: 8, Capacity: 8, Color: '#1aaa55', Type: 'Cabin' },
{ Name: 'Swarm', Id: 9, Capacity: 30, Color: '#df5286', Type: 'Conference' },
{ Name: 'Photogenic', Id: 10, Capacity: 25, Color: '#710193', Type: 'Conference' }
];
const eventSettings = { dataSource: ScheduleData };
const headerTemplate = (props) => {
return (<div className="quick-info-header">
<div className="quick-info-header-content" style={getHeaderStyles(props)}>
<div className="quick-info-title">{getHeaderTitle(props)}</div>
<div className="duration-text">{getHeaderDetails(props)}</div>
</div>
</div>);
}
const contentTemplate = (props) => {
return (<div className="quick-info-content">
{props.elementType === 'cell' ?
<div className="e-cell-content">
<div className="content-area">
<TextBoxComponent id="title" ref={titleObj} placeholder="Title" />
</div>
<div className="content-area">
<DropDownListComponent id="eventType" ref={eventTypeObj} dataSource={roomData} fields= placeholder="Choose Type" index={0} popupHeight="200px" />
</div>
<div className="content-area">
<TextBoxComponent id="notes" ref={notesObj} placeholder="Notes" />
</div>
</div>
:
<div className="event-content">
<div className="meeting-type-wrap">
<label>Subject</label>:
<span>{props.Subject}</span>
</div>
<div className="meeting-subject-wrap">
<label>Type</label>:
<span>{getEventType(props)}</span>
</div>
<div className="notes-wrap">
<label>Notes</label>:
<span>{props.Description}</span>
</div>
</div>}
</div>);
}
const footerTemplate = (props) => {
return (<div className="quick-info-footer">
{props.elementType === "cell" ?
<div className="cell-footer">
<ButtonComponent id="more-details" cssClass='e-flat' content="More Details" onClick={buttonClickActions.bind(this)} />
<ButtonComponent id="add" cssClass='e-flat' content="Add" isPrimary={true} onClick={buttonClickActions.bind(this)} />
</div>
:
<div className="event-footer">
<ButtonComponent id="delete" cssClass='e-flat' content="Delete" onClick={buttonClickActions.bind(this)} />
<ButtonComponent id="more-details" cssClass='e-flat' content="More Details" isPrimary={true} onClick={buttonClickActions.bind(this).bind(this)} />
</div>}
</div>);
}
const quickInfoTemplates = {
header: headerTemplate,
content: contentTemplate,
footer: footerTemplate
};
const getResourceData = (data) => {
const resources = scheduleObj.current.getResourceCollections().slice(-1)[0];
const resourceData = resources.dataSource.filter((resource) => resource.Id === data.RoomId)[0];
return resourceData;
}
const getHeaderStyles = (data) => {
if (data.elementType === 'cell') {
return { alignItems: 'center', color: '#919191' };
}
else {
const resourceData = getResourceData(data);
return { background: resourceData.Color, color: '#FFFFFF' };
}
}
const getHeaderTitle = (data) => {
return (data.elementType === 'cell') ? 'Add Appointment' : 'Appointment Details';
}
const getHeaderDetails = (data) => {
return intl.formatDate(data.StartTime, { type: 'date', skeleton: 'full' }) + ' (' +
intl.formatDate(data.StartTime, { skeleton: 'hm' }) + ' - ' +
intl.formatDate(data.EndTime, { skeleton: 'hm' }) + ')';
}
const getEventType = (data) => {
const resourceData = getResourceData(data);
return resourceData.Name;
}
const buttonClickActions = (e) => {
const quickPopup = scheduleObj.current.element.querySelector('.e-quick-popup-wrapper');
const getSlotData = () => {
const cellDetails = scheduleObj.current.getCellDetails(scheduleObj.current.getSelectedElements());
const addObj = {};
addObj.Id = scheduleObj.current.getEventMaxID();
addObj.Subject = titleObj.current.value;
addObj.StartTime = new Date(+cellDetails.startTime);
addObj.EndTime = new Date(+cellDetails.endTime);
addObj.Description = notesObj.current.value;
addObj.RoomId = eventTypeObj.current.value;
return addObj;
};
if (e.target.id === 'add') {
const addObj = getSlotData();
scheduleObj.current.addEvent(addObj);
}
else if (e.target.id === 'delete') {
const eventDetails = scheduleObj.current.activeEventData.event;
let currentAction = 'Delete';
if (eventDetails.RecurrenceRule) {
currentAction = 'DeleteOccurrence';
}
scheduleObj.current.deleteEvent(eventDetails, currentAction);
}
else {
const isCellPopup = quickPopup.firstElementChild.classList.contains('e-cell-popup');
const eventDetails = isCellPopup ? getSlotData() :
scheduleObj.current.activeEventData.event;
let currentAction = isCellPopup ? 'Add' : 'Save';
if (eventDetails.RecurrenceRule) {
currentAction = 'EditOccurrence';
}
scheduleObj.current.openEditor(eventDetails, currentAction, true);
}
scheduleObj.current.closeQuickInfoPopup();
}
return (<div className='schedule-control-section'>
<div className='col-lg-12 control-section'>
<div className='control-wrapper'>
<ScheduleComponent id="schedule" cssClass='quick-info-template' ref={scheduleObj} height="650px" selectedDate={new Date(2020, 0, 9)} eventSettings={eventSettings} quickInfoTemplates={quickInfoTemplates}>
<ResourcesDirective>
<ResourceDirective field='RoomId' title='Room Type' name='MeetingRoom' textField='Name' idField='Id' colorField='Color' dataSource={roomData}></ResourceDirective>
</ResourcesDirective>
<Inject services={[Day, Week, WorkWeek, Month, Agenda, MonthAgenda]} />
</ScheduleComponent>
</div>
</div>
</div>);
}
;
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, ResourcesDirective, ResourceDirective, Day, Week, WorkWeek, Month,
Agenda, MonthAgenda, Inject, ResourcesModel, CellClickEventArgs, CurrentAction, EventSettingsModel
} from '@syncfusion/ej2-react-schedule';
import { Internationalization } from '@syncfusion/ej2-base';
import { DropDownListComponent } from '@syncfusion/ej2-react-dropdowns';
import { TextBoxComponent } from '@syncfusion/ej2-react-inputs';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import { ScheduleData } from './datasource';
const App = () => {
const eventTypeObj = useRef<DropDownListComponent>(null);
const titleObj = useRef<TextBoxComponent>(null);
const notesObj = useRef<TextBoxComponent>(null);
const scheduleObj = useRef<ScheduleComponent>(null);
const intl: Internationalization = new Internationalization();
const headerTemplate = (props: { [key: string]: Date }): JSX.Element => {
return (
<div className="quick-info-header">
<div className="quick-info-header-content" style={getHeaderStyles(props)}>
<div className="quick-info-title">{getHeaderTitle(props)}</div>
<div className="duration-text">{getHeaderDetails(props)}</div>
</div>
</div>
);
}
const contentTemplate = (props: { [key: string]: string }): JSX.Element => {
return (
<div className="quick-info-content">
{props.elementType === 'cell' ?
<div className="e-cell-content">
<div className="content-area">
<TextBoxComponent id="title" ref={titleObj} placeholder="Title" />
</div>
<div className="content-area">
<DropDownListComponent id="eventType" ref={eventTypeObj} dataSource={roomData}
fields= placeholder="Choose Type" index={0} popupHeight="200px" />
</div>
<div className="content-area">
<TextBoxComponent id="notes" ref={notesObj} placeholder="Notes" />
</div>
</div>
:
<div className="event-content">
<div className="meeting-type-wrap">
<label>Subject</label>:
<span>{props.Subject}</span>
</div>
<div className="meeting-subject-wrap">
<label>Type</label>:
<span>{getEventType(props)}</span>
</div>
<div className="notes-wrap">
<label>Notes</label>:
<span>{props.Description}</span>
</div>
</div>
}
</div>
);
}
const footerTemplate = (props: { [key: string]: Object }): JSX.Element => {
return (
<div className="quick-info-footer">
{props.elementType === "cell" ?
<div className="cell-footer">
<ButtonComponent id="more-details" cssClass='e-flat' content="More Details" onClick={buttonClickActions.bind(this)} />
<ButtonComponent id="add" cssClass='e-flat' content="Add" isPrimary={true} onClick={buttonClickActions.bind(this)} />
</div>
:
<div className="event-footer">
<ButtonComponent id="delete" cssClass='e-flat' content="Delete" onClick={buttonClickActions.bind(this)} />
<ButtonComponent id="more-details" cssClass='e-flat' content="More Details" isPrimary={true} onClick={buttonClickActions.bind(this).bind(this)} />
</div>
}
</div>
);
}
const roomData: { [key: string]: Object }[] = [
{ Name: 'Jammy', Id: 1, Capacity: 20, Color: '#ea7a57', Type: 'Conference' },
{ Name: 'Tweety', Id: 2, Capacity: 7, Color: '#7fa900', Type: 'Cabin' },
{ Name: 'Nestle', Id: 3, Capacity: 5, Color: '#5978ee', Type: 'Cabin' },
{ Name: 'Phoenix', Id: 4, Capacity: 15, Color: '#fec200', Type: 'Conference' },
{ Name: 'Mission', Id: 5, Capacity: 25, Color: '#df5286', Type: 'Conference' },
{ Name: 'Hangout', Id: 6, Capacity: 10, Color: '#00bdae', Type: 'Cabin' },
{ Name: 'Rick Roll', Id: 7, Capacity: 20, Color: '#865fcf', Type: 'Conference' },
{ Name: 'Rainbow', Id: 8, Capacity: 8, Color: '#1aaa55', Type: 'Cabin' },
{ Name: 'Swarm', Id: 9, Capacity: 30, Color: '#df5286', Type: 'Conference' },
{ Name: 'Photogenic', Id: 10, Capacity: 25, Color: '#710193', Type: 'Conference' }
];
const eventSettings: EventSettingsModel = { dataSource: ScheduleData };
const quickInfoTemplates = {
header: headerTemplate,
content: contentTemplate,
footer: footerTemplate
};
const getResourceData = (data: { [key: string]: Object }): { [key: string]: Object } => {
const resources: ResourcesModel = scheduleObj.current.getResourceCollections().slice(-1)[0];
const resourceData: { [key: string]: Object } = (resources.dataSource as Object[]).filter((resource: { [key: string]: Object }) =>
resource.Id === data.RoomId)[0] as { [key: string]: Object };
return resourceData;
}
const getHeaderStyles = (data: { [key: string]: Object }): Object => {
if (data.elementType === 'cell') {
return { alignItems: 'center', color: '#919191' };
} else {
const resourceData: { [key: string]: Object } = getResourceData(data);
return { background: resourceData.Color, color: '#FFFFFF' };
}
}
const getHeaderTitle = (data: { [key: string]: Object }): string => {
return (data.elementType === 'cell') ? 'Add Appointment' : 'Appointment Details';
}
const getHeaderDetails = (data: { [key: string]: Date }): string => {
return intl.formatDate(data.StartTime, { type: 'date', skeleton: 'full' }) + ' (' +
intl.formatDate(data.StartTime, { skeleton: 'hm' }) + ' - ' +
intl.formatDate(data.EndTime, { skeleton: 'hm' }) + ')';
}
const getEventType = (data: { [key: string]: string }): string => {
const resourceData: { [key: string]: Object } = getResourceData(data);
return resourceData.Name as string;
}
const buttonClickActions = (e: Event) => {
const quickPopup: HTMLElement = scheduleObj.current.element.querySelector('.e-quick-popup-wrapper') as HTMLElement;
const getSlotData: Function = (): { [key: string]: Object } => {
const cellDetails: CellClickEventArgs = scheduleObj.current.getCellDetails(scheduleObj.current.getSelectedElements());
const addObj: { [key: string]: Object } = {};
addObj.Id = scheduleObj.current.getEventMaxID();
addObj.Subject = titleObj.current.value;
addObj.StartTime = new Date(+cellDetails.startTime);
addObj.EndTime = new Date(+cellDetails.endTime);
addObj.Description = notesObj.current.value;
addObj.RoomId = eventTypeObj.current.value;
return addObj;
};
if ((e.target as HTMLElement).id === 'add') {
const addObj: { [key: string]: Object } = getSlotData();
scheduleObj.current.addEvent(addObj);
} else if ((e.target as HTMLElement).id === 'delete') {
const eventDetails: { [key: string]: Object } = scheduleObj.current.activeEventData.event as { [key: string]: Object };
let currentAction: CurrentAction = 'Delete';
if (eventDetails.RecurrenceRule) {
currentAction = 'DeleteOccurrence';
}
scheduleObj.current.deleteEvent(eventDetails, currentAction);
} else {
const isCellPopup: boolean = (quickPopup.firstElementChild as HTMLElement).classList.contains('e-cell-popup');
const eventDetails: { [key: string]: Object } = isCellPopup ? getSlotData() :
scheduleObj.current.activeEventData.event as { [key: string]: Object };
let currentAction: CurrentAction = isCellPopup ? 'Add' : 'Save';
if (eventDetails.RecurrenceRule) {
currentAction = 'EditOccurrence';
}
scheduleObj.current.openEditor(eventDetails, currentAction, true);
}
scheduleObj.current.closeQuickInfoPopup();
}
return (
<div className='schedule-control-section'>
<div className='col-lg-12 control-section'>
<div className='control-wrapper'>
<ScheduleComponent id="schedule" cssClass='quick-info-template' ref={scheduleObj} height="650px"
selectedDate={new Date(2020, 0, 9)} eventSettings={eventSettings} quickInfoTemplates={quickInfoTemplates}>
<ResourcesDirective>
<ResourceDirective field='RoomId' title='Room Type' name='MeetingRoom' textField='Name' idField='Id'
colorField='Color' dataSource={roomData}></ResourceDirective>
</ResourcesDirective>
<Inject services={[Day, Week, WorkWeek, Month, Agenda, MonthAgenda]} />
</ScheduleComponent>
</div>
</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/29.1.33/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-react-calendars/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-react-schedule/styles/material.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%;
}
</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>