draggable
draggable copied to clipboard
Nested Sortables?
Hi! Great work with this project, it's really good.
I was wondering if nested sortables are a possibility? For example, if I have a list of parent items and child items and I would like to sort the parents between each other or sort their children.
I am using React and have experimented with creating two different sortable objects but haven't been able to make it work as they conflict with one another. Is this not possible at this point or is it my mistake?
Thanks!
Thanks for asking! We are planning to build a NestedSortable
module or bake nesting into the existing Sortable
module, but this is planned for post stable release. No ETA for this yet unfortunately
Related: https://github.com/Shopify/draggable/issues/56
This would be awesome, currently using an adapted version of the retired(?) https://github.com/angular-ui-tree/angular-ui-tree . Happy to help with the logic if you'd like
You have the handle property, so this does support nested drag & drop currently in the event that the parent list at-least has a handle property corresponding to a non-sortable sub-element.
The only problem I'm having is setting this to work nested is when I add another group for sub-items to be transferable between upper level lists. Like a KanBan.
https://codepen.io/Lewiscowles1986/pen/YvgPgP
I did think about adding the selector for the last list, but then the append action is off too. It's just a quick evaluation to see if this is capable of replacing jQuery UI sortable (it's so close).
Nesting is already possible with the current Sortable
:
https://jsfiddle.net/zodqmx09/6/
It's possible, but a bit of a dead end if you can only sort static elements, not receive new ones. Some form of mutation observer is probably needed.
You can create and patch the elements with a virtual dom library (like e.g. snabbdom). I just built a nested kanban-board with this technique.
are there tomes of the internet containing the incantations to work such magic?
I'm sorry, I don't understand what you intend to say...
You can create and patch the elements with a virtual dom library (like e.g. snabbdom). I just built a nested kanban-board with this technique.
@fdietze that sounds really cool! You don't happen to have a repo / example you could point to by chance?
It's certainly the last time (this week) I'll try asking anything in a funny way.
@fdietze what @beefchimi just said.
@Lewiscowles1986 I apologize for not getting the joke. I'm not a native english speaker. Please don't stop making humor because of language barriers. :wink:
The kanban board I built is very wired with my project written in Scala, so this would probably not be a helpful example. But I'll try to explain it in more detail here instead:
- Create one
Sortable
instance for the whole kanban-board. - To display a nested kanban board, you obviously have to store your data in a tree.
- You can traverse this tree recursively and create virtual dom. For inner nodes of the tree you create (sub-)columns which contain more sub-trees. For the leafs you create cards. Create the dom with the necessary classes to make
Sortable
work. - Store ids or references to your nodes in the tree in
data
-attributes. - In Snabbdom you can use
insert hooks
to add the containers to theSortable
instance. In React this would be done via lifecycle hooks. Add each (sub-)column as a container. - Listen to
sortable:sorted
of theSortable
instance to react to dropped elements. From this event you can extract the ids of the element, the source and the target container from theirdata
attributes. Use these ids to change your tree data structure. - Re-render your kanban-board with your updated tree.
Just ask, if a step is unclear.
Hi @fdietze,
I think what I'm doing is probably incompatible with that. For one at the moment I'm not backing anything anywhere so tree structure really doesn't matter (If it's a tree it's a darn special one). I have an example of this working without virtualdom, it just has bugs, it's probably the listening to the sortable:sorted
of the Sortable
instance that will resolve them. Right now I remove the listeners before adding the sortable and then re-add sortable. that's obviously not ideal should I take it further.
The strange thing is that it works when I have just one instance of Sortable, however I also want to be able to change column order. I think I'll end up just adding nav-button overlay to each to ease the burden of drag-and-drop. It'll achieve the same end result without too much technical debt and up-front decision making.
- Up down buttons for sibling exchange (easy)
- left right buttons for column-list exchange (easy)
- maybe a state for ad-hoc movements.
I started because I'm using WeKan at work. It's heavy for what it is and I'd prefer to store in markdown with a small helper to detect kanban layout. That way it's lightweight and doesn't need a formal storage. One person can be in-charge of full-edits to a board. YMMV
All these examples does not work as expected. Waiting for native nested support very much.
Me too! How can we help?
Any update on this? I tried nesting Sortables, which works, but I'm seeing this error in the console:
![screen shot 2018-10-25 at 5 39 37 pm](https://user-images.githubusercontent.com/1731025/47531948-fef7d800-d87c-11e8-8c05-4a586a37bc63.png)
Hi all, same issue here @tlaverdure , did you find any way out of this ? thanks in advance
@HectorLS nope. Just had to do without for now.
Hi @travdesjard and all, im having troubles snaping to the nested dropzone, its sorting perfectly between siblings top level, but it gets too much tricky to snap into the nested ones. Any idea why could be ? maybe some css rule 😕 ?
Hope someone can help on this Thanks!
@HectorLS would love to help you out but I think this is out of my wheelhouse 😉
Could we hope for implementing nested sortable feature?
I managed to get a proof of concept working for nested sortables by turning on and off the droppable containers using the events. I attached a data attribute that gets the sortable group and then using the sourceContainer
I can determine which groups a sortable element belongs to. From there I just unbind the event to the other containers.
Markup looks a bit like this :
<div class="sortable dashboard" data-sortable-group="dashboard">
<div class="sortable-item">
dashboard panel A
</div>
<div class="sortable-item">
<div class="sortable" data-sortable-group="tabs">
<div class="sortable-item">
TAB 1
</div>
<div class="sortable-item">
TAB 2
</div>
</div>
</div>
<div class="sortable-item">
dashboard panel C
</div>
<div class="sortable-item">
<div class="sortable" data-sortable-group="tabs">
<div class="sortable-item">
TAB X
</div>
<div class="sortable-item">
TAB Y
</div>
</div>
</div>
<div class="sortable-item">
dashboard panel E
</div>
</div>
And the JS does something like this:
const groupTargetIdentifier = "data-sortable-group";
this.droppableContainers = document.querySelector('.sortable');
this.sortable = new Sortable(this.droppableContainers, {
draggable: ".sortable-item",
mirror: {
constrainDimensions: true,
},
});
this.unwantedContainers = null;
let group;
this.sortable.on("drag:start", e => {
group = e.sourceContainer.getAttribute(groupTargetIdentifier);
this.unwantedContainers = this.droppableContainers.filter(container => container.getAttribute(groupTargetIdentifier) !== group);
this.unwantedContainers.forEach(target => this.sortable.removeContainer(target));
});
this.sortable.on("drag:stop", () =>{
this.unwantedContainers.forEach(target => this.sortable.addContainer(target));
this.unwantedContainers = null;
});
Maybe not the most performant, but my use case I've got 5 dashboard panels that can be rearranged, and a maximum of 9 tabs
Is there any plan to make this work?
Every few months I check the website to see whether the 'nestable' is finally no longer grayed out. As long as that is not possible, we cannot use this library because a very important function is missing. Too bad.
Still no PR for this?