SortableJS / ngx-sortablejs

Angular 2+ binding to SortableJS. Previously known as angular-sortablejs
https://sortablejs.github.io/ngx-sortablejs/
MIT License
466 stars 160 forks source link

Disable item dragged or moved with its next item on draging of item for sort #135

Open Amitesh opened 6 years ago

Amitesh commented 6 years ago

Hi @smnbbrv ,

Thank you for your great work!!

I was playing with the disable option with your given example for one of my usecase. Below is my observation regarding this feature.

Problem

If I try to sort by dragging an item below of disabled item then disabled and the next item both gets sort.

Expected behaviour

If I drag the active item (not disabled) then only active items should move to the drop position and disabled item should not move. For example, if we have below list [1,2,3,4,5] where 3 is disabled (not draggable). If I drag the 4 and drop above of 2 then next order should be [1,4,2,3,5] but it is coming as [1,3,4,2,5].

Example

Initial value

 [ { "draggable": true, "text": "1" }, { "draggable": true, "text": "2" }, { "draggable": false, "text": "3" }, { "draggable": true, "text": "4" }, { "draggable": true, "text": "5" } ]

image

After sort

 [ { "draggable": true, "text": "1" }, { "draggable": false, "text": "3" }, { "draggable": true, "text": "2" }, { "draggable": true, "text": "4" }, { "draggable": true, "text": "5" } ]

image

This issue can be produced on your example itself. If you need any stackblitz/plunker then let me know.

Any help to solve it will be appreciated!

Thanks

smnbbrv commented 6 years ago

hi @Amitesh

you are talking most likely about something like "freezing" the position of a particular item. This is not what disable is for. Disabled item is not draggable but you can drag other items around, this is still a valid behavior. I would rather look at the original library's examples, how they do it in particular.

You can use onMove function and return true or false in order to gain full control over the moved item. With this you can actually implement any freezing behavior you want

Amitesh commented 6 years ago

Hi @smnbbrv

Thank you for your quick reply. I think, I missed to add expected behaviour with the issue detail. My Bad. Now, I have added it.

In mean while, I dig into underlaying library Sortable.js. It comes to me that, it is calculating wrong startIndex in case of disabled items in sortable list at line #373.

startIndex = _index(target, options.draggable);

Here startIndex is counted on the basis of draggable class name or if it is not provided then on tag name. To make an element disabled we are not setting the draggable class to it and hence it is escaped in index counting flow _matches().

I tried to tweek the source code for validating and testing my finding. I did following and it is working.

// Sortable.js
// Line 373
// Get the index of the dragged element within its parent
startIndex = _index(target, options.draggable);
let disabledItems = _index(target, '.disabled'); // hard coded for testing
startIndex = startIndex + disabledItems ;

It might possible our requirement is different than the sortable.js implementation and thats why author has not considered this case.

Can you lead me to any solution or workaround to achieve my expected behaviour.

Thanks

smnbbrv commented 6 years ago

Well, I would advise to file the issue on original library then. This repository is just an interface to it...

Amitesh commented 6 years ago

Thanks @smnbbrv It seems like the original library author is looking for new owner to maintain the library. I am not sure, if he will take this change soon. anyways, thanks for your all help for this awesome library.

smnbbrv commented 6 years ago

Wow. Didn’t see that rubaxa gave up. Well, we'll see how it goes in future. Actually angular team works on sortable in cdk so probably this would be the future