Подтвердить что ты не робот

JQuery Sortable - выбор и перетаскивание нескольких элементов списка

У меня есть проект, где у меня есть список доступных ящиков, пользователи берут коробки, перетаскивая их из списка доступных ящиков в свой список "Мои боксы".

Пользователи чаще всего принимают по несколько ящиков одновременно (макс. 20), после того, как они закончили с полями, которые они перетаскивают обратно в список доступных ящиков, чтобы вернуть их.

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

Мне, возможно, придется придумать другой метод пользовательского интерфейса, но сначала у кого-нибудь есть предложения о том, как это можно сделать?

Спасибо!

4b9b3361

Ответ 1

У меня нет этой работы, используя сортировку, но я использовал draggable и droppable. Я не знаю, покрыл ли я всю необходимую функциональность, но это должно быть хорошее начало (демонстрация здесь):

HTML

<div class="demo">
    <p>Available Boxes (click to select multiple boxes)</p>    
    <ul id="draggable">
        <li>Box #1</li>
        <li>Box #2</li>
        <li>Box #3</li>
        <li>Box #4</li>
    </ul>

    <p>My Boxes</p>
    <ul id="droppable">
    </ul>

</div>

Script

$(document).ready(function(){

    var selectedClass = 'ui-state-highlight',
        clickDelay = 600,     // click time (milliseconds)
        lastClick, diffClick; // timestamps

    $("#draggable li")
        // Script to deferentiate a click from a mousedown for drag event
        .bind('mousedown mouseup', function(e){
            if (e.type=="mousedown") {
                lastClick = e.timeStamp; // get mousedown time
            } else {
                diffClick = e.timeStamp - lastClick;
                if ( diffClick < clickDelay ) {
                    // add selected class to group draggable objects
                    $(this).toggleClass(selectedClass);
                }
            }
        })
        .draggable({
            revertDuration: 10, // grouped items animate separately, so leave this number low
            containment: '.demo',
            start: function(e, ui) {
                ui.helper.addClass(selectedClass);
            },
            stop: function(e, ui) {
                // reset group positions
                $('.' + selectedClass).css({ top:0, left:0 });
            },
            drag: function(e, ui) {
                // set selected group position to main dragged object
                // this works because the position is relative to the starting position
                $('.' + selectedClass).css({
                    top : ui.position.top,
                    left: ui.position.left
                });
            }
        });

    $("#droppable, #draggable")
        .sortable()
        .droppable({
            drop: function(e, ui) {
                $('.' + selectedClass)
                 .appendTo($(this))
                 .add(ui.draggable) // ui.draggable is appended by the script, so add it after
                 .removeClass(selectedClass)
                 .css({ top:0, left:0 });
            }
        });

});

Ответ 2

Рабочее решение

tl; dr: Обратитесь к этому скрипту за рабочий ответ.


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

Однако...

Принятый ответ ошибочен, а @Shanimal answer близок, но не совсем завершен. Я взял код @Shanimal и построил его.

I исправлено:

Я добавил:

  • Соответствующая Ctrl + click (или Cmd + click, если на Mac) поддержка для выбора нескольких элементов. Щелчок без удерживаемой клавиши Ctrl приведет к тому, что этот элемент будет выбран, а другие элементы в том же списке будут отменены. Это то же поведение кликов, что и jQuery UI Selectable() виджет, разница в том, что Selectable() имеет выделение на mousedrag.

Fiddle

HTML:

<ul>
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
</ul>
<ul>
    <li>Four</li>
    <li>Five</li>
    <li>Six</li>
</ul>

JavaScript (с jQuery и jQuery UI):

$("ul").on('click', 'li', function (e) {
    if (e.ctrlKey || e.metaKey) {
        $(this).toggleClass("selected");
    } else {
        $(this).addClass("selected").siblings().removeClass('selected');
    }
}).sortable({
    connectWith: "ul",
    delay: 150, //Needed to prevent accidental drag when trying to select
    revert: 0,
    helper: function (e, item) {
        var helper = $('<li/>');
        if (!item.hasClass('selected')) {
            item.addClass('selected').siblings().removeClass('selected');
        }
        var elements = item.parent().children('.selected').clone();
        item.data('multidrag', elements).siblings('.selected').remove();
        return helper.append(elements);
    },
    stop: function (e, info) {
        info.item.after(info.item.data('multidrag')).remove();
    }

});

Примечание:

Так как я опубликовал это, я реализовал что-то simmilar - подключение перетаскиваемых элементов списка к сортируемым, с возможностью множественного выбора. Он настроен почти точно так же, поскольку виджеты jQuery UI настолько похожи. Один совет UI должен убедиться, что у вас есть параметр delay для перетаскиваемых или выборочных, поэтому вы можете щелкнуть, чтобы выбрать несколько элементов без инициирования перетаскивания. Затем вы создаете помощника, который выглядит, как и все выделенные элементы (создайте новый элемент, клонируйте выбранные элементы и добавьте их), но убедитесь, что, чтобы оставить оригинальный элемент неповрежденный (в противном случае он закручивает функциональность - я не могу точно сказать, почему, но это связано с множеством разочарований Исключения DOM).

Я также добавил функциональность Shift + Click, так что она больше похожа на собственные настольные приложения. Мне может потребоваться начать блог, чтобы я мог более подробно рассказать об этом: -)

Ответ 3

JSFiddle: http://jsfiddle.net/hQnWG/

<style>
    ul {border:1px solid Black;width:200px;height:200px;display:inline-block;vertical-align:top}
    li {background-color:Azure;border-bottom:1px dotted Gray}   
    li.selected {background-color:GoldenRod}
</style>
<h1>Click items to select them</h1>
<ul>
    <li>One</li>
    <li>Two<li>
    <li>Three</li>
</ul><ul>
    <li>Four</li>
    <li>Five<li>
    <li>Six</li>
</ul>
<script>
    $("li").click(function(){
        $(this).toggleClass("selected");
    })
    $("ul").sortable({
        connectWith: "ul",
        start:function(e,info){
            // info.item.siblings(".selected").appendTo(info.item);
            info.item.siblings(".selected").not(".ui-sortable-placeholder").appendTo(info.item);

        },
        stop:function(e,info){
            info.item.after(info.item.find("li"))
        }
    })
</script>

Ответ 5

Решение Aaron Blenkush имеет серьезную ошибку: удаление и добавление элементов в структуру сортируемых списков; обновление может помочь, но если другие функции обрабатывают листинг, для обновления требуется триггер для всех, и все это становится чрезмерно сложным.

После анализа некоторых решений в stackoverflow я подвел итоги следующим образом:

Не используйте вспомогательную функцию запуска, потому что у нее уже есть ui.item, которая по умолчанию является помощником.

    start: function(event, ui){
        // only essential functionality below

        // get your own dragged items, which do not include ui.item;
        // the example shows my custom select which selects the elements
        // with ".selected" class
        var dragged = ui.item.siblings(arr["nested_item"]).children('.tRow.tSelected').parent(arr["nested_item"]);

        // clone the dragged items
        var dragged_cloned = dragged.clone();

        // add special class for easier pick-up at update part
        dragged_cloned.each(function(){$(this).addClass('drag_clone');});

        // record dragged items as data to the ui.item
        ui.item.data('dragged', dragged);

        // hide dragged from the main list
        dragged.hide();

        // attached cloned items to the ui.item - which is also ui.helper
        dragged_cloned.appendTo(ui.item);
        },
  1. В части обновления:

    update: function(event, ui){
        // only essential functionality below
    
        // attach dragged items after the ui.item and show them
        ui.item.after(ui.item.data("dragged").show());
    
        // remove cloned items
        ui.item.children(".drag_clone").remove();
        },
    

Функция Stop может нуждаться в некоторой копии функциональных возможностей обновления, но, вероятно, будет отделена от обновления, потому что если никаких изменений - ничего не передает серверу.

Добавить: сохранение порядка перетаскиваемых элементов.