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

Validator returning undefined while adding required field to dropDownListComponent in custom Editor Window

I am using a custom editor template for the editor window. There is a dropDownListComponent there, which I want to be a required field. So I'm using the validator in the onPopupOpen function to make it a required field but it is returning undefined. Here is my code.

import React, { useRef } from 'react';
import { ScheduleComponent, Day, Week, Resize, DragAndDrop, Inject, ViewsDirective, ViewDirective } 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 { useDispatch, useSelector } from 'react-redux';
import { createSchedule, deleteMhpSchedule, updateSchedule } from '../../actions/schedule';
import './ScheduleCalendar.scss';

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

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

  const onActionBegin = (args) => {
    if (args.requestType === 'eventCreate') {
      dispatch(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') {
      dispatch(updateSchedule(args.data.id, {
        startTime: args.data.startTime.toISOString(),
        endTime: args.data.endTime.toISOString(),
        sessionType: args.data.sessionType,
      }));
    } else if (args.requestType === 'eventRemove') {
      dispatch(deleteMhpSchedule(args.data[0].id));
    }
  };

  const eventTemplate = (props) => {
    if (props.sessionType === 'regular') {
      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 === 'free-call') {
        endObj.value = new Date(startObj.value.getTime() + 15 * 60000);
      } else {
        endObj.value = new Date(startObj.value.getTime() + 60 * 60000);
      }
    }
  };

  const onStartTimeChange = (args) => {
    const sessionObj = document.querySelector('#sessionType').ej2_instances[0];
    const endObj = document.querySelector('#endTime').ej2_instances[0];
    if (sessionObj.value === 'free-call') {
      endObj.value = new Date(args.value.getTime() + 15 * 60000);
    } else {
      endObj.value = new Date(args.value.getTime() + 60 * 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"
                required
                placeholder="Session Type"
                data-name="sessionType"
                className="e-field"
                style={{ width: '100%' }}
                dataSource={[
                  { text: 'Therapy Session', value: 'regular' },
                  { text: 'Consultation Call', value: 'free-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={60}
                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={60}
                id="endTime"
                data-name="endTime"
                value={new Date(props.endTime || props.EndTime)}
                className="e-field"
              />
            </td>
          </tr>
        </tbody>
      </table>
    ) : <div />);
  };

  const onPopupOpen = (args) => {
    if (args.type === 'Editor') {
      const statusElement = args.element.querySelector('#sessionType');
      statusElement.setAttribute('name', 'sessionType');
      const formElement = args.element.querySelector('.e-schedule-form');
      const validator = (formElement).ej2_instances[0];
      validator.addRules('sessionType', { required: true });
      const endObj = document.querySelector('#endTime').ej2_instances[0];
      endObj.value = new Date(endObj.value.getTime() + 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',
          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="73vh"
      selectedDate={new Date()}
      enablePersistence
    >
      <ViewsDirective>
        <ViewDirective option="Week" />
        <ViewDirective option="Day" />
      </ViewsDirective>
      <Inject services={[Day, Week, Resize, DragAndDrop]} />
    </ScheduleComponent>
  );
}

export default ScheduleCalendar;

And the screenshot of the error.


Please look into this and please tell me if you have a solution for the same.


6 Replies

SK Satheesh Kumar Balasubramanian Syncfusion Team February 17, 2022 12:28 PM UTC

Hi Mansi, 
  
We have prepared sample to reproduce the reported issue based on the shared details. But, editor window is open properly without the reported error. 
  
  
Could you please share the below details to reproduce the issue? This will help to validate the issue and provide prompt solution at earliest.  
  • Whether we have missed to include anything in the above shared sample?
  • Replicate the issue in above sample (or) share issue replicating sample if possible
  • Share package version details

Regards, 
Satheesh Kumar B 



MS Mansi Sharma February 18, 2022 10:19 PM UTC

The main issue is arising when I'm using these two lines in the code I gave.


const formElement = args.element.querySelector('.e-schedule-form');
const validator = (formElement).ej2_instances[0];

That is when validating. The sample you provided is working okay but mine is the same still it is giving an error.
These are the versions I'm using: 

"@syncfusion/ej2-base": "^19.4.48",
    "@syncfusion/ej2-react-calendars": "^19.4.50",
    "@syncfusion/ej2-react-dropdowns": "^19.4.50",
    "@syncfusion/ej2-react-schedule": "^19.4.50",


SK Satheesh Kumar Balasubramanian Syncfusion Team February 21, 2022 02:53 PM UTC

Hi Mansi,  
   
We have modified the sample to reproduce the reported issue based on the shared details. But, editor window is open properly without the reported error.  
   
Could you please share the below details to reproduce the issue? This will help to validate the issue and provide prompt solution at earliest.   
  • Replicate the issue in above sample (or) share issue replicating sample if possible
  • Share issue depicting video
Regards,  
Satheesh Kumar B 



MO Mohanad June 25, 2022 02:10 AM UTC

Hello, I'm facing the same issue as the above, however I managed to narrow down the cause

async componentDidMount() {
const { data } = await axios.get(
"/timeslot/counselor/" + this.state.selected
);
// .catch(function (error) {
// console.log(error);
// });
this.setState({ timeslots: data });
// const response = await axios.get("/user/counselor").catch(function (error) {
// console.log(error);
// });
// this.setState({ counselors: response.data });
}


If I comment out the this.setState the error no longer appears when calling ej2_instances, it could be any setState. I'm not sure if this is exclusive to setState in componentDidMount or not but it seems to be the case.


EDIT:

I was able to reproduce the error in your own stackblitz by using setState in useEffect.

https://stackblitz.com/edit/react-schedule-editor-template-field-validation-ev9daa?file=index.js

Now if you try to open the editor it gives out the mentioned error.



RV Ravikumar Venkatesan Syncfusion Team June 29, 2022 02:57 PM UTC

Hi Mohanad,


We have validated your reported issue at our end and confirmed this as a bug and logged the defect report "Form validator instance not available in the popupOpen event of the Schedule" which can be tracked from the following link.


https://www.syncfusion.com/feedback/36015/form-validator-instance-not-available-in-the-popupopen-event-of-the-schedule


The fix for this defect will be included in our upcoming patch release which is expected to be rolled out by the mid of July 2022. We would appreciate your valuable patience until then.


Kindly let us know if you need any further assistance.


Regards,

Ravikumar Venkatesan



SK Satheesh Kumar Balasubramanian Syncfusion Team July 13, 2022 11:28 AM UTC

Hi Mohanad,


Thanks for being patience.


We are glad to announce that our weekly patch release v20.2.38 has been rolled out successfully. In this release, an issue with Form validator instance not available in popupOpen event of Scheduler has been fixed. As a result, we recommend you upgrade to the latest version of our Syncfusion package to avail of those changes.


Kindly check the reported defect in the latest version and get back to us if you need any further assistance.


Regards,

Satheesh Kumar B



Loader.
Up arrow icon