Premium support for our pure JavaScript UI components


Post by gorakh.nath »

Hi,
Whenever I am dragging and dropping event from one technician to other or same technician to other time frame then event is jumping to previous position.
I am handing the beforeEventDropFinalize event and calling some dispatch action , after this dispatch actions page is re-rendering and the event is jumping to previous position.

           async beforeEventDropFinalize({ context }) {
             context.async = true;
             //showLoader();
             dragLoader();
             reduxActionDispatch(context);
             context.valid = true;
             context.finalize(true);
            }

reduxActionDispatch is the set of dispatch actions.If I will remove this then event will not jump and will stay in the place where we dropped it.

 <BryntumSchedulerPro
          ref={scheduler}
          minWidth='13.125rem'
          createEventOnDblClick={false}
          autoHeight={false}
          allowOverlap={isAllowOverlap}
          zoomOnMouseWheel={false}
          zoomOnTimeAxisDoubleClick={false}
          viewPreset={getViewPreset(timelineView,
            timelineHeader, timeResolution)}
          tbar={
            [
              {
                type: 'combo',
                value: timelineView,
                editable: false,
                ref: 'viewPresetCombo',
                cls: 'select-view',
                listCls: 'list-items',
                listeners: { change: viewPresetHandler },
                items: getTimeLineViewList(jsonDef)
              },
              {
                type: 'dateField',
                editable: false,
                cls: 'date-field',
                onChange ({ value, userAction }) {
                  if (hasSchedulerInstance() && userAction) {
                    clearSchedulerFilter();
                    limitMonthRange(value);
                    const diff = DateHelper.diff(
                      DateHelper.clearTime(getSchedulerInstance().startDate),
                      value,
                      'days'
                    );
                    const updatedStartDate = DateHelper.add(
                      getSchedulerInstance().startDate,
                      diff,
                      'days'
                    );
                    getSchedulerInstance().startDate = updatedStartDate;
                    getSchedulerInstance().scrollToDate(value, {
                      block: getViewPosition()
                    });
                    checkForDataFetch(false, updatedStartDate);
                  }
                },
                listeners: {
                  trigger: onDatePickerLoad
                },
                ref: 'selectDate'
              },
              {
                type: 'button',
                text: 'L{todayText}',
                onClick () {
                  const today = DateHelper.clearTime(new Date());
                  if (hasSchedulerInstance() && DateHelper.isValidDate(getSchedulerInstance().startDate) &&
                    !DateHelper.isEqual(today, getSchedulerInstance().startDate, 'days')) {
                    clearSchedulerFilter();
                    limitMonthRange(today);
                    getSchedulerInstance().startDate = today;
                    getSchedulerInstance().scrollToDate(DateHelper.set(today, 'hour', TWELVE),
                      { block: 'center', animate: 500 });
                    checkForDataFetch(false, today);
                  }
                },
                cls: 'btn-today'
              },
              {
                type: 'button',
                icon: 'b-fa-angle-left',
                cls: 'btn-prev',
                onClick () {
                  if (hasSchedulerInstance()) {
                    clearSchedulerFilter();
                    const preDate = getSchedulerInstance().startDate;
                    getSchedulerInstance().shiftPrevious();
                    if (DateHelper.isValidDate(getSchedulerInstance().startDate)) {
                      checkForDataFetch(true);
                    } else {
                      getSchedulerInstance().startDate = preDate;
                    }

              }
            }
          },
          {
            type: 'button',
            icon: 'b-fa-angle-right',
            cls: 'btn-next',
            onClick () {
              if (hasSchedulerInstance()) {
                clearSchedulerFilter();
                const preDate = getSchedulerInstance().startDate;
                getSchedulerInstance().shiftNext();
                if (DateHelper.isValidDate(getSchedulerInstance().startDate)) {
                  checkForDataFetch(true);
                } else {
                  getSchedulerInstance().startDate = preDate;
                }
              }
            }
          },
          '->',
          {
            type: 'textfield',
            ref: 'filterByName',
            placeholder: 'L{searchPlaceholder}',
            cls: 'input-search',
            clearable: true,
            keyStrokeChangeDelay: 100,
            triggers: {
              filter: {
                align: 'start',
                cls: 'b-fa b-fa-search'
              }
            },
            listeners: { change: searchHandler }
          }
        ]
      }
      project ={ {
        resourcesData: data.resources,
        eventsData: data.events,
        timeRangeStore: timeRangeStores,
        timeRangesData: data.timeRanges,
        resourceTimeRangeStore: resourceTimeRangeStore,
        calendar: 'Weekend',
        calendarsData: data.calendars,
        resourceTimeRangesData: data.resourceTimeRanges,
        eventModelClass: ParentEvent
      }}
      eventsVersion={eventsVersion.current}
      resourceTimeRangesFeature={true}
      resourceNonWorkingTimeFeature={true}
      nonWorkingTimeFeature={true}
      columns={schedulerColumns}
      filterBarFeature={true} // to enable search on columns
      listeners={{
        presetChange,
        eventClick: ({ eventRecord, eventElement, event }) => {
          debouncedCallback(onEventClick);
          function onEventClick() {
            showLoader();
            clearSchedulerFilter();
            eventRecord.data.elementType = TASK;
            const selectedResource = event?.resourceRecord?.originalData;
            setPageContext({ selectedResource: selectedResource });
            if (eventPopup?.close) eventPopup.close();
            openEventPopup(eventRecord, eventElement, event.x, event.y, TASK);
            //hideLoader();
          }
        },
        scheduleDblClick: ({ resourceRecord, tickStartDate,
          tickEndDate, event, eventElement }) => {
          if (isEmptyCellDefined) {
            showLoader();
            clearSchedulerFilter();
            const selectedResource = resourceRecord?.originalData;
            setPageContext({ selectedResource: selectedResource });
            onScheduleClick(
              resourceRecord, tickStartDate, tickEndDate, event, eventElement);
            hideLoader();
          }
        },

       async beforeEventDropFinalize({ context }) {
         context.async = true;
         //showLoader();
         dragLoader();
         onEventDropAction(context);
         context.valid = true;
         context.finalize(true);
        },
      }}
      eventStyle={'colored'}
      eventLayout={eventLayout || 'stack'}
      eventBodyTemplate={(data) => getEventTemplate(data)}
      eventRenderer={(eventRecord) => eventRenderer(eventRecord)}
      // disable contextmenu on right click of events
      eventMenuFeature={false}
      scheduleMenuFeature={false}
      timeAxisHeaderMenuFeature={false}
      eventEditFeature={{
        disabled: true // disable event edit popup on double click of events
      }}
      eventDragCreateFeature={{
        disabled: true // disable event creation on drag
      }} 
      eventDragFeature={{
        disabled: !jsonDef?.dragAllow,
        validatorFn ({ startDate }) {
          if (dayjs().isAfter(startDate, 'second')) {
            return {
              valid: false,
              message: DRAG_PAST_DATE_ERROR_MSG
            };
          }
          return {
            valid: true
          };
        }
      }}
      eventTooltipFeature={{
        template: (data) => debouncedCallback(getPopupContent,data?.eventRecord?.originalData )
      }}
      eventResizeFeature={{
        disabled: true
      }}
      stripeFeature={isStripFeature}
      timeRangesFeature={{
        showCurrentTimeLine: true,
        currentDateFormat: getLodash(jsonDef, 'currentDateFormat', 'HH:mm'),
        showHeaderElements: true,
        enableResizing: true
      }}
      dependenciesFeature={isEnableDependency}
    />

How I can avoid jumping of event to previous position on render.

Attachments
Screenshot 2022-06-23 at 4.11.21 PM.png
Screenshot 2022-06-23 at 4.11.21 PM.png (141.86 KiB) Viewed 331 times

Post by alex.l »

Please check the data you returned on your dispatch. That looks like data has been reverted.
Also, beforeEventDropFinalize method marked as async, as well as context.async, but code you wrote is sync. Maybe you need to add await for reduxActionDispatch call?
If no luck, we need a runnable test case to debug.

All the best,
Alex


Post by gorakh.nath »

thanks alex, I search in my code as you suggested and found that I am doing:-

 schedulerObj.resourceStore?.clearFilters();
 schedulerObj.widgetMap.filterByName.value = '';

and this code was causing it to reload the scheduler.
It is working after removing these lines.


Post Reply