SortableJS / Sortable

Reorderable drag-and-drop lists for modern browsers and touch devices. No jQuery or framework required.
https://sortablejs.github.io/Sortable/
MIT License
29.59k stars 3.7k forks source link

How to prevent selection of a Sortable item when clicking on one of its child elements? #1840

Open AJB99 opened 4 years ago

AJB99 commented 4 years ago

The Issue I'm using Sortable.js to build a draggable tree component. Which means each of my sortable-items has a toggle-arrow as a child element that opens and closes a sub-tree (if there is one).

I'm attempting to use stopPropagation() to prevent the selection of the parent sortable-item if the toggle-arrow is clicked, but it's not working.

It looks like this when closed:

Screen Shot 2020-05-30 at 2 38 33 AM

And looks like this when open:

Screen Shot 2020-05-30 at 2 38 51 AM

The blue highlight you see in the open state (the second image) is the styling I've chosen for the selectedClass option when using the multiDrag plugin.

This is illustrating that when I click on the toggle-arrow it results in the parent sortable-item being selected.

I don't want this to happen.

The Code The code for an item in my Sortable.js tree component looks like so (using Vue.js, and Pug syntax):

div.sortable-item
    div.content
        div.toggle-arrow(@click.stop="toggleTree($event)")
        div.icon
        div.title
    div.sub-tree

And then I've got a handler for the @click binding on my toggle-arrow element:

toggleTree = function($event) {
    $event.stopPropagation()
    /// Code for handling the sub-tree toggling goes here.
    /// The sub-tree toggling itself works just fine.
}

You can see that I'm declaring @click.stop as the event binding, which should stop the click event from bubbling up from the toggle-arrow child element, but it's not working. I'm even attempting to use $event.stopPropagation within the handler. But, the event seems to continue to bubble, and thus the parent sortable-item element ends up in a selected state.

Questions

  1. How do I stop propagation of an event when a child element of my sortable-item is clicked?

  2. How is selection handled by the multiDrag plugin? I dug through the code and saw that the select event is fired within the handler of the drop event of the sortable-item, but I'm confused by that. Why is the drop event handler being used to toggle selection of a sortable-item?

Thanks in advance for any light you may be able to shed on this.

jlong4096 commented 4 years ago

Hi AJB99, I'm experiencing a similar problem.

Regarding your Question #1, I've had success with putting stopPropagation on the mouseup event. Regarding your Question #2, I also do not know.

Extending on your problem, I've found another issue. After you've successfully stopped the proagation, it seems to resume on the next click. I modified this example to demonstrate the issue: https://jsbin.com/kemezohuva/edit?html,js,console,output

Notice, the clicking on the "Test" button does not select the Item. However, as soon as you something else on the page, Item 2 becomes selected. I'd love any feedback on how to prevent this from happening.

Thanks

Raven0uss commented 3 years ago

Any updates about this issue ?

It's currently not possible to click on a child element without selecting the grid element. For example, a delete button will call the function to delete but will select the element of grid and keep it as selected. I tried of course to stop the propagation but without success.

Version 1.10.2