Что ж, это выглядит не элегантно, но это делает работу.
Вот jsfiddle, чтобы показать, что я собираюсь объяснить:
http://jsfiddle.net/perrytew/RxKkA/3/
Настройка:
Я удалил ваши идентификаторы для каждого элемента, так как они будут клонированы на копии, чтобы избежать того же идентификатора в документе дважды. Я использую классы вместо этого. Вот как выглядел мой 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>
Чтобы это сработало, я добавил хук к событию 'receive' сортируемого объекта. Когда это сработало, я сделал две вещи:
- установите возврат перетаскиваемого элемента в true, чтобы будущие перетаскивания вернулись назад.
- проверить, существует ли уже элемент в перетаскиваемой таблице. Если это так, я удалил новый.
Кажется, это недостаток дизайна пользовательского интерфейса jquery, потому что даже если для возврата задано значение true, перетаскиваемый элемент все равно удаляется. Он возвращается, но копия все еще появляется в перетаскиваемой таблице. Вот почему я делаю уборку с помощью вызова remove()
. Это кажется хакерским, но дает очень приятный визуальный опыт. Я добавил небольшое исчезающее сообщение, чтобы предупредить пользователя, почему перетаскивание не удалось.
Приветствие.
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;
}