We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

Custom Editor Template not added to dates

Hello, I've been working on creating an appointment system via the scheduler. The examples have been helpful but I've come to a dead end. I can't seem to be able to add an event to any date or time when using a editorTemplate.


Here's the code​​


import * as React from "react";
import { ScheduleComponent, ResourcesDirective, ResourceDirective, ViewsDirective, ViewDirective, Inject, TimelineViews, Resize, DragAndDrop, TimelineMonth, Agenda, Day, Week, RecurrenceEditorComponent } from "@syncfusion/ej2-react-schedule";
import "../../assets/css/external-drag-drop.css";
import { extend, closest, remove, addClass } from "@syncfusion/ej2-base";
import { TreeViewComponent } from "@syncfusion/ej2-react-navigations";
import dataSource from "./datasource.json";
import { DateTimePickerComponent } from "@syncfusion/ej2-react-calendars";

import Loading from "../components/Loading.js";
import { useState } from "react";
import { useSelector } from "react-redux";
import { useEffect } from "react";
import { Avatar } from "@mui/material";
import DateTimePicker from "react-datetime-picker";

// const waitingList = [
// {
// "Id": 1,
// "Name": "Steven",
// "StartTime": "2021-09-04T02:00:00.000Z",
// "EndTime": "2021-09-04T04:00:00.000Z",
// "Description": "Consulting",
// "DepartmentName": "GENERAL"
// },
// {
// "Id": 2,
// "Name": "Milan",
// "StartTime": "2021-09-05T03:00:00.000Z",
// "EndTime": "2021-09-05T05:00:00.000Z",
// "Description": "Bad Breath",
// "DepartmentName": "DENTAL"
// },
// ];

let hospitalData = [
{
Id: 10,
Name: "David",
StartTime: "2022-12-20T03:30:00.000Z",
EndTime: "2022-12-20T04:30:00.000Z",
Description: "Health Checkup",
DepartmentID: 1,
ConsultantID: 1,
DepartmentName: "GENERAL",
},
{
Id: 11,
Name: "John",
StartTime: "2022-12-20T05:00:00.000Z",
EndTime: "2022-12-20T06:00:00.000Z",
Description: "Tooth Erosion",
DepartmentID: 2,
ConsultantID: 2,
DepartmentName: "DENTAL",
},
];

