Skip to content

[BUG] Drag causes an error when acceptWidgets: true is set, but not when it is set to false #2920

Open
@waiwai0308

Description

@waiwai0308

Subject of the issue

Original discussion thread
https://gridstackjs.slack.com/archives/C0LPPLXJR/p1735744953594099?thread_ts=1735236074.058529&cid=C0LPPLXJR

I use the example Website demo 1

Drag causes an error when acceptWidgets: true is set, but not when it is set to false. You can refer to the explanation below for more details

Your environment

gridstack.js - v11.2.0
browser: Chrome 131.0.6778.205

Steps to reproduce

let children = [
  { id: 0, x: 0, y: 0, w: 1, h: 1, content: "1" },
  { id: 1, x: 1, y: 0, w: 1, h: 1, content: "2" },
  { id: 2, x: 2, y: 0, w: 1, h: 1, content: "3" },
  { id: 3, x: 3, y: 0, w: 1, h: 1, content: "4" },
  { id: 4, x: 4, y: 0, w: 1, h: 1, content: "5" },
  { id: 5, x: 5, y: 0, w: 1, h: 1, content: "6" },
  { id: 6, x: 0, y: 1, w: 1, h: 1, content: "1" },
  { id: 7, x: 1, y: 1, w: 1, h: 1, content: "2" },
  { id: 8, x: 2, y: 1, w: 1, h: 1, content: "3" },
  { id: 9, x: 3, y: 1, w: 1, h: 2, content: "Item A" },
  { id: 10, x: 4, y: 1, w: 2, h: 2, content: "Item B" },
  { id: 12, x: 0, y: 2, w: 1, h: 1, content: "1" },
  { id: 13, x: 1, y: 2, w: 1, h: 1, content: "2" },
  { id: 14, x: 2, y: 2, w: 1, h: 1, content: "3" },
  { id: 18, x: 0, y: 3, w: 1, h: 1, content: "1" },
  { id: 19, x: 1, y: 3, w: 1, h: 1, content: "2" },
  { id: 20, x: 2, y: 3, w: 1, h: 1, content: "3" },
  { id: 21, x: 3, y: 3, w: 1, h: 1, content: "4", noResize: true, locked: true, noMove: true },
  { id: 22, x: 4, y: 3, w: 1, h: 1, content: "5", noResize: true, locked: true, noMove: true },
  { id: 23, x: 5, y: 3, w: 1, h: 1, content: "6", noResize: true, locked: true, noMove: true },
];

let grid = GridStack.init({
  cellHeight: 70,
  row: 4,
  column: 6,
  float: true,
  acceptWidgets: true,
  children,
});

reproduce example: https://codesandbox.io/p/sandbox/tg9zg4

2025-01-05.12.46.37.mov
  1. Drag Item B to swap with Item A, then move them directly out of the yellow area.
  2. Get an error message
gridstack-all.js:2 Uncaught RangeError: Maximum call stack size exceeded
    at t.get (gridstack-all.js:2:34331)
    at t._useEntireRowArea (gridstack-all.js:2:31070)
    at t._fixCollisions (gridstack-all.js:2:31397)
    at t.moveNode (gridstack-all.js:2:41080)
    at t._fixCollisions (gridstack-all.js:2:31912)
    at t.moveNode (gridstack-all.js:2:41080)
    at t._fixCollisions (gridstack-all.js:2:31912)
    at t.moveNode (gridstack-all.js:2:41080)
    at t._fixCollisions (gridstack-all.js:2:31912)
    at t.moveNode (gridstack-all.js:2:41080)

If I set acceptWidgets: false and repeat the steps above, the error does not occur.

Expected behavior

When swapping Item B and Item A, the items should successfully change positions, and even if I drag them out of the yellow area, it shouldn't cause an error.

Additional details

I tried modifying the original code and found that when I set acceptWidgets: false, the dropout event doesn't trigger. However, when set to true, it enters the following block of code:

// gridstack.js/src/gridstack.ts

.on(this.el, 'dropout', (event, el: GridItemHTMLElement, helper: GridItemHTMLElement) => { 
    // *************************************************
    console.log("acceptWidgets === true will show this");
    if(this.opts.acceptWidgets === true) return false;
    // *************************************************

    // console.log(`out ${this.el.gridstack.opts.id} ${count++}`); // TEST
    const node = helper?.gridstackNode || el.gridstackNode;
    if (!node) return false;
    // fix #1578 when dragging fast, we might get leave after another grid gets entered (which calls us to clean)
    // so skip this one if we're not the active grid really..
    if (!node.grid || node.grid === this) {
      this._leave(el, helper);
      // if we were created as temporary nested grid, revert to the previous state
      if (this._isTemp) {
        this.removeAsSubGrid(node);
      }
    }
    return false; // prevent parent from receiving message (which may also be grid)
})

When acceptWidgets: false is set, the following console.log does not display
false

When acceptWidgets: true is set, the following console.log is displayed and get error message
true no return

When acceptWidgets: true is set, I added if(this.opts.acceptWidgets === true) return false; the error doesn't occur.
true

Thanks

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions