【问题标题】:Jquery Sortable & cloneJquery 可排序和克隆
【发布时间】:2013-11-26 11:54:09
【问题描述】:

场景:将一个或多个元素拖放到另一个列表中,但不要从源列表中删除拖动的元素。

为了允许多次拖动,我使用了 Aaron Blenkush here 发布的代码。

Demo

我已根据自己的需要进行了更改,例如修复了 Shift 问题。

  $("ul").on('click', 'li', function (e) {
      if (e.ctrlKey || e.metaKey) { //meta key for mac users
          $(this).toggleClass("ui-selected");
          $(this).parent().parent().siblings().children('ul').children().removeClass('ui-selected');
    }
    else if (e.shiftKey) {
        // $(this).toggleClass("selected");               
        var list = $(this).parent();
        var first = list.find('.ui-selected').first().index();
        // var last = list.find('.selected').last().index();
        var last = $(this).index();

        if (first == -1 || last == -1) {
            return false;
        }

        if (last < first) {
            firstHolder = first;
            first = last;
            last = firstHolder;
        }

        for (i = first; i <= last ; i++) {
            list.children().eq(i).addClass("ui-selected");
        }
    }
    else {                
        $(this).addClass("ui-selected").siblings().removeClass('ui-selected'); //select only clicked element and unselecting other elements

        //to Remove selected Class from 2nd UL li
        $(this).parent().parent().siblings().children('ul').children().removeClass('ui-selected');
    }
})
   .sortable({
       connectWith: "ul",
       delay: 150, //Needed to prevent accidental drag when trying to select
       revert: 0,
       cursor: "move",
       disabled: false,
       placeholder: 'placeholder',
       //  handle: ".handle",
       helper: function (e, item) {
           //Basically, if you grab an unhighlighted item to drag, it will deselect (unhighlight) everything else
           if (!item.hasClass('ui-selected')) {
               item.addClass('ui-selected').siblings().removeClass('ui-selected');
           }

           //////////////////////////////////////////////////////////////////////
           //HERE'S HOW TO PASS THE SELECTED ITEMS TO THE `stop()` FUNCTION:

           //Clone the selected items into an array
           var elements = item.parent().children('.ui-selected').clone();

           //Add a property to `item` called 'multidrag` that contains the selected items, then remove the selected items from the source list
           item.data('multidrag', elements)
               //.siblings('.ui-selected').remove();

           //Now the selected items exist in memory, attached to the `item`, so we can access them later when we get to the `stop()` callback

           //Create the helper
           var helper = $('<li/>');
           return helper.append(elements);
       },
       start: function(event, ui) {
           //$(ui.item).show();
           var elements = ui.item.data('multidrag');
           ui.item.after(elements);
           //clone = $(ui.item).clone();
           //before = $(ui.item).prev();
       },
       stop: function (e, ui) {
           //Now we access those items that we stored in `item`s data!
           var elements = ui.item.data('multidrag');

           //`elements` now contains the originally selected items from the source list (the dragged items)!!

           //Finally I insert the selected items after the `item`, then remove the `item`, since item is a duplicate of one of the selected items.
           ui.item.after(elements).remove();
         //  $(ui.item).show();
           //$(this).sortable('cancel');
       }
   });

问题:它从源列表中删除已删除的元素。

我对这个问题进行了一些研究。有人说在辅助方法中使用克隆,但是当我传递给返回多个元素的函数时,我不能使用克隆。在 Firebug 中,当我拖动元素时,它会将 style=display:none 放在它们上面,但是当我放置元素时,它会将它们从源列表中删除。

更新

我已对接受的答案进行了一些更改以使其更简单

Updated Answer

有一些问题,例如当 li 从第一个列表下降到第二个列表时。然后将 li 从第 2 个拖回第 1 个,它将删除元素

solution 可以在项目被放入第二个列表时删除 ui-selected 类。

我希望它会帮助一些人:)

【问题讨论】:

    标签: jquery jquery-ui jquery-ui-sortable


    【解决方案1】:

    好吧,我把它搞砸了一段时间。如果当时我能想到的最好的话,下面是..

    var selected;
    var selectedCurrent;
    var temp;
    var received = false;
    $("ul").on('mousedown', 'li', function (e) {
    if($(this).next('li').hasClass('pholder'))
            $(this).next('li').remove();
    if ((e.ctrlKey || e.metaKey) && selected != undefined) {
        if($(this).text() != selectedCurrent.text()) 
             selectedCurrent.after(selected.clone().addClass('pholder temp').hide());
    }
    selectedCurrent = $(this);
    selected = $(this).clone().removeClass('selected');
    });
    $("ul").on('click', 'li', function (e) {
    if(temp != undefined)
        $('.temp').remove();        
    if (e.ctrlKey || e.metaKey) {
        if($(this).next('li').hasClass('pholder'))
            $(this).next('li').remove();
        else
            $(this).after($(this).clone().addClass('pholder').hide());
        $(this).toggleClass("selected");
    } else {
        $(this).addClass("selected").siblings().removeClass('selected');
        $('.pholder').remove();
    }
    }).sortable({
    connectWith: "ul",
    delay: 150,
    revert: 0,
    helper: function (e, item) {
        if (!item.hasClass('selected')) {
            item.addClass('selected').siblings().removeClass('selected');
        }
        var elements = item.parent().children('.selected').clone();
        item.data('multidrag', elements).siblings('.selected').remove();
        var helper = $('<li/>');
        return helper.append(elements);
    },
    stop: function (e, ui) {
        if(!received){
            selected.remove();
            $('.pholder').remove(); 
        }
        else{
            received = false;
            $('.pholder').removeClass('pholder');
        }
        var elements = ui.item.data('multidrag');
        ui.item.after(elements).remove();
        $('.selected').removeClass('selected');
    },
    start: function(event, ui){
        ui.item.after(selected);
        $('.pholder').show();
    },
    receive: function(event, ui){
            received = true;
    }
    });
    

    小提琴

    http://jsfiddle.net/hQnWG/749/

    更新

    http://jsfiddle.net/hQnWG/752/

    Update 2 - 删除列表中的重复项。

    http://jsfiddle.net/hQnWG/754/

    【讨论】:

    • 有一个问题。如果您使用 ctrl 选择所有三个 li,它会在第一个和第二个之间复制 li,这会增加 li 的计数。
    • @user751959 是的,我担心可能会有一些错误。不过我会调查一下。
    • @user751959 我想出了一个更强大的更新。 jsfiddle.net/hQnWG/752 我现在唯一能找到的是,如果列表中有多个 One 或任意数字的倍数,并且您将它们都移到另一个列表中,那么只有一个 One保留在原始列表中,而不是两者都保留.. 我不知道为什么你会在一个列表中想要多个相同的东西,所以我会再想出一个小提琴,如果列表中有重复项,它会删除它们。
    • @user751959 消除重复的最后一次更新...jsfiddle.net/hQnWG/754
    • 我已经用你的代码试过了。它是如此复杂,我想出了更简单的解决方案。 http://jsfiddle.net/abUF2/1/
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-21
    • 2013-08-24
    • 1970-01-01
    • 2014-01-24
    • 2018-01-11
    • 1970-01-01
    • 2011-03-02
    相关资源
    最近更新 更多