使用jQuery UI使可拖动元素在droppable中可排序

时间:2014-01-08 02:55:47

标签: jquery jquery-ui jquery-ui-sortable jquery-ui-draggable jquery-ui-droppable

分辨

所以我用sortable()属性稍微研究了connectWith,发现解决方案比我预期的要简单,但我认为它因为draggable()和{而有点倒退{1}}。

这是小提琴:http://jsfiddle.net/DKBU9/12/


原始问题如下:

这是以前的SO问题的延伸,我认为应该将其分开。

原始问题在这里:jQuery UI - Clone droppable/sortable list after drop event。它涉及重新初始化克隆元素上的droppable处理程序。

最重要的是,我试图允许从初始列表中拖出的元素在可放置列表中进行排序。

这是一个小提琴,主要说明了原始问题的结果:http://jsfiddle.net/DKBU9/7/

所需的代码因为SO喜欢抱怨并臃肿这些帖子:

HTML

droppable()

JS

<ul id="draggables">

    <li>foo1</li>
    <li>foo2</li>
    <li>foo3</li>

</ul>

<ul class="droppable new">

</ul>

参考问题:Jquery UI combine sortable and draggable

我一直试图用这个问题来解决我的问题,因为结果正是我想要实现的,特别是在接受的答案的评论中提供的最后一个小提琴,但我似乎无法考虑到微小的差异,弄清楚如何使其适应我的代码。例如,该问题中的小提琴克隆了可拖动而不是拖动实际元素,与我不同的是,不允许将元素拖回到初始列表中。

因此,我们非常感谢任何尝试为我的代码获取结果的帮助。

此外,在该示例中,$(function() { $('#draggables > li').draggable({ appendTo: 'document', revert: 'invalid' }); $('.droppable > li').draggable({ appendTo: 'document', revert: 'invalid' }); $('#draggables').droppable({ accept: '.droppable > li', drop: function(event, ui) { ui.draggable.detach().css({top: 0,left: 0}).appendTo($(this)); cleanUp(); } }); initDrop($('.droppable')); }); function initDrop($element) { $element.droppable({ accept: function(event, ui) { return true; }, drop: function(event, ui) { if($(this).hasClass('new')) { var clone = $(this).clone(); $(this).after(clone); $(this).removeClass('new'); initDrop( clone ); } ui.draggable.detach().css({top: 0,left: 0}).appendTo($(this)); cleanUp(); } }).sortable({ items: 'li', revert: false, update: function() { cleanUp(); } }); } function cleanUp() { $('.droppable').not('.new').each(function() { if($(this).find('li').length == 0) { $(this).remove(); } }); } 属性被设置为返回true的函数。这是什么原因?这不仅仅意味着它会接受任何东西,或任何可拖动的元素吗?

编辑:我读了一些只使用了sortable()和connectWith属性的答案,但由于某些原因我不认为它做了我需要的,部分是因为我不希望初始列表是可排序的同样。但是,单独使用sortable()似乎可以获得我正在使用的功能,但我还没有调整所有事件处理程序。

1 个答案:

答案 0 :(得分:5)

请参阅 this fiddle

它会使项目在新列表中可以删除和排序,但不会在初始中(根据您的编辑)。

有一些技巧:

1)从draggable开始,我添加了一个新函数,因为我们需要留下一个占位符(使用一个克隆),这样容器在拖动过程中不会跳转,我们需要将新元素初始化为draggable。 / p>

function initDraggable($element)
{
    $($element).draggable({
        connectToSortable: '.droppable',     
        revert: function(droppableObj)
        {
            if(droppableObj === false)
             {                
                $(this).removeClass('dragging');
                return true;
             }
             else
             {              
                return false;
             }
        },
        helper: 'clone',
        start: function(e, ui)
        {           
            $draggingParent = $(this).parent();
           $(this).addClass('dragging');
        }
    });
}

请注意connectToSortable: .droppable(作为清理,我认为您应该将droppable更改为可排序);

另请注意revert: - 这使我们有机会在恢复时删除“拖动”类(使原始(克隆)元素不可见)。

最后,有start添加了'拖动'类,这使得原始(克隆)元素在拖动过程中不可见。它还设置$ draggingParent,用于检查是否正在从#draggables.droppables拖动项目。

2)然后droppable()的{​​{1}}:

#draggables

请注意, $("#draggables").droppable({ drop: function(ev, ui) { if($draggingParent[0] === $(ui.helper).parent()[0]) { //dragged from draggables to draggables $(ui.draggable).removeClass('dragging'); } else { if(ui.draggable.parent()) var $clone = $(ui.draggable).clone(); $(ui.draggable).remove(); $clone.removeClass(); $clone.removeAttr('style'); initDraggable($clone); $(this).append($clone); } } 处理程序会检查此元素是从drop还是#draggables中删除,并采取相应的行动。

3)最后,正如您已经提到的,我们真的希望droppable可以排序:

.droppables

请注意function initDroppableSort($element) { $element.sortable({ items: 'li', connectWith: ".droppable,#draggables", revert: true, stop: function(event, ui) { $(ui.item).removeClass('dragging'); $('.dragging').remove(); if($(this).hasClass('new')) { var clone = $(this).clone(); clone.empty(); $(this).after(clone); $(this).removeClass('new'); initDroppableSort( clone ); } cleanUp(); } }); } ,特别是它指的是connectWith.droppable