jQuery Sortable – select并拖动多个列表项目

我有一个有“可用框”列表的devise,用户将框从“可用框”列表拖到“我的框”列表中。

用户通常不会一次拿多个盒子(最多20个),一旦他们把盒子拖回到“可用盒子”列表中以返回它们。

jQuery可sorting允许我一次拖动一个框,从用户的angular度来看是不可取的。 我一直无法想出一个简单的解决scheme来解决这个问题。

我可能不得不完全想出一个不同的UI方法,但是首先有没有人可以提出这样的build议?

谢谢!

我没有使用可sorting的这个工作,但是我使用了可拖拽和可拖拽。 我不知道我是否覆盖了所有你需要的function,但这应该是一个很好的开始( 演示在这里 ):

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

工作解决scheme

tl; dr : 参考这个小提琴的工作答案 。


我到处寻找一个解决scheme, 将多个选定的项目从一个可sorting的项目拖到一个可连接的可sorting项目中 ,这些答案是我能find的最好的答案。

然而…

接受的答案是越野车, @ Shanimal的答案是接近的 ,但不完整。 我拿了@ Shanimal的代码,并build立在它上面。

我解决了:

  • @Ryan提到的消失的列表项错误 ,
  • 清理了HTML中的语法错误(缺less结束标签和嵌套的<li/> s)。

我补充说:

  • 正确的Ctrl +点击 (或Cmd +点击,如果在Mac上)支持select多个项目。 点击没有 按住Ctrl键将导致该项目被选中,并且同一列表中的其他项目被取消select 。 这与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 – 将可拖动的列表项连接到一个可sorting的,具有多选function。 它的设置几乎完全一样,因为jQuery UI小部件非常相似。 一个用户界面技巧是确保你有delay参数为可拖动或可选项设置,所以你可以点击select多个项目而不发起拖动。 然后你构build一个看起来像所有选定的元素放在一起的助手(创build一个新的元素,克隆选定的项目,并追加它们),但一定要保持原来的项目不变(否则它搞砸了function – 我不能说究竟是为什么,但它涉及到很多令人沮丧的DOMexception)。

我还添加了Shift + Clickfunction,以使其function更像本地桌面应用程序。 我可能不得不开始一个博客,所以我可以详细阐述这一点:-)

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

Aaron Blenkush的解决scheme有一个重大的错误:删除和添加项目的可sorting列表中断结构; 刷新可以提供帮助,但是如果其他函数处理列表,则需要刷新所有触发器,这一切都变得过于复杂。

在分析了一些在stackoverflow的解决scheme后,我总结了以下内容:

不要使用助手 – 使用启动function,因为它已经有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(); }, 

停止function可能需要更新function的一些副本,但很可能与更新分开,因为如果没有更改 – 不要提交任何东西到服务器。

添加:保存拖动项目的顺序。