JQuery sortable list with some frozen items?

I am looking for a method for a jQuery-like sortable list ( link ), but with some elements in fixed underdeveloped positions.

It is trivial that some elements are not available, but their positions do not remain fixed, because the number of elements to be dragged higher and lower can change.

To be more specific: I have a list of 10 items in ranking order. I want the user to be able to change the ranking for some items by dragging (sortable list) but not changing the rank of other frozen items. The standard jQuery sorting function for sorting allows you to change the rank of frozen items by changing the number of items above or below frozen items.

I tried to do this manually by sorting through the list items while dragging and dropping. Ie, when a list item is dragged over an unfrozen item, the position of the two items is replaced. This gives the semantics that I want, but the item being dragged noticeably β€œjumps” between its new position and the current β€œdrag” position. (I want it to stay in the current drag position, only its position in the DOM should change. But when the DOM position changes, the coordinates of the drag offset must be recalculated. And I don’t know how to change the position of the DOM and change the shift coordinates of the shift atomically. preventing redrawing between them. Nowadays, sometimes there is a redrawing between them, and the element noticeably, although soon, skips.)

Edit Here jsfiddle shows my manual approach: link . Play with him for a while and you will notice the flicker / jumps that I mentioned.

+6
source share
3 answers

I looked at your fiddle, I thought another, and here is one way to do this using sortable : on start to save fixed index positions in the data object of each fixed element, and then turn on any change , move the fixed elements in place.

 $(function() { $('#rankings').sortable({ axis: 'y', items: '.sortable', start: function () { $(this).find("li:not(.sortable)").each(function () { $(this).data("fixedIndex", $(this).index()); }); }, change: function () { $(this).find("li:not(.sortable)").each(function () { $(this).detach().insertAfter($("#rankings li:eq(" + ($(this).data("fixedIndex")-1) + ")")); }); } }); }); 

Using a list, for example:

 <ol id="rankings"> <li class="sortable">Dog</li> <li class="">Cat</li> <li class="sortable">Parrot</li> <li class="sortable">Gerbil</li> <li class="sortable">Snake</li> <li class="">Goldfish</li> </ol> 

Seems to work .

+14
source

I think I may have hacked it - http://jsfiddle.net/q5c4Y/3/ . However, a rather difficult task. Several things helped along the way.

  • Using more structured markup
  • Using droppable over event to replace list items but not drop event (dragstop is used instead)
  • Setting up some positioning on internal elements to keep them in the correct position after changing the parent element

While reading @graphicdivine, answer above, it looks like you really need all the time jquery ui sortable

+4
source

1) If the elements that you do not want to change are at the top and / or at the bottom of the list, you can create these elements outside the list, thereby allowing only the sorting of OTHER elements and keeping the ranking immutable.

2) Can you use the stop event to verify that the ranking of the ones you want has been saved? those. make sure that there are still only 3 elements above the fourth rating, and if not, move the new β€œ4th” below the one that has the same 4th rank? Basically, forcibly re-moving items after an item has been dragged to an illegal place?

+1
source

Source: https://habr.com/ru/post/908659/


All Articles