Skip to content

[bug] Continuous item reordering issue in grid layout when dragging the first item to the end of a row #2439

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

Open
wonhyo-e opened this issue Apr 11, 2025 · 5 comments

Comments

@wonhyo-e
Copy link

wonhyo-e commented Apr 11, 2025

Note: This issue description was drafted with assistance from an AI. Please excuse any formatting inconsistencies😅

Describe the bug
When using a grid layout, there's an issue with the first item in each row. When dragging the first item towards the last position in the row, other items in the same row continuously swap positions back and forth, creating a flickering effect. This happens consistently and makes it difficult to place the item in the desired position.

To Reproduce

  1. Create a grid layout with multiple items per row (2 or more columns)
  2. Click and drag the first item in a row
  3. Try to move it to the last position in the same row
  4. Observe how other items in the row continuously swap positions back and forth

Expected behavior
Items should maintain stable positions during dragging, and only swap when the dragged item passes the threshold for repositioning. There should be no continuous back-and-forth repositioning of other items.

Information
Versions - Look in your package.json for this information:
sortablejs = ^1.15.6
@types/sortablejs = ^1

Additional context

  • This issue occurs in the official grid examples as well
  • The problem is reproducible across different browsers and devices
  • The issue is more noticeable on mobile devices with smaller screens

Reproduction
This issue can be easily reproduced using the official grid example at https://sortablejs.github.io/Sortable/#grid
Steps to reproduce with the official example:

  • Visit https://sortablejs.github.io/Sortable/#grid
  • Reduce your browser window width until the items display in 2-3 columns per row
  • Click and hold on the first item in any row (e.g., item 1)
  • Drag it towards the end position of the same row
  • Observe how other items in the row continuously swap positions back and forth as you approach the end of the row
sortable_grid_error_2_converted.mp4
@innodonni
Copy link

innodonni commented Apr 14, 2025

I have been investigating the same issue, referring to the docs for Dealing with swap glitching. I have explicitly set the direction to "horizontal" as recommended, but this doesn't help, at least for me when dragging items of different heights and widths. invertSwap doesn't help that I can see, and swapThreshold: 0.3 doesn't prevent the issue altogether.
Investigating alternatives, it seems that the unmaintained https://rosspi.github.io/gridstrap.js/ is slightly less glitchy, and seems to have some debounce/limit code that I cannot find in Sortable.

I tried this and it helped tremendously once I got it working: #2287

@wonhyo-e
Copy link
Author

wonhyo-e commented Apr 15, 2025

@innodonni
Thank you for your suggestion about using the debounce plugin. I appreciate your effort to help solve this issue. I've implemented and tested the debounce approach as recommended in #2287, but unfortunately, it doesn't address the specific problem I reported.

While the debounce technique is effective at reducing the frequency of sort events during normal dragging operations, it doesn't solve the fundamental issue with the first item in each row. The problem persists because even with debounced sorting, once the sort events do trigger, the same problematic back-and-forth swapping behavior continues to occur when dragging the first item towards the end of a row.

The debounce only delays when the sorting events happen, but doesn't prevent the erratic swapping behavior that makes it difficult to position the first item correctly. The core issue appears to be in how the grid layout algorithm determines positioning for the first item in each row, rather than the frequency of sort events.

I'm still investigating alternative solutions and would welcome any other suggestions. Thanks again for taking the time to respond to my issue report.

debounce_example.mov

@innodonni
Copy link

innodonni commented Apr 15, 2025 via email

@innodonni
Copy link

Turns out I was right that editing the debounce plugin to ignore the next drop target would work, but only with my colleagues help did we achieve it. Checking and setting a flag before you trigger changed(); completed(true); and then clearing it when lastX/lastY/lastTime are reinitialised works.

Image

@wonhyo-e
Copy link
Author

@innodonni
Thank you for your solution! I've implemented the suggested modification to the debounce plugin by setting a flag before triggering changed(); completed(true); and clearing it during reinitialization of lastX/lastY/lastTime. This completely fixed the issue with the first item in each row. I appreciate your help in solving this problem.

debounce_resolved.mov

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

No branches or pull requests

2 participants