jQuery Sortable-выбор и перетаскивание нескольких элементов списка
У меня есть дизайн, где у меня есть список "доступных ящиков", пользователи берут ящики, перетаскивая их из списка "доступные ящики" в список "мои ящики".
пользователи чаще всего берут несколько ящиков одновременно (максимум 20), как только они закончили с полями, они перетаскивают их обратно в список "доступные поля", чтобы вернуть их.
jQuery sortable позволяет мне перетаскивать по одному ящику за раз, что с точки зрения пользователя нежелательно. Я был не в состоянии придумать простое решение вопроса.
возможно, мне придется придумать совершенно другой метод пользовательского интерфейса, но сначала у кого-нибудь есть предложения о том, как это можно сделать?
спасибо!
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 и построил на нем.
я исправил:
- the исчезающий элемент списка ошибка, которую @Ryan упомянул,
- очистил синтаксические ошибки в HTML (отсутствуют закрывающие теги и вложенные
<li/>s).я добавил:
- правильный 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); },
на части обновления:
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