嗯,这感觉不优雅,但它完成了工作。
这是一个 jsfiddle 来展示我要解释的内容:
http://jsfiddle.net/perrytew/RxKkA/3/
设置:
我删除了每个项目的 id,因为它们将被克隆到副本中以避免在文档中两次具有相同的 id。我改用类。这是我的 html 的样子:
<div class="leftDiv">
<div class="item item1">Item 1</div>
<div class="item item2">Item 2</div>
<div class="item item3">Item 3</div>
<div class="item item4">Item 4</div>
<div class="item item5">Item 5</div>
<div class="item item6">Item 6</div>
</div>
<div class="rightDiv">
</div>
<div id='errorMessage'></div>
为了让它工作,我在可排序对象的“接收”事件中添加了一个钩子。触发后,我做了两件事:
- 将拖动的项目的恢复设置为 true,以便将来的拖动会快速恢复。
- 检查该项目是否已存在于放置表中。如果是这样,我删除了新的。
这似乎是 jquery ui 的设计缺陷,因为即使将 revert 设置为 true,拖动的项目仍然会被丢弃。它会还原,但副本仍然出现在放置表中。这就是我使用remove() 调用进行清理的原因。感觉很hackish,但它提供了非常令人满意的视觉体验。我添加了一条淡出消息来提醒用户拖动失败的原因。
干杯。
Javascript:
$(document).ready(function(){
$(".leftDiv .item").draggable({
helper: function(ev, ui) {
return "<span class='helperPick'>"+$(this).html()+"</span>";
},
connectToSortable: ".rightDiv"
});
$(".rightDiv").sortable({
'items': ".item",
'receive': function(event, ui){
// find the class of the dropped ui, look for the one
//with the integer suffix.
var clazz = getClassNameWithNumberSuffix(ui.item);
$('.leftDiv .' + clazz).draggable( "option", "revert", true );
if($('.rightDiv .' + clazz).length > 1){
$('.rightDiv .' + clazz + ':not(:first)').remove();
var msg = $('#errorMessage');
msg.html(ui.item.html() + ' already added. Duplicates not allowed');
msg.show();
msg.fadeOut(3000);
}
}
});
});
function getClassNameWithNumberSuffix(el) {
var className = null;
var regexp = /\w+\d+/;
$($(el).attr('class').split(' ')).each(function() {
if (regexp.test(this)) {
className = this;
return false;
}
});
return className;
}
CSS:
.leftDiv, .rightDiv {width:120px; float:left; border:1px solid #000;
padding:5px; margin:10px; min-height:130px}
.rightDiv {margin-left:40px}
.item {height:20px; line-height:20px; text-align:center;
border:1px solid #EEE; background-color:#FFF}
.helperPick {border:1px dashed red; height:20px; line-height:20px;
text-align:center; width:120px}
#errorMessage{
margin:10px;
clear:both;
color:red; font-weight:bold;
}