jQuery UI Droppable和Sortable - 在正确的排序位置放置

16

我正在处理一个项目,在这个项目中,我正在使用 droppable 和 sortable 的组合将元素从第三方 jQuery 控件拖动到 jQuery sortable 中。

这个功能完美地运行,但是被添加的项目总是被添加到可排序列表的底部,你必须将它单独移动到正确的位置。

是否可能将项目添加到您在列表中放置它的位置?

您可以在来自这里的 jQuery 购物车 droppable 演示中查看此行为。这是相同代码的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");
         }
     });
 });
2个回答

23

使用droppabledrop事件中的回调函数,将可拖动元素助手的当前顶部偏移位置与已经存在或之前添加到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);
    }

}

} 

带代码的演示

全屏演示


17

使用connectToSortable和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();
            }
        }
    });
});

Fiddle上的演示


+1 太棒了,因为它还包括一个占位符,这使得用户明显地知道他们选择的项目也正在下拉列表中排序。 - KyleMit
好的解决方案。然而,我正在使用的第三方控件没有实现jQueryUI中的connectTo,所以我无法使用它。我试图在我的问题中指出这一点,但没有详细说明控件本身,以免引起太多关于控件的问题。谢谢您的帮助。 - AaronS
1
这是一个很好的解决方案,但是在我移出可放置区域后,示例中的占位符没有显示出来。 - Karl Gjertsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接