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); },
-
在更新部分:
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的一些副本,但很可能与更新分开,因为如果没有更改 – 不要提交任何东西到服务器。
添加:保存拖动项目的顺序。