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.6k stars 3.7k forks source link

Preventing items from being dragged beyond a special item inside the list. #1067

Open bs-thomas opened 7 years ago

bs-thomas commented 7 years ago

Hello there,

I'm using the native sortablejs plugin, and it looks pretty great so far! Thanks for creating such a lovely plugin.

I have one issue, which I searched around and has yet found a solution. The closest issue I can find is this one: https://github.com/RubaXa/Sortable/issues/911

I have an item which is a part of the item list, but is not sortable in anyway. (It's an upload trigger). What I would like to do is to:

  1. always be put ths upload trigger item in the back of the list. This means, I cannot drag it to elsewhere in the list.
  2. not allow any other items in the list to drag beyond the upload trigger. So dragging any items beyond it should issue a "cancel" of some sort.

I achieved 1 by making use of this option: filter: '.upload-trigger',

For 2, I tried to console.log() various types of events. The closest one seems to be "onMove", where I can issue a "return false" to prevent the drag. However, I am unable to obtain the "newIndex", which I thought would be useful if I know that, because I'd be able to do some calculations, and decide if I should return false or not.

As this special item "upload-trigger" is a part of the list (I cannot take it away, otherwise mobile-responsive will not respond according to the requirement specifications). The upload trigger needs to be a part of the whole list.

I was wondering if you can shed me some light if there are any approaches or alternatives to solving the problem.

Your help is greatly appreciated.

Thank you very much!

bs-thomas commented 7 years ago

I noticed there is another related issue, though I'm unsure if this is supported yet at the moment. https://github.com/RubaXa/Sortable/issues/728

bs-thomas commented 7 years ago

Just hope this could help out the lost people out there, what I finally did was, in the callback "onMove(evt)", I used:

var newIndex = Sortable.utils.index(evt.related, '.item');

where '.item' is the "options.draggable" value I passed in to initialize the plugin for me.

@RubaXa Though, I thought it would be very nice if this could be included in the callback without doing any tricky stuff. ;-)

RubyZhuuu commented 7 years ago

@bs-thomas Your answer really help me a lot! Thanks very much.

schwamic commented 6 years ago

@bs-thomas The index returned is not consistent and therefore cannot be used easily. Often the index by one or two positions does not match the current list.

@RubaXa Also the 'toArray' does not give any clear information about the current order of the elements while onMove, and is difficult to find out how the indexes have to be mapped.

In the current version there is no easy way to get the current order of the list during onMove. Neither the 'ghost'-element nor an exact position of the 'drag'-element can be identified. However, there must be an exact order within Sortable, why is this information not accessible? It would be a nice feature for a better UX, if the index of the list-items would be updated during onMove instead of onEnd.

I have already tested the following:

Is there currently still another way to get the current order during onMove?

wangbo201308 commented 5 years ago

@bs-thomas I also accountered the same question as yours, thanks for your answer!