different editor templates for different event types

I have two types of events on my scheduler. Booked events and not booked events. I want to display different editor templates for them like this

Screenshot 2022-02-28 121333.png

The editor template I want along with different header and footers are

Screenshot 2022-02-28 121757.png

The above is for the not booked event.

Screenshot 2022-02-28 121824.png

And this is for the not booked session.

How can I accomplish the same?


I am using React.js with functional components

This is my initial code

import React, { useRef } from 'react';
import { ScheduleComponent, Day, Week, Resize, DragAndDrop, Inject, ViewsDirective, ViewDirective, RecurrenceEditorComponent } from '@syncfusion/ej2-react-schedule';
import { DropDownListComponent } from '@syncfusion/ej2-react-dropdowns';
import { L10n } from '@syncfusion/ej2-base';
import { DateTimePickerComponent } from '@syncfusion/ej2-react-calendars';
import { useSelector } from 'react-redux';
import { createSchedule, deleteSchedule, updateSchedule } from '../../api/index';
import './ScheduleCalendar.scss';

L10n.load({
  'en-US': {
    schedule: {
      saveButton: 'Save',
      cancelButton: 'Cancel',
      deleteButton: 'Remove',
      newEvent: 'Add Time Slot',
      editEvent: 'Update Time Slot',
      deleteEvent: 'Delete Time Slot',
    },
  },
});

