using drag and drop to create nested Grids
Nest items within items with drag and drop.
How can I nest items within items using drag and drop.
Your environment
- Last of gridstack.js
- Chrome, Firefox and Edge
Steps to reproduce
I need to drag menu items (grid-stack-item-content) into item (grid-stack-item-content), nesting parent and child items. The example is in: https://github.com/AlessandroNogueiraPorto/gridstack
Expected behaviour
Group child items within parent items using drag and drop.
Actual behaviour
Items are currently draggable but not grouped within another item. I need to build a process diagram with gridstack by including items within other items.
related to #992
maybe a ctrl/alt key could signal wanting to drop over vs moving item out of the way. Would be cool feature....
Hi @adumesny, now that we have a sub grid accepting an item from its parent grid, I want to create a sub grid by dragging an item from a parent grid and hovering it on top of another item, then dropping it on top it.
Regarding the method to distinguish between an item just pushing another one and creating a sub grid (folder)... would perfectly overlapping an item on top of another one work? Dragging item will push an item when it overlaps less 90% for example, but if the dragging item is hovered on the other one like a solar eclipse and kept it for like a few seconds, then it creates a sub grid containing the other item. It's basically how iphone home operates (refer to the youtube video below).
I am open to and eager to keep things simpler for the sake of clean UI and code, but I cannot afford to demand users to press an extra key for an UI to do this feature or determine how items to react to user's interaction.
https://youtu.be/lS4TtjOTmR0?t=33
https://user-images.githubusercontent.com/54137057/147718199-4511dcf9-995e-4746-bdf9-4c1f060df0bd.mp4
Thanks!
The iphone desktop is clearly a great design, but is solving a different and limited problem
- all items are the same size (1x1 square) which make it trivial (push) while GridStack (GS) supports any shapes so the collision is very different
- because of 1 there is also a top-left flow when items are inserted it just reflows the other ones into 1 list that wraps. Note this feature has been asked before. (in addition to
float:true|false) have a list reflow mode. - you insert an item by picking the in between space, while GS requires you to have >50% over an edge to push/swap an item out of the way. Iphone does that because 90% over means nest/group so you need to tell them apart.
- when grouped/nested, iphone has smaller items so parent is still 1x1 - not something native to GS so behavior might not work the same.... if you hover the item long enough, we would need to create a nested grid, and position you item there, push the other to the right/below) and hopefully the sub-grid CSS would look different enough to let user know they are grouped and can be moved as such (if clicking on parent)
- in order to support dynamically creating sub-grids, I need to know what column count to use. I think adding a
column='auto'to match the parent width count is the only thing that would work (then items stay pretty much the same size when nested). <-- that could be added to what we have today - in the GS case we still need to figure out to differentiate a push (50% of space) vs a nest (say 90-100% with delay), problem is the first always happens before the other, so....
One crazy idea would be to have an 'iphone desktop' mode that would replicate the above as much as possible, but that would be a big task...not sure how deep your pocket is.
The iphone desktop is clearly a great design, but is solving a different and limited problem
- all items are the same size (1x1 square) which make it trivial (push) while GridStack (GS) supports any shapes so the collision is very different
Would this simplify this issue?: only when colliding item's size matches the target item's to activate nesting option. Or even 1x1 to 1x1 case to be the only nesting case is okay.
- because of 1 there is also a top-left flow when items are inserted it just reflows the other ones into 1 list that wraps. Note this feature has been asked before.
I need to put items with diverse sizes into an already created sub-grid but don't need to do the new collide-to-nest feature when 2x1 to 1x1 something like that. Maybe the sub-grid created by this new feature to have a size of 2x2 by default or any size that fits the inserted two items which are the dragging and the collided one.
- you insert an item by picking the in between space, while GS requires you to have >50% over an edge to push/swap an item out of the way. Iphone does that because 90% over means nest/group so you need to tell them apart.
I think when a dragging item is placed on the exact top of another item covering it can tell the difference. When drag is stopped on top of an item but doesn't overlap quite fully, then it should just push it.
- when grouped/nested, iphone has smaller items so parent is still 1x1 - not something native to GS so behavior might not work the same.... if you hover the item long enough, we would need to create a nested grid, and position you item there, push the other to the right/below) and hopefully the sub-grid CSS would look different enough to let user know they are grouped and can be moved as such (if clicking on parent)
I think sub-grid CSS should be up to library users, and the CSS should be applied to the sub-grid such as its background or border, not to the items in it. I am also no to the sub-grid staying 1x1 and opening up a modal, I didn't intend to mimic this. I'm satisfied with how GS shows a sub-grid showing its containing items explicitly.
- in order to support dynamically creating sub-grids, I need to know what column count to use. I think adding a column='auto' to match the parent width count is the only thing that would work (then items stay pretty much the same size when nested). <-- that could be added to what we have today
I want to keep the size of an item in a sub-grid to be very similar or exactly the same as an item on the top-level grid. So change a sub-grid's column using .column() whenever the sub-grid gets resized.
- in the GS case we still need to figure out to differentiate a push (50% of space) vs a nest (say 90-100% with delay), problem is the first always happens before the other, so....
Can this be resolved by my answer on Q1?
| I think when a dragging item is placed on the exact top of another item covering it can tell the difference. When drag is stopped on top of an item but doesn't overlap quite fully, then it should just push it.
only problem is you already have pushed before you completely overlap UNLESS you need to pause to push (which is not ideal since pushing is likely a lot more common that create new nesting) OR have a very specific area to push that is small enough that if you pass it (on the way to overlap) you can restore it back so you can later overlap and nest...
Likely much harder to do with randomly shaped items of different sizes than phone 1x1 squares...
I need to think more about this and how that would affect everyone vs 4.x we have today....
| I want to keep the size of an item in a sub-grid to be very similar or exactly the same as an item on the top-level grid. So change a sub-grid's column using .column() whenever the sub-grid gets resized.
we're on the same page here and something that can be done now. I thought about it after I updated the nested.html example and thought about how we could keep all the children the same size...
only problem is you already have pushed before you completely overlap UNLESS you need to pause to push (which is not ideal since pushing is likely a lot more common that create new nesting) OR have a very specific area to push that is small enough that if you pass it (on the way to overlap) you can restore it back so you can later overlap and nest...
How about we provide an option to enable this collide-to-nest feature, then a little pause to push is acceptable for those who want this feature. I believe dragging an item onto the in-between space is intuitive and won't be a bad UI when the nesting option is enabled.
What is required to finalize https://github.com/gridstack/gridstack.js/issues/1941 ? As far as I understand, having groups A and B (the same nesting level), dragging B to A can only be implemented by enabling a certain mode (via ctrl/alt). How much is it possible and labor-intensive? I'm ready to do it, please tell me where to start?
starting work on this as Stephane P has generously sponsored this feature...
first part done! using pause to differentiate between push and nesting... lot of work, more to do.
https://user-images.githubusercontent.com/3496166/192121775-5ff370f1-b2d8-4ed1-8c2d-2d3f3bd2de9c.mp4
you can now drag sub-grids into sub-grids, creating unlimited nesting
https://user-images.githubusercontent.com/3496166/192152865-ee37e340-30fb-4aba-ae1d-3555d9fb0971.mp4
more edges fixes - make sure to delete temporary nested grids or empty ones
https://user-images.githubusercontent.com/3496166/192185096-a4edd1c6-c9c7-4e74-9862-00f692db2eba.mp4
Hello,
from what I can see the nesting behaviour revolves around the DDDragOpt.pause option. But this option introduces a global lag (the user needs to stop for a while to see the placeholder in the right place). Is there any way around that?
@vszakd not without having a disctinc behavior of push vs merge into subgrid - see https://github.com/gridstack/gridstack.js/issues/1009#issuecomment-568143450 this is not very different from phone widgets where you do have the pause briefly before 2 get grouped into a new folder...