Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
waiwai0308 opened this issue Jan 5, 2025 · 0 comments

Comments

@waiwai0308
Copy link

waiwai0308 commented Jan 5, 2025

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants