Я хочу иметь отсортированный список, но также хочу, чтобы элементы в этом списке были недоступны для div, которые я определил как droppable. Кажется, я не могу найти способ сделать это. Любые идеи?
JQuery Sortable и Droppable
Ответ 1
Здесь приведена упрощенная версия решения Colin.
Самое большое различие заключается в том, что это решение не хранит весь html сортируемых элементов, а только текущий элемент. Затем он вставлен в исходное положение, если элемент выпадает на область сбрасываемой области.
В любом случае, здесь код:
<!doctype html>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/jquery-ui.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var dropped = false;
var draggable_sibling;
$("#sortable").sortable({
start: function(event, ui) {
draggable_sibling = $(ui.item).prev();
},
stop: function(event, ui) {
if (dropped) {
if (draggable_sibling.length == 0)
$('#sortable').prepend(ui.item);
draggable_sibling.after(ui.item);
dropped = false;
}
}
});
$(".droppable").droppable({
activeClass: 'active',
hoverClass:'hovered',
drop:function(event,ui){
dropped = true;
$(event.target).addClass('dropped');
}
});
});
</script>
<style type="text/css">
#sortable li{
clear:both;
float:left;
}
.droppable {
clear:both;
height:300px;
width:400px;
background-color:#CCC;
}
.droppable.active { background: #CFC; }
.droppable.hovered { background: #CCF; }
.dropped { background: #f52; }
</style>
</head>
<body>
<ul id="sortable">
<li id="one">One</li>
<li id="two">Two</li>
<li id="three">Three</li>
<li id="four">Four</li>
<li id="five">Five</li>
<li id="six">Six</li>
</ul>
<div class="droppable">Drop Here</div>
<div class="droppable">Drop Here</div>
</body>
</html>
Он по-прежнему испытывает ту же проблему, что и решение Colin, если элемент перетаскивается в новую позицию в списке, а затем выходит за пределы <ul>
и droppable <div>
. Затем элемент не будет reset, а займет последнюю позицию в списке (проверен в Google Chrome). Во всяком случае, это легко решить с помощью мыши с обнаружением или даже может быть желательным поведением.
Ответ 2
Насколько я могу судить, проблема с предыдущим кодом, который я опубликовал, заключается в том, что функция drop of droppable вызывалась до того, как была выбрана сортировка, и, поскольку я переписал список, сортировка разозлилась (из-за отсутствия лучших терминов). Это несколько догадка.
Глядя на окончательный код:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.js"></script>
<script type="text/javascript">
var dropped = false;
var templateHtml;
$(document).ready(function(){
setSortable();
$("#droppable").droppable({
activeClass: 'active',
hoverClass:'hovered',
accept:".drop",
drop:function(event,ui){
dropped = true;
//alert(ui.draggable.text());
}
});
});
function setSortable(){
$("#sortable").sortable({
stop:function(event,ui){
if(dropped){
$("#sortable").sortable('destroy').html(templateHtml);
dropped = false;
setSortable();
}
}
});
$("#sortable li").addClass("drop").bind('mousedown',function(){
templateHtml = $("#sortable").html();
});
}
</script>
<style type="text/css">
#sortable li{
clear:both;
float:left;
}
#droppable {
clear:both;
height:300px;
width:400px;
background-color:#CCC;
}
#droppable.active {
background-color:#CFC;
}
#droppable.hovered {
background-color:#CCF;
}
</style>
</head>
<body>
<ul id="sortable">
<li id="one">One</li>
<li id="two">Two</li>
<li id="three">Three</li>
<li id="four">Four</li>
<li id="five">Five</li>
<li id="six">Six</li>
</ul>
<div id="droppable">
Drop Here
</div>
</body>
Здесь задействованы тонны причуд.
Я попытался сохранить #sortable html в стартовом событии sortable, но это вызвано после того, как все приложения ui-css будут применены, и закончил размещение элементов списка в сумасшедших местах. Итак, мне нужно было использовать функцию mousedown на LI.
Функция SetSortable находится в функции, потому что событие остановки перезаписывает сортируемое, которое, как я полагаю, является "рекурсивным". Не уверен, что здесь есть настоящая терминология, но мы можем досадно сбивать с толку.
К счастью, функция droppable drop вызывается до функции остановки сортировки, поэтому мне удалось установить глобальную переменную "drop", которая была использована для проверки того, был ли элемент удален.
Я все еще удивляюсь, что это было нелегко сделать, я думал, что jQuery будет иметь функции, чтобы справиться с этим намного лучше. Возможно, я что-то упустил?
Ответ 3
Я потратил весь день на это, и я стал намного ближе, но все равно не так хорошо, как хотелось бы. Теперь у меня есть функциональность, в которой я нуждаюсь, но возникает ошибка Javascript.
Проблема заключается в том, чтобы сортируемый список возвращался к своей предыдущей позиции, если элемент был сброшен в droppable, а не в списке. В настоящее время я сохраняю html onmousedown, а затем переписываю html в функции drop of droppable. Это работает, но его предоставление переменной jquery имеет нулевую ошибку. Может ли кто-нибудь найти лучшее решение?
код:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.js"></script>
<script type="text/javascript">
var templateHtml;
$(document).ready(function(){
$("#sortable").sortable();
$("#sortable li").addClass("drop").bind('mousedown',function(){
templateHtml = $("#sortable").html();
});
$("#droppable").droppable({
activeClass: 'active',
hoverClass:'hovered',
accept:".drop",
drop:function(event,ui){
$("#sortable").sortable('destroy').html(templateHtml);
$("#sortable").sortable();
$("#sortable li").addClass("drop").bind('mousedown',function(){
templateHtml = $("#sortable").html();
});
}
});
});
</script>
<style type="text/css">
#sortable li{
clear:both;
float:left;
}
#droppable {
clear:both;
height:300px;
width:400px;
background-color:#CCC;
}
#droppable.active {
background-color:#CFC;
}
#droppable.hovered {
background-color:#CCF;
}
</style>
</head>
<body>
<ul id="sortable">
<li id="one">One</li>
<li id="two">Two</li>
<li id="three">Three</li>
<li id="four">Four</li>
<li id="five">Five</li>
<li id="six">Six</li>
</ul>
<div id="droppable">
Drop Here
</div>
</body>
Ответ 4
Получил аналогичный конечный результат, сделав каждый из целевых DIV своих собственных сортировщиков.
Затем я через connectWith сделал все сортировки, способные подключаться и обмениваться перетаскиваемыми файлами.
Что-то вроде:
var connects = '#main_sortable, div.target';
$('#main_sortable').sortable({ connectWith: connect });
$('div').sortable({ connectWith: connect} );
Ответ 5
Если вы можете разрешить сортировку других областей сбрасываемых областей, вы можете использовать connectWith option с общим селектором:
<div id="droppable1" class="droppable-area"></div>
<div id="droppable2" class="droppable-area"></div>
<div id="droppable3" class="droppable-area"></div>
ваш код jQuery будет следующим:
$('.droppable-area').sortable({ connectWith: '.droppable-area' });
Это решение прекрасно работало для меня в любом случае.
Ответ 6
Не совсем то, что вы просили, но мне нужен был начальный контейнер, где элементы можно было перетащить в другой сортируемый контейнер - и подумал, что я должен поделиться им. Так я достиг этого (jQuery 1.8.3):
$("#sortable-list").sortable();
$("#initial-list div").draggable({
revert: true,
revertDuration: 0
});
$("#initial-list").droppable({
accept: ".item-selected",
drop: function(e, ui) {
var dropped = ui.draggable;
var droppedOn = $(this);
var itemInOtherList = $(this).children("#" + dropped.attr('id'));
itemInOtherList.removeClass('ui-state-disabled').draggable({ disabled: false });
dropped.remove();
}
});
$("#sortable-list").droppable({
accept: ".item-initial",
drop: function(e, ui) {
var dropped = ui.draggable;
var droppedOn = $(this);
droppedOn.append(dropped.clone()
.removeAttr('style')
.removeClass("item-initial")
.addClass("item-selected"));
dropped.animate(dropped.data().origPosition, {
complete: function() {
$(this).addClass('ui-state-disabled').draggable({ disabled: true });
}
});
}
});
JSFiddle: http://jsfiddle.net/Muskar/dwz4mvxa/8/