Skip to content

Commit

Permalink
fix: when onDragInit return false it should stop (#1340)
Browse files Browse the repository at this point in the history
* fix: when `onDragInit` return false it should stop
- when `onDragInit` returns `false` then the row or cell dragging shouldn't be allowed
- this is similar to previous PR #1339
  • Loading branch information
ghiscoding authored Jan 17, 2024
1 parent 5a3bd1c commit d9c714c
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 16 deletions.
53 changes: 45 additions & 8 deletions packages/common/src/core/__tests__/slickGrid.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1938,15 +1938,44 @@ describe('SlickGrid core file', () => {
expect(onDragEndSpy).not.toHaveBeenCalled();
});

it('should return value onDragStart when event has cancelled bubbling (immediatePropagationStopped)', () => {
it('should not execute any events after onDragInit when it returns false', () => {
grid = new SlickGrid<any, Column>(container, data, columns, defaultOptions);

const cMouseDownEvent = new CustomEvent('mousedown');
const sedMouseDown = new SlickEventData();
sedMouseDown.addReturnValue(false);
sedMouseDown.stopImmediatePropagation();
const onDragInitSpy = jest.spyOn(grid.onDragInit, 'notify');
const onDragStartSpy = jest.spyOn(grid.onDragStart, 'notify').mockReturnValue(sedMouseDown);
const onDragStartSpy = jest.spyOn(grid.onDragStart, 'notify');
const onDragSpy = jest.spyOn(grid.onDrag, 'notify');
const onDragEndSpy = jest.spyOn(grid.onDragEnd, 'notify');
const slickCellElm = container.querySelector('.slick-cell.l1.r1') as HTMLDivElement;
slickCellElm.classList.add('dnd', 'cell-reorder');

const bodyMouseMoveEvent1 = new CustomEvent('mousemove');
const bodyMouseUpEvent = new CustomEvent('mouseup');
Object.defineProperty(cMouseDownEvent, 'target', { writable: true, value: slickCellElm });
Object.defineProperty(bodyMouseMoveEvent1, 'target', { writable: true, value: slickCellElm });

container.dispatchEvent(cMouseDownEvent);
document.body.dispatchEvent(bodyMouseMoveEvent1);
document.body.dispatchEvent(bodyMouseUpEvent);

expect(onDragInitSpy).toHaveBeenCalled();
expect(onDragStartSpy).not.toHaveBeenCalled();
expect(onDragSpy).not.toHaveBeenCalled();
expect(onDragEndSpy).not.toHaveBeenCalled();
});

it('should not execute onDragStart or any other events when onDragStart event has cancelled bubbling (immediatePropagationStopped)', () => {
grid = new SlickGrid<any, Column>(container, data, columns, defaultOptions);

const cMouseDownEvent = new CustomEvent('mousedown');
const sedDragInit = new SlickEventData();
const sedDragStart = new SlickEventData();
sedDragInit.addReturnValue(true);
sedDragStart.addReturnValue(false);
sedDragInit.stopImmediatePropagation();
sedDragStart.stopImmediatePropagation();
const onDragInitSpy = jest.spyOn(grid.onDragInit, 'notify').mockReturnValue(sedDragInit);
const onDragStartSpy = jest.spyOn(grid.onDragStart, 'notify').mockReturnValue(sedDragStart);
const onDragSpy = jest.spyOn(grid.onDrag, 'notify');
const onDragEndSpy = jest.spyOn(grid.onDragEnd, 'notify');
const slickCellElm = container.querySelector('.slick-cell.l1.r1') as HTMLDivElement;
Expand All @@ -1967,9 +1996,13 @@ describe('SlickGrid core file', () => {
expect(onDragEndSpy).toHaveBeenCalled();
});

it('should drag from a cell and execute all onDrag events when a slick-cell is dragged', () => {
it('should drag from a cell and execute all onDrag events when a slick-cell is dragged and its event is stopped', () => {
grid = new SlickGrid<any, Column>(container, data, columns, defaultOptions);
const onDragInitSpy = jest.spyOn(grid.onDragInit, 'notify');

const sedDragInit = new SlickEventData();
sedDragInit.addReturnValue(true);
sedDragInit.stopImmediatePropagation();
const onDragInitSpy = jest.spyOn(grid.onDragInit, 'notify').mockReturnValue(sedDragInit);
const onDragStartSpy = jest.spyOn(grid.onDragStart, 'notify');
const onDragSpy = jest.spyOn(grid.onDrag, 'notify');
const onDragEndSpy = jest.spyOn(grid.onDragEnd, 'notify');
Expand All @@ -1996,7 +2029,11 @@ describe('SlickGrid core file', () => {

it('should drag from a cell and execute all onDrag events except onDragStart when mousemove event target is not a slick-cell', () => {
grid = new SlickGrid<any, Column>(container, data, columns, defaultOptions);
const onDragInitSpy = jest.spyOn(grid.onDragInit, 'notify');

const sedDragInit = new SlickEventData();
sedDragInit.addReturnValue(true);
sedDragInit.stopImmediatePropagation();
const onDragInitSpy = jest.spyOn(grid.onDragInit, 'notify').mockReturnValue(sedDragInit);
const onDragStartSpy = jest.spyOn(grid.onDragStart, 'notify');
const onDragSpy = jest.spyOn(grid.onDrag, 'notify');
const onDragEndSpy = jest.spyOn(grid.onDragEnd, 'notify');
Expand Down
18 changes: 10 additions & 8 deletions packages/common/src/core/slickInteractions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export function Draggable(options: DraggableOption) {

function executeDragCallbackWhenDefined(callback?: (e: DragEvent, dd: DragPosition) => boolean | void, evt?: MouseEvent | Touch | TouchEvent, dd?: DragItem) {
if (typeof callback === 'function') {
callback(evt as DragEvent, dd as DragItem);
return callback(evt as DragEvent, dd as DragItem);
}
}

Expand All @@ -79,13 +79,15 @@ export function Draggable(options: DraggableOption) {
deltaX = targetEvent.clientX - targetEvent.clientX;
deltaY = targetEvent.clientY - targetEvent.clientY;
originaldd = Object.assign(originaldd, { deltaX, deltaY, startX, startY, target });
executeDragCallbackWhenDefined(onDragInit as (e: DragEvent, dd: DragPosition) => boolean | void, event, originaldd as DragItem);

document.body.addEventListener('mousemove', userMoved);
document.body.addEventListener('touchmove', userMoved);
document.body.addEventListener('mouseup', userReleased);
document.body.addEventListener('touchend', userReleased);
document.body.addEventListener('touchcancel', userReleased);
const result = executeDragCallbackWhenDefined(onDragInit as (e: DragEvent, dd: DragPosition) => boolean | void, event, originaldd as DragItem);

if (result !== false) {
document.body.addEventListener('mousemove', userMoved);
document.body.addEventListener('touchmove', userMoved);
document.body.addEventListener('mouseup', userReleased);
document.body.addEventListener('touchend', userReleased);
document.body.addEventListener('touchcancel', userReleased);
}
}
}

Expand Down

0 comments on commit d9c714c

Please sign in to comment.