List element of a shift list in several <ul> at once if one of the <li> changes position

I use the drag and drop function so that users can arrange elements on the page. I have several <ul> elements with <li> elements inside them (all <ul> contain 3 <li> ), where each unordered list corresponds to a month, so

 <ul class="dragable" id="month-june"> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul> <ul class="dragable" id="month-july"> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul> <ul class="dragable" id="month-august"> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul> <!-- etc.. --> 

I want to somehow sort all the lists when the .drop() event .drop() basically, users delete the item after dragging it). I change the positions of positions in dom, so they are always ordered there, for example, if item 3 from August moves between item 1 and item 2 in July, it will look like this:

 <ul class="dragable" id="month-july"> <li>Item 1</li> <li>Item 3</li> <li>Item 2</li> <li>Item 3</li> </ul> 

Now I need to figure out how to click Item 3 from july down to augusts an unordered list, and also reset all other items after it. This should have the opposite effects, if, for example, point 1 of june drops in July between point 2 and point 3, in which case everything above it should shift to the left. Therefore, I need to have 3 elements in the entire list at any given time.

Below is an image that, I hope, explains this better: (Consider the middle section as the initial section, and the arrows show where the item is being dragged and what happens to the lists before and after it, depending on the position)

enter image description here

Is it possible to do this without using identifiers or classes, but relying on the next and previous elements (unordered lists), since I do not know exactly what months follow what is in this case.

Here is a very simple js fiddle with drag and drop behavior: DEMO

+5
source share
1 answer

Drop Updates

 $(".sortable-queue").sortable({ revert: true, scroll: false, connectWith: ".connected-sortable", placeholder: "item-dragable-placeholder", receive: function (event, ui) { var target = $(event.target).parent().parent(); var source = ui.sender.parent().parent(); var children = target.parent().children(); var start = children.index(source); var end = children.index(target); // bubble up? if (start < end) { for (var i = start; i < end; i++) { $(children[i]).find("ul").append($(children[i + 1]).find("li").first().detach()) } } // bubble down? else if (start > end) { for (var i = start; i > end; i--) { $(children[i]).find("ul").prepend($(children[i - 1]).find("li").last().detach()) } } // same pulldown else return; } }).disableSelection(); 

All he does is identify div wrappers for source and target uls. He then uses this to find out if the ul target is above or below the ul source.

If it is lower, it passes through all the wrappers from the source to the target, capturing the first li from the subsequent shell and adding it to the end.

If it is higher, then the same thing happens, the only difference is that it is selected from the end and added to the beginning.

If the source and target shell are the same, we do not need to do anything.


Fiddle - https://jsfiddle.net/ajdw2u0b/


Drag and Drop Updates

 var source; $(".sortable-queue").sortable({ revert: true, scroll: false, connectWith: ".connected-sortable", placeholder: "item-dragable-placeholder", start: function(event, ui) { source = ui.item.parent().parent().parent(); }, over: function (event, ui) { var target = $(event.target).parent().parent(); var children = target.parent().children(); var start = children.index(source); var end = children.index(target); // same pulldown if (start === end) { console.log(start) return; } // bubble up? else if (start < end) { for (var i = start; i < end; i++) { $(children[i]).find("ul").append($(children[i + 1]).find("li:not(.ui-sortable-helper):not(.item-dragable-placeholder)").first().detach()) } } // bubble down? else if (start > end) { for (var i = start; i > end; i--) { $(children[i]).find("ul").prepend($(children[i - 1]).find("li:not(.ui-sortable-helper):not(.item-dragable-placeholder)").last().detach()) } } source = target; } }).disableSelection(); 

The logic is almost the same. The only difference is that

  • You do updates on over (while dragging your item over the target point).
  • You need to save the value of the source shell instead of getting it from the ui object, since you will change it as soon as you hover over the drop target.

Note that you must exclude the draggable item and the place holder when selecting the item to detach.


Fiddle - https://jsfiddle.net/f4655x9n/

+1
source

All Articles