JQuery UI Droppable and Sortable - удаление в правильном месте сортировки

Я работаю над проектом, в котором я перетаскиваю элементы из стороннего элемента управления jQuery в сортировку jQuery, используя комбинацию droppable и sortable.

Это работает отлично, за исключением того, что добавляемый элемент всегда добавляется к нижней части сортируемого списка, и вы должны перенести его в нужное место в качестве отдельного шага.

Возможно ли, чтобы элемент был добавлен в место, где вы уронили его в списке?

Вы можете увидеть это поведение в демонстрационной палитре jQuery для покупок от здесь. Вот jsfiddle того же кода. Когда вы добавляете предметы из продуктов в корзину в нижней части, они всегда добавляются снизу, даже если вы бросаете их вверху.

Здесь код jQuery:

     $(function () {
     $("#catalog").accordion();
     $("#catalog li").draggable({
         appendTo: "body",
         helper: "clone"
     });
     $("#cart ol").droppable({
         activeClass: "ui-state-default",
         hoverClass: "ui-state-hover",
         accept: ":not(.ui-sortable-helper)",
         drop: function (event, ui) {
             $(this).find(".placeholder").remove();
             $("<li></li>").text(ui.draggable.text()).appendTo(this);
         }
     }).sortable({
         items: "li:not(.placeholder)",
         sort: function () {
             $(this).removeClass("ui-state-default");
         }
     });
 });

Ответы

Ответ 1

используйте droppable's drop событие callback, чтобы сравнить current top offset position of the draggable helper с top offset каждого элемента, уже присутствующего или ранее добавленного в droppable

drop: function (event, ui) {

if($(this).find(".placeholder").length>0)  //add first element when cart is empty
{
    $(this).find(".placeholder").remove();
    $("<li></li>").text(ui.draggable.text()).appendTo(this);
}

else
{

    var i=0; //used as flag to find out if element added or not

    $(this).children('li').each(function()
    {
        if($(this).offset().top>=ui.offset.top)  //compare
       {
          $("<li></li>").text(ui.draggable.text()).insertBefore($(this));
          i=1;   
          return false; //break loop
       }
    })

    if(i!=1) //if element dropped at the end of cart
    {
        $("<li></li>").text(ui.draggable.text()).appendTo(this);
    }

}

} 

ДЕМО С КОДОМ

FULL SCREEN DEMO

Ответ 2

Как насчет этого? Думаю, использование обоих вариантов connectToSortable AND connectWith. Может быть, более умный способ скрыть/показать местозаполнитель, но это определенно работает.

$(function () {
    $("#catalog").accordion();
    $("#catalog li").draggable({
        appendTo: "body",
        helper: "clone",
        connectToSortable: "#cart ol"
    });
    $("#cart ol").sortable({
        items: "li:not(.placeholder)",
        connectWith: "li",
        sort: function () {

            $(this).removeClass("ui-state-default");
        },
        over: function () {
            //hides the placeholder when the item is over the sortable
            $(".placeholder").hide(); 

        },
        out: function () {
            if ($(this).children(":not(.placeholder)").length == 0) {
                //shows the placeholder again if there are no items in the list
                $(".placeholder").show();
            }
        }
    });
});

Рабочая демонстрация в скрипте