Open zhaodong-wang opened 5 years ago
So I quickly took a look at your StackBlitz and also how Google Drive does it. I think this is not really the responsibility of this library. As far as I can see, Google Drive only allows to drag an element if it is selected. So you might need to enable/disable the drag-and-drop as well as the drag-to-select. So you would disable drag and drop for all items unless they are selected. If you start dragging an element that is selected, it allows you to drag that element elsewhere. In that case the drag-to-select would need to be disabled, or at least the selected items need to be disabled. If you drag on an element that is not selected, then you would just disable dragging and the drag-to-select kicks in.
I am wondering if this would require something like beforeDrag
on the select-container
so you can disable it before the selection is started.
@timdeschryver Curious to hear your thoughts on this.
@d3lm Thanks for your quick response! Now I can do something like this with the disableDrag
input. But this is a bit hacky. The idea is:
selectedItems
(a BehaviorObject
).select-container
subscribes selectedItems
: if selectedItems.length > 0
I set disableDrag = true
, otherwise I set it to false
.dtsSelectItem
) subscribes selectedItems
as well (within a customized directive): if selectedItems.length > 0
I set attribute draggable = true
, otherwise I set it to false
. Also, if this item belongs to selectedItems
, I add a selected-item
css class to it, otherwise I will remove it.So can somewhat reproduce the Google Drive behavior, but still there are some differences:
selectedItems
is NOT updated due to the first clicking (and thus the styles remain unchanged, just opacity being smaller). However, in dts-select-container
, if I click an item, the selectedItem
will be updated to this item, so we lost all the selectedItems prior to the clicking.(selectionEnded)="updateSelectedNodes($event)"
, where updateSelectedNodes($event) = (items) => {selectedItems.next(items.slice())}
. So the selectedItems
won't be updated due to "clicking". This can also replicates another effect (which is good): if I selected multiple items, then click any of them but do not start dragging, this item will be selected and selectedItem
should be updated.selectedItems
WILL be updated. But since I only used selectionEnded
so in my solution selectedItems
won't be updated.disableDrag = true
if selectedItems.length > 0
, I won't be able to start another selection box.So I think the feature I would like to have in ngx-drag-to-select
is:
Is it possible to "only" disableDrag
after I have clicked any "selected" items (and don't update selectedItems
due to this click).
Sorry, the description might be a little complicated. Please let me know if there are any thing unclear.
Below is a small demo for the features:
@d3lm I think beforeDrag
could potentially solve this. Is it possible to add this?
Yep, I think we can add this output. Do you think that should be enough to make it work with the DnD library from the Angular CDK?
Curious to hear your thoughts. Maybe you have a solution in mind that is less or even not hacky at all.
I am not sure if this would work with Angular CDK Drag and Drop. In the Stackblitz I wrote my own handler for drag
, dragstart
, dragend
etc. I didn't use Angular CDK.
I think in order to replicate the GDrive effect, we probably need to provide the following API such that the entire event chain is like follows:
mousedown
inSelectedArea
, emit this value.beforeDrag($event)
consuming this emitted value. So we can determine the subsequent actions. For example:
inSelecteArea = true
, disable drag and select. So this mousedown
will not updated selectedItems
and if the drag event starts, selection box will not be generated. Thus the previously selected items can be dragged to somewhere else.mousedown
, e.g., the user click onto any of the selected item, and then release mouse (mouseup
), then this is not a drag event, and in this case, we shouldn't disable drag or select and the event handling should be similar to inSelectedArea = false
. This is the tricky part.inSelecteArea = false
, everything works like what we have now: a new selection box will be generated and the previously selectedItems
will be updated.I am not sure if this is easy to implement. I went through the source code and it seems that there are a lot of callbacks registered in the pipe
after mousedown
. So it might not be easy to ensure beforeDrag
happens before any of the drag events, selection box generation, and selectedItems updates.
What do you think?
@d3lm do you have any comments on this? Curious to hear your thoughts.
Did you ever figure out how to do this?
Hey, I need to revisit this and think about it. Was working on a different feature (range selection, #89) first. I ll definitely come back to this. Any help is much appreciated, and if you have concrete ideas on how this could work then please go ahead and post it here. I'd also love to see someone working on a PR 🙌
This is a feature request (or if it is already achievable, please let me know). Might be related to #70.
Let me describe it briefly:
Here is the StackBlitz for the MWE: https://stackblitz.com/edit/angular-sbkxtf
So as you can see, we have a container and we have some children in it. The container is
dts-select-container
and the children aredraggable="true"
.When I start dragging the child:
dragstart
of the child fired, so we can drag around the childMy expected behavior is like Google Drive:
Where
dragstart
will be firstly fired in the container (so selection box shows up), when some items are selected,dragstart
will be fired for those children and some animations shows up, afterdragend
fired, the selection box will NOT re-activately immediately unless the nextdragstart
fired. So eitherdragstart
will be fired in the parent or child depends on whether there are selected things.It is achievable with
ngx-drag-to-select
?@d3lm