diff --git a/e2e/testcafe-devextreme/tests/scheduler/dragAndDrop/T1263508.ts b/e2e/testcafe-devextreme/tests/scheduler/dragAndDrop/T1263508.ts
new file mode 100644
index 000000000000..3dc1a4868bd2
--- /dev/null
+++ b/e2e/testcafe-devextreme/tests/scheduler/dragAndDrop/T1263508.ts
@@ -0,0 +1,97 @@
+import Scheduler from 'devextreme-testcafe-models/scheduler';
+import { ClientFunction, Selector } from 'testcafe';
+import { MouseAction, MouseUpEvents } from '../../../helpers/mouseUpEvents';
+import { createWidget } from '../../../helpers/createWidget';
+import url from '../../../helpers/getPageUrl';
+
+fixture.disablePageReloads`Scheduler Drag-and-Drop Fix`
+ .page(url(__dirname, '../../container.html'));
+
+const DRAGGABLE_ITEM_CLASS = 'dx-card';
+const draggingGroupName = 'appointmentsGroup';
+
+const initList = ClientFunction(() => {
+ $('
', { id: 'list' }).appendTo('#parentContainer');
+});
+
+const addTasksToList = ClientFunction((tasks) => {
+ tasks.forEach((task) => {
+ $('
', {
+ class: 'dx-card',
+ text: task.text,
+ }).appendTo('#list');
+ });
+});
+
+const createItemElement = async (task) => {
+ await createWidget('dxDraggable', {
+ group: draggingGroupName,
+ data: task,
+ clone: true,
+ onDragStart(e) {
+ e.itemData = e.fromData;
+ },
+ }, `.${DRAGGABLE_ITEM_CLASS}:contains(${task.text})`);
+};
+
+test('Scheduler - The \'Cannot read properties of undefined (reading \'getTime\')\' error is thrown on an attempt to drag an outside element if the previous drag operation was canceled', async (t) => {
+ const scheduler = new Scheduler('#container');
+ const draggableAppointment = scheduler.getAppointment('Book').element;
+ const targetCell = scheduler.getDateTableCell(5, 0);
+ const draggableItem = Selector(`.${DRAGGABLE_ITEM_CLASS}`).withText('Brochures');
+
+ await t.expect(scheduler.element.exists).ok();
+
+ await MouseUpEvents.disable(MouseAction.dragToElement);
+
+ await t
+ .dragToElement(draggableAppointment, targetCell)
+ .pressKey('esc');
+
+ await MouseUpEvents.enable(MouseAction.dragToElement);
+
+ await t
+ .expect(draggableItem.exists)
+ .ok()
+ .dragToElement(draggableItem, targetCell);
+
+ const newAppointment = scheduler.getAppointment('Brochures');
+
+ await t
+ .expect(newAppointment.element.exists)
+ .ok();
+}).before(async () => {
+ const tasks = [
+ { text: 'Brochures' },
+ ];
+
+ await initList();
+ await addTasksToList(tasks);
+ await Promise.all(tasks.map((task) => createItemElement(task)));
+ await createWidget('dxScheduler', {
+ timeZone: 'America/Los_Angeles',
+ dataSource: [
+ {
+ text: 'Book',
+ startDate: new Date('2021-04-26T19:00:00.000Z'),
+ endDate: new Date('2021-04-26T20:00:00.000Z'),
+ },
+ ],
+ currentDate: new Date(2021, 3, 26),
+ startDayHour: 9,
+ height: 600,
+ editing: true,
+ appointmentDragging: {
+ group: draggingGroupName,
+ onDragEnd(e) {
+ e.cancel = e.event.ctrlKey;
+ },
+ onRemove(e) {
+ e.component.deleteAppointment(e.itemData);
+ },
+ onAdd(e) {
+ e.component.addAppointment(e.itemData);
+ },
+ },
+ });
+});
diff --git a/packages/devextreme/js/__internal/scheduler/m_appointment_drag_behavior.ts b/packages/devextreme/js/__internal/scheduler/m_appointment_drag_behavior.ts
index 718913429957..2e4643cb3adf 100644
--- a/packages/devextreme/js/__internal/scheduler/m_appointment_drag_behavior.ts
+++ b/packages/devextreme/js/__internal/scheduler/m_appointment_drag_behavior.ts
@@ -130,7 +130,7 @@ export default class AppointmentDragBehavior {
// NOTE: event.cancel may be promise or different type, so we need strict check here.
if (e.cancel === true) {
- this.removeDroppableClasses();
+ options.onDragCancel(e);
}
if (e.cancel !== true && isSchedulerComponent(e.toComponent)) {
diff --git a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts
index 638f0589743d..61c249d1a754 100644
--- a/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts
+++ b/packages/devextreme/js/__internal/scheduler/workspaces/m_work_space.ts
@@ -51,6 +51,7 @@ import {
import WidgetObserver from '../base/m_widget_observer';
import AppointmentDragBehavior from '../m_appointment_drag_behavior';
import {
+ APPOINTMENT_DRAG_SOURCE_CLASS,
DATE_TABLE_CLASS,
DATE_TABLE_ROW_CLASS,
FIXED_CONTAINER_CLASS,
@@ -3383,6 +3384,15 @@ const createDragBehaviorConfig = (
removeDroppableCellClass();
};
+ const onDragCancel = (e) => {
+ if (!isDefaultDraggingMode) {
+ enableDefaultDragging();
+ }
+
+ removeDroppableCellClass();
+ e.itemElement?.removeClass?.(APPOINTMENT_DRAG_SOURCE_CLASS);
+ };
+
const cursorOffset = options.isSetCursorOffset
? () => {
const $dragElement = $(state.dragElement);
@@ -3399,6 +3409,7 @@ const createDragBehaviorConfig = (
onDragStart,
onDragMove,
onDragEnd,
+ onDragCancel,
cursorOffset,
filter: options.filter,
};