function ScheduleCalendar() {
  const scheduleObj = useRef();
  const recurrenceObj = useRef();
  const { schedules } = useSelector((state) => state.schedules);
  const user = JSON.parse(localStorage.getItem('profile'))?.user;

  const onActionBegin = (args) => {
    if (args.requestType === 'eventCreate') {
      createSchedule({
        startTime: args.data[0].startTime.toISOString(),
        endTime: args.data[0].endTime.toISOString(),
        sessionType: args.data[0].sessionType,
        mhp: user.id,
      });
    } else if (args.requestType === 'eventChange') {
      if (args.data.isBooked) {
        // eslint-disable-next-line
        args.cancel = true;
      } else {
        updateSchedule(args.data.id, {
          startTime: args.data.startTime.toISOString(),
          endTime: args.data.endTime.toISOString(),
          sessionType: args.data.sessionType,
        });
      }
    } else if (args.requestType === 'eventRemove') {
      if (args.data.isBooked) {
        // eslint-disable-next-line
        args.cancel = true;
      } else {
        deleteSchedule(args.data[0].id);
      }
    }
  };

  const eventTemplate = (props) => {
    if (props.sessionType === 'Therapy Session') {
      if (props.isBooked) {
        return (
          <div className="schedulePage__schedulerEvent" style={{ background: '#AB70CA' }}>
            <div>Booked</div>
          </div>
        );
      }
      return (
        <div className="schedulePage__schedulerEvent" style={{ background: '#AB70CA' }} />
      );
    }
    return (
      <div className="schedulePage__schedulerEvent" style={{ background: '#FA8A8A' }} />
    );
  };

  const onSessionTypeChange = (args) => {
    if (args.itemData !== null) {
      const startObj = document.querySelector('#startTime').ej2_instances[0];
      const endObj = document.querySelector('#endTime').ej2_instances[0];
      if (args.itemData.value === 'Consultation Call') {
        endObj.value = new Date(startObj.value.getTime() + 15 * 60000);
      } else {
        endObj.value = new Date(startObj.value.getTime() + user.sessionDuration * 60000);
      }
    }
  };

  const onStartTimeChange = (args) => {
    const sessionObj = document.querySelector('#sessionType').ej2_instances[0];
    const endObj = document.querySelector('#endTime').ej2_instances[0];
    if (sessionObj.value === 'Consultation Call') {
      endObj.value = new Date(args.value.getTime() + 15 * 60000);
    } else {
      endObj.value = new Date(args.value.getTime() + user.sessionDuration * 60000);
    }
  };

  const editorTemplate = (props) => {
    return (props !== undefined ? (
      <table className="custom-event-editor" style={{ width: '100%', cellpadding: '5' }}>
        <tbody>
          <tr>
            <td className="e-textlabel">Session Type</td>
            <td className="custom-dropdown" colSpan={4}>
              <DropDownListComponent
                id="sessionType"
                placeholder="Session Type"
                data-name="sessionType"
                className="e-field"
                style={{ width: '100%' }}
                dataSource={[
                  { text: 'Therapy Session', value: 'Therapy Session' },
                  { text: 'Consultation Call', value: 'Consultation Call' },
                ]}
                fields={{ text: 'text', value: 'value' }}
                value={props.sessionType || 'null'}
                change={onSessionTypeChange}
              />
            </td>
          </tr>
          <tr>
            <td className="e-textlabel">Start Time</td>
            <td colSpan={4}>
              <DateTimePickerComponent
                format="dd/MM/yy hh:mm a"
                step={user.sessionDuration}
                id="startTime"
                data-name="startTime"
                value={new Date(props.startTime || props.StartTime)}
                className="e-field"
                change={onStartTimeChange}
              />
            </td>
          </tr>
          <tr>
            <td className="e-textlabel">End Time</td>
            <td colSpan={4}>
              <DateTimePickerComponent
                format="dd/MM/yy hh:mm a"
                step={user.sessionDuration}
                id="endTime"
                data-name="endTime"
                value={new Date(props.endTime || props.EndTime)}
                className="e-field"
              />
            </td>
          </tr>
          <tr>
            <td className="e-textlabel">Recurrence</td>
            <td colSpan={4}>
              <RecurrenceEditorComponent ref={recurrenceObj} id="RecurrenceEditor" />
            </td>

          </tr>
        </tbody>
      </table>
    ) : <div />);
  };

  const onPopupOpen = (args) => {
    if (args.data.isBooked) {
      // eslint-disable-next-line
      args.cancel = true;
    } else if (args.type === 'Editor') {
      scheduleObj.current.eventWindow.recurrenceEditor = recurrenceObj.current;
      const statusElement = args.element.querySelector('#sessionType');
      statusElement.setAttribute('name', 'sessionType');
      const sessionObj = document.querySelector('#sessionType').ej2_instances[0];
      sessionObj.value = args.data.sessionType ? args.data.sessionType : 'Therapy Session';
      const endObj = document.querySelector('#endTime').ej2_instances[0];
      endObj.value = args.data.endTime ? args.data.endTime : new Date(endObj.value.getTime() + (user.sessionDuration - 30) * 60000);
    }
  };

  const onCellClick = (args) => {
    scheduleObj.current.openEditor(args, 'Add');
  };

  const onEventClick = (args) => {
    if (!args.event.RecurrenceRule) {
      scheduleObj.current.openEditor(args.event, 'Save');
    } else {
      scheduleObj.current.quickPopup.openRecurrenceAlert();
    }
  };

  return (
    <ScheduleComponent
      ref={scheduleObj}
      showQuickInfo={false}
      eventClick={onEventClick}
      cellClick={onCellClick}
      eventSettings={{
        dataSource: schedules,
        template: eventTemplate,
        fields: {
          id: 'id',
          isBooked: 'isBooked',
          sessionType: { name: 'sessionType', validation: { required: true } },
          startTime: { name: 'startTime', validation: { required: true } },
          endTime: { name: 'endTime', validation: { required: true } },
        },
      }}
      popupOpen={onPopupOpen}
      actionBegin={onActionBegin}
      editorTemplate={editorTemplate}
      className="schedulePage__scheduler"
      width="100%"
      height="75vh"
      selectedDate={new Date()}
      enablePersistence
    >
      <ViewsDirective>
        <ViewDirective option="Week" />
        <ViewDirective option="Day" />
      </ViewsDirective>
      <Inject services={[Day, Week, Resize, DragAndDrop]} />
    </ScheduleComponent>
  );
}

export default ScheduleCalendar;



6 Replies 1 reply marked as answer

MS Mansi Sharma March 1, 2022 12:47 AM UTC

Basically, I want to show this modal if the session is booked.




BS Balasubramanian Sattanathan Syncfusion Team March 2, 2022 02:14 PM UTC

You can have a different editor window based on the appointment type by using the below code snippet.

Code snippet:

editorTemplate(props) {

  return ((props !== undefined) ? <EditorContent currentType={props} /> : <div></div>);

}
. . .

. . .

class EditorContent extends React.Component {

  constructor() {

    super(...arguments);

    this.instance = new Internationalization();

  }

  getTimeString(value) {

    return this.instance.formatDate(value, { skeleton: 'hm' });

  }

  render() {

    return (

      (this.props.currentType.EventType != "Booked") ? <table className="custom-event-editor" style={{ width: '100%', cellpadding: '5' }}><tbody>

        <tr><td className="e-textlabel">Summary</td><td style={{ colspan: '4' }}>

          <input id="Summary" className="e-field e-input" type="text" name="Subject" style={{ width: '100%' }} />

        </td></tr>

        <tr><td className="e-textlabel">Reason</td><td style={{ colspan: '4' }}>

          <textarea id="Description" className="e-field e-input" name="Description" rows={3} cols={50} style={{ width: '100%', height: '60px !important', resize: 'vertical' }}></textarea>

        </td></tr></tbody></table> :

        <div>

          <div>

            {

              (this.props.currentType.Subject !== undefined) ?

                <div>{this.props.currentType.Subject}</div> : ""

            }

            {

              (this.props.currentType.StartTime !== undefined) ?

                <div>{this.getTimeString(this.props.currentType.StartTime)}</div> : ""

            }

            {

              (this.props.currentType.EndTime !== undefined) ?

                <div >{this.getTimeString(this.props.currentType.EndTime)}</div> : ""

            }

          </div>

        </div>

    )

  }

}


Sample: https://stackblitz.com/edit/react-schedule-editor-template-numeric-textbox-8dmgjt?file=index.js

Kindly try the above solution and let us know if this is helpful



MS Mansi Sharma March 2, 2022 03:25 PM UTC

This would work if I don't want to change the footer button but as you can see in the screenshots I provided, 

Screenshot 2022-02-28 121757.png


There are different buttons in the footer too. So how can I achieve that since the button of booked session needs to perform a different action too.



BS Balasubramanian Sattanathan Syncfusion Team March 3, 2022 03:13 PM UTC

As we mentioned in our last reply. You can have a different editor window based on the appointment type by using the below code snippet. Here you need to form the editor window on your own and use it in the below-highlighted code.

The Skyblue color code will open the editor window for the not-booked appointment type. Here you can use the custom editor window as same as your screenshot
The green color code will open the editor window for booked appointment type. Here you can use the custom editor window only having the Appointment details as same as your screenshot.

Code snippet:

editorTemplate(props) {

  return ((props !== undefined) ? <EditorContent currentType={props} /> : <div></div>);

}
. . .

. . .

class EditorContent extends React.Component {

  constructor() {

    super(...arguments);

    this.instance = new Internationalization();

  }

  getTimeString(value) {

    return this.instance.formatDate(value, { skeleton: 'hm' });

  }

  render() {

    return (

      (this.props.currentType.EventType != "Booked") ? <table className="custom-event-editor" style={{ width: '100%', cellpadding: '5' }}><tbody>

        <tr><td className="e-textlabel">Summary</td><td style={{ colspan: '4' }}>

          <input id="Summary" className="e-field e-input" type="text" name="Subject" style={{ width: '100%' }} />

        </td></tr>

        <tr><td className="e-textlabel">Reason</td><td style={{ colspan: '4' }}>

          <textarea id="Description" className="e-field e-input" name="Description" rows={3} cols={50} style={{ width: '100%', height: '60px !important', resize: 'vertical' }}></textarea>

        </td></tr></tbody></table> :

        <div>

          <div>

            {

              (this.props.currentType.Subject !== undefined) ?

                <div>{this.props.currentType.Subject}</div> : ""

            }

            {

              (this.props.currentType.StartTime !== undefined) ?

                <div>{this.getTimeString(this.props.currentType.StartTime)}</div> : ""

            }

            {

              (this.props.currentType.EndTime !== undefined) ?

                <div >{this.getTimeString(this.props.currentType.EndTime)}</div> : ""

            }

          </div>

        </div>

    )

  }

}


Kindly follow the above solution and change the editor template codes based on your requirement. Let us know if you need further assistance.



MS Mansi Sharma March 3, 2022 10:47 PM UTC

As per the solution you provided,

This is the editorTemplate for booked event



And this is the template for not booked event



And what I actually want is along with the content (that has changed according to event type) I also want the header and footer of the modal to be changed as you can see I have marked. That is my main que



BS Balasubramanian Sattanathan Syncfusion Team March 9, 2022 08:04 PM UTC

Please find the below sample to have different footer buttons.

https://stackblitz.com/edit/react-schedule-editor-template-numeric-textbox-w1xkow?file=index.js


Marked as answer
Loader.
Up arrow icon