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



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



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



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



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



спасибо!

844   5  

5 ответов:

у меня нет этой работы с помощью сортируемого, но я использовал 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>

скрипт

$(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 });
            }
        });

});

Рабочего Раствора

tl; dr:обратитесь к этой скрипке для рабочего ответа.


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

однако...

принятый ответ глючит, и @Shanimal это is закрыть, но не совсем полный. Я взял код @Shanimal и построил на нем.

я исправил:

я добавил:

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

Скрипка

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 настолько похожи. Один совет пользовательского интерфейса, чтобы убедиться, что у вас есть delay набор параметров для draggables или selectables, так что вы можете нажать, чтобы выбрать несколько элементов без инициирования перетаскивания. Затем вы строите помощник, что выглядит как и все выбранные элементы вместе взятые (сделать новый элемент, клонировать выбранные элементы, и добавить их), но убедится чтобы оставить исходный элемент нетронутым (в противном случае он испортит функциональность - я не могу точно сказать, почему, но он включает в себя много разочаровывающих исключений DOM).

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

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>

для этого есть плагин jQuery UI:https://github.com/shvetsgroup/jquery.multisortable

jsFiddle: http://jsfiddle.net/neochief/KWeMM/

$('ul.sortable').multisortable();

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

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

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

    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 может нуждаться в некоторой копии функциональности обновления, но, вероятно, будет отделена от обновления, потому что если нет изменений - ничего не отправляйте на сервер.

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

Comments

    Ничего не найдено.