function Calender() {
const [isLoading, setIsLoading] = useState(true);
const [teams, setTeams] = useState(undefined);
const [workOrders, setWorkOrders] = useState(undefined);

const teamsData = useSelector((state) => state.teamReducer.leader_teams.data);
const workOrdersData = useSelector((state) => state.workOrderReducer.workOrders.data);

let scheduleObj;
let treeObj;
let isTreeItemDropped = false;
let draggedItemId = "";
const allowDragAndDrops = true;
// const fields = { dataSource: waitingList, id: 'Id', text: 'Name' };
const [assignedData, setAssignedData] = useState(undefined);
// const departmentData = [
// { Text: 'GENERAL', Id: 1, Color: '#bbdc00' },
// { Text: 'DENTAL', Id: 2, Color: '#9e5fff' }
// ];
const consultantData = [
{ Text: "Alice", Id: 1, GroupId: 1, Color: "#bbdc00", Designation: "Cardiologist" },
{ Text: "Nancy", Id: 2, GroupId: 2, Color: "#9e5fff", Designation: "Orthodontist" },
{ Text: "Robert", Id: 3, GroupId: 1, Color: "#bbdc00", Designation: "Optometrist" },
{ Text: "Robson", Id: 4, GroupId: 2, Color: "#9e5fff", Designation: "Periodontist" },
{ Text: "Laura", Id: 5, GroupId: 1, Color: "#bbdc00", Designation: "Orthopedic" },
{ Text: "Margaret", Id: 6, GroupId: 2, Color: "#9e5fff", Designation: "Endodontist" },
];

useEffect(() => {
if (teamsData && workOrdersData && setAssignedData) {
let tempTeams = [];
teamsData.map((team) => {
// console.log("team.team");
// console.log(team.team);
tempTeams.push({
Id: team?.leader?.id,
TeamId: team?.id,
teamName: team?.team?.name,
leaderName: team?.leader?.name,
picture: team?.leader?.picture,
});
});
setTeams(tempTeams);

let tempWorkOrders = [];
workOrdersData.map((workOrder) => {
// console.log("workOrder");
// console.log(workOrder);
tempWorkOrders.push({
Id: workOrder.workOrder.id,
Task: workOrder.location.name + ", " + workOrder.service.name + ", " + workOrder.module.name,
CustomerEmail: workOrder.request.customer_email,
Details: workOrder.request_entity.description,
Repeat: workOrder.request_entity.schedule_frequency,
});
});

setWorkOrders(tempWorkOrders);

setAssignedData(extend([], dataSource.hospitalData, null, true));

setIsLoading(false);
}
}, [teamsData, workOrdersData]);

function getTeamName(value) {
return value.resourceData.teamName;
}
function getTeamLeaderImage(value) {
if (value.resourceData.picture) {
return value.resourceData.picture;
}
}
function getTeamLeaderName(value) {
if (value.resourceData.leaderName) {
return value.resourceData.leaderName;
} else {
return "NO LEADER";
}
}

function resourceHeaderTemplate(props) {
return (
<div className="template-wrap">
<div className="specialist-category">
<Avatar className="specialist-image" src={getTeamLeaderImage(props)} />
<div className="specialist-name">{getTeamName(props)}</div>
<div className="specialist-designation">{getTeamLeaderName(props)}</div>
</div>
</div>
);
}

function treeTemplate(props) {
console.log("treeTemplate");
// console.log(props)
return (
<div id="waiting">
<div id="waitdetails">
<div id="waitlist">{props.Task}</div>
<div id="waitcategory">{props.CustomerEmail}</div>
</div>
</div>
);
}
function onItemDrag(event) {
console.log("onItemDrag");
if (scheduleObj.isAdaptive) {
let classElement = scheduleObj.element.querySelector(".e-device-hover");
if (classElement) {
classElement.classList.remove("e-device-hover");
}
if (event.event.target.classList.contains("e-work-cells")) {
addClass([event.event.target], "e-device-hover");
}
}
if (document.body.style.cursor === "not-allowed") {
document.body.style.cursor = "";
}
if (event.name === "nodeDragging") {
let dragElementIcon = document.querySelectorAll(".e-drag-item.treeview-external-drag .e-icon-expandable");
for (let i = 0; i < dragElementIcon.length; i++) {
dragElementIcon[i].style.display = "none";
}
}
}
function onActionBegin(event) {
if (event.requestType === "eventCreate" && isTreeItemDropped) {
let treeViewData = treeObj.fields.dataSource;

console.log('treeViewData');
console.log(treeViewData);

const filteredPeople = treeViewData.filter((item) => item.Id !== parseInt(draggedItemId, 10));

console.log('filteredPeople');
console.log(filteredPeople);

treeObj.fields.dataSource = filteredPeople;
let elements = document.querySelectorAll(".e-drag-item.treeview-external-drag");

console.log('elements')
console.log(elements)
for (let i = 0; i < elements.length; i++) {
remove(elements[i]);
}
}
}

const onPopupOpen = (args) => {
// alert('pipup')
console.log("pipup");
console.log(args);
// if (args.type === 'Editor') {
// scheduleObj.eventWindow.recurrenceEditor = recurrObject;
// }
};

const editorTemplate = (props) => {
// console.log("props");
// console.log(props);

return props !== undefined ? (
<table className="custom-event-editor" style={{ width: "100%", cellpadding: "5", height: "600px" }}>
<tbody>
<tr>
<td className="e-textlabel">Title</td>
<td colSpan={4}>
<input disabled value={props.title} data-name="Title" id="title" className="e-field e-input" type="text" name="Title" style={{ width: "100%" }} />
</td>
</tr>
<tr>
<td className="e-textlabel">Customer Email</td>
<td colSpan={4}>
<input disabled value={props.customerEmail} data-name="customerEmail" id="customerEmail" className="e-field e-input" type="text" name="Customer Email" style={{ width: "100%" }} />
</td>
</tr>
<tr>
<td className="e-textlabel">Selected Team</td>
<td colSpan={4}>
<input disabled value={props.teamName} data-name="teamName" id="teamName" className="e-field e-input" type="text" name="Selected Team" style={{ width: "100%" }} />
</td>
</tr>
<tr>
<td className="e-textlabel">From</td>
<td colSpan={4}>
<DateTimePickerComponent enabled={false} format="dd/MM/yy hh:mm a" id="StartTime" data-name="StartTime" value={new Date(props.startTime || props.StartTime)} className="e-field"></DateTimePickerComponent>
</td>
</tr>
<tr>
<td className="e-textlabel">To</td>
<td colSpan={4}>
<DateTimePickerComponent format="dd/MM/yy hh:mm a" id="EndTime" data-name="EndTime" value={new Date(props.endTime || props.EndTime)} className="e-field"></DateTimePickerComponent>
</td>
</tr>
<tr>
<td className="e-textlabel">Schedule</td>
<td colSpan={4}>
<RecurrenceEditorComponent data-name="repeatE" disabled={"true"} value={"FREQ=DAILY;INTERVAL=" + props.repeatEvery} frequencies={["daily"]} id="RecurrenceEditor"></RecurrenceEditorComponent>
</td>
</tr>
<tr>
<td className="e-textlabel">Details</td>
<td colSpan={4}>
<textarea value={props.details} data-name="Details" id="Details" className="e-field e-input" name="Details" rows={4} cols={50} style={{ width: "100%", height: "50px !important", resize: "vertical" }}></textarea>
</td>
</tr>

<input hidden disabled value={props.workOrderId} data-name="workOrderId" id="workOrderId" className="e-field e-input" type="text" name="workOrderId" style={{ width: "100%" }} />
<input hidden disabled value={props.teamId} data-name="teamId" id="teamId" className="e-field e-input" type="text" name="teamId" style={{ width: "100%" }} />
</tbody>
</table>
) : (
<div></div>
);
};

function onTreeDragStop(event) {
let treeElement = closest(event.target, ".e-treeview");
let classElement = scheduleObj.element.querySelector(".e-device-hover");
if (classElement) {
classElement.classList.remove("e-device-hover");
}
if (!treeElement) {
event.cancel = true;
let scheduleElement = closest(event.target, ".e-content-wrap");
if (scheduleElement) {
let treeviewData = treeObj.fields.dataSource;
if (event.target.classList.contains("e-work-cells")) {
const filteredData = treeviewData.filter((item) => item.Id === parseInt(event.draggedNodeData.id, 10));
// console.log("filteredData");
// console.log(filteredData);

let cellData = scheduleObj.getCellDetails(event.target);
// console.log("cellData");
// console.log(cellData);

let resourceDetails = scheduleObj.getResourcesByIndex(cellData.groupIndex);

// console.log('resourceDetails')
// console.log(resourceDetails)
// let eventData = {
// Task: filteredData[0].Task,
// StartTime: cellData.startTime,
// EndTime: cellData.endTime,
// IsAllDay: cellData.isAllDay,
// Details: filteredData[0].Details,
// ABC: '123',

// // DepartmentID: resourceDetails.resourceData.GroupId,
// ConsultantID: resourceDetails.resourceData.Id,
// };
let eventData = {
title: filteredData[0].Task,
StartTime: cellData.startTime,
EndTime: cellData.endTime,
// IsAllDay: cellData.isAllDay,
IsAllDay: false,
customerEmail: filteredData[0].CustomerEmail,
workOrderId: filteredData[0].Id,
teamId: resourceDetails.resourceData.Id,
teamName: resourceDetails.resourceData.teamName,
details: filteredData[0].Details,
repeatEvery: filteredData[0].Repeat,
ConsultantID: 2,
};
scheduleObj.openEditor(eventData, "Add", true);
isTreeItemDropped = true;
draggedItemId = event.draggedNodeData.id;
}
}
}
}
return (
<Loading isLoading={isLoading}>
<div className="schedule-control-section">
<div className="col-lg-12 control-section">
<div className="control-wrapper drag-sample-wrapper">
<div className="schedule-container">
<div className="title-container">
<h1 className="title-text">Work Order Assignment</h1>
</div>
<ScheduleComponent
ref={(schedule) => (scheduleObj = schedule)}
cssClass="schedule-drag-drop"
width="100%"
height="650px"
selectedDate={new Date()}
currentView="Day"
resourceHeaderTemplate={resourceHeaderTemplate.bind(this)}
eventSettings={{
dataSource: assignedData,
fields: {
id: { title: "ID", name: "Id" },
subject: { title: "Task", name: "Task" },
startTime: { title: "From", name: "StartTime" },
endTime: { title: "To", name: "EndTime" },
description: { title: "Details", name: "Details" },
isAllDay: false,
},
timezone: false,
}}
editorTemplate={editorTemplate.bind(this)}
group={{ enableCompactView: true, resources: ["Consultants"] }}
actionBegin={onActionBegin.bind(this)}
drag={onItemDrag.bind(this)}
>
<ResourcesDirective>
{/* <ResourceDirective field='DepartmentID' title='Department' name='Departments' allowMultiple={false} dataSource={departmentData} textField='Text' idField='Id' colorField='Color'>
</ResourceDirective> */}
<ResourceDirective field="ConsultantID" title="Consultant" name="Consultants" allowMultiple={false} dataSource={teams} textField="teamName" idField="Id" colorField="Color"></ResourceDirective>
</ResourcesDirective>
<ViewsDirective>
{/* <ViewDirective option='TimelineDay' /> */}
<ViewDirective option="TimelineMonth" />
{/* <ViewDirective option='Agenda' /> */}
<ViewDirective option="Week" />
<ViewDirective option="Day" />
</ViewsDirective>
<Inject services={[TimelineViews, TimelineMonth, Resize, DragAndDrop, Agenda, Week, Day]} />
</ScheduleComponent>
</div>
<div className="treeview-container">
<div className="title-container">
<h1 className="title-text">Waiting List</h1>
</div>
<TreeViewComponent ref={(tree) => (treeObj = tree)} cssClass="treeview-external-drag" dragArea=".drag-sample-wrapper" nodeTemplate={treeTemplate.bind(this)} fields={{ dataSource: workOrders, id: "Id", text: "Name" }} nodeDragStop={onTreeDragStop.bind(this)} nodeDragging={onItemDrag.bind(this)} allowDragAndDrop={allowDragAndDrops} />
</div>
</div>
</div>
</div>
</Loading>
);
}
export default Calender;


I think I'm maybe mapping the values incorrectly? What do you think?


4 Replies 1 reply marked as answer

SR Swathi Ravi Syncfusion Team December 21, 2022 07:16 AM UTC

Hi Ismail,


You can resolve this problem by adding the resource fields in the editorTemplate as shown in the below snippet. Since you are using the Schedule with resources, so it’s mandatory to add a resource field value to the appointment. The added appointment is not rendered on the Schedule since you didn’t add the resource field in the editorTemplate.


Sample: https://stackblitz.com/edit/ej2-react-schedule-editor-template-with-resources-bytxhw?file=index.js

UG: https://ej2.syncfusion.com/react/documentation/schedule/editor-template/#how-to-add-resource-options-within-editor-template


[index.js]

 const field = { text: 'Text'value: 'Id' }

 function editorTemplate(props) {

       return props !== undefined ? (

            <table className="custom-event-editor" style={width: "100%"cellpadding: "5"height: "600px" }}>

                  <tbody>

                           <tr><td className="e-textlabel">Department</td><td colSpan={4}>

                                    <DropDownListComponent className="e-field" placeholder='Choose Department' data-name="DepartmentID" dataSource={departmentData} fields={field} value={props.DepartmentID} />

                           </td></tr>

                            <tr><td className="e-textlabel">Consultant</td><td colSpan={4}>

                                     <DropDownListComponent className="e-field" placeholder='Choose Consultant' data-name="ConsultantID" dataSource={consultantData} fields={field} value={props.ConsultantID} />

                            </td></tr>

                  </tbody>

             </table>

        ) : (

            <div></div>

        );

 };


Regards,

Swathi Ravi


Marked as answer

IS Ismail replied to Swathi Ravi December 21, 2022 10:06 AM UTC

Hmm, okay good to know but that's not my problem. I'm not using Dropdowns so I shouldn't have to set any resources, right?



IS Ismail December 21, 2022 11:03 AM UTC

Oh wait, it worked! I've been trying this for a few days now, tysm! <3



RV Ravikumar Venkatesan Syncfusion Team December 22, 2022 03:17 PM UTC

You're welcome! Please get back to us if you need any further assistance.


Loader.
Up arrow icon