jQuery сортируемый и отбрасываемый - PullRequest
27 голосов
/ 19 января 2010

Я хочу иметь список, который можно сортировать, но я также хочу, чтобы элементы этого списка можно было сбрасывать в элементы div, которые я определил как сбрасываемые. Я не могу найти способ сделать это. Есть идеи?

Ответы [ 6 ]

22 голосов
/ 06 декабря 2010

Вот упрощенная версия решения Колина.

Самым большим отличием является то, что это решение хранит не весь 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>

Он по-прежнему страдает той же проблемой, что и решение Колина, если элемент перетаскивается на новую позицию в списке, а затем выпадает за пределы как <ul>, так и <div>. Затем элемент не будет сброшен, но займет последнюю позицию в списке (проверено в Google Chrome). В любом случае, это легко решается с помощью обнаружения мыши или даже может быть желательным поведением.

4 голосов
/ 20 января 2010

Насколько я могу судить, проблема с предыдущим кодом, который я разместил, заключалась в том, что функция перетаскивания 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 в стартовом событии sorttable, но этот get вызывается после того, как все ui-css применено, и в итоге поместил элементы списка в безумные места. Итак, мне нужно было использовать функцию mousedown на LI.

setSortable находится в функции, потому что событие stop перезаписывает sortable, что, я думаю, является "рекурсивным". Не уверен, точная терминология здесь, но мы можем пойти с досадно запутывающим.

К счастью, функция отбрасывания droppable вызывается перед функцией остановки sortables, поэтому я смог установить глобальную переменную «drop», которая использовалась для проверки, был ли удален элемент.

Я все еще удивлен, что это было не так легко сделать, я думал, что jQuery будет иметь функции, чтобы справиться с этим намного лучше. Возможно, я что-то упустил?

1 голос
/ 17 мая 2017

Не совсем то, что вы просили, но мне нужен был первоначальный контейнер, куда можно было перетащить предметы в другой сортируемый контейнер - и подумал, что я должен поделиться им. Вот как я этого добился (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/

0 голосов
/ 25 января 2013

Если вы также можете разрешить сортировку других областей, доступных для сбрасывания, вы можете использовать connectWith опция с общим селектором:

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

В любом случае, это решение прекрасно сработало.

0 голосов
/ 02 мая 2011

Был в состоянии получить аналогичный конечный результат, сделав каждый из целевых DIVs их собственные сортируемые.

Затем я через connectWith сделал все сортируемые файлы способными подключать и обмениваться перетаскиваемыми файлами.

Что-то вроде:

var connects = '#main_sortable, div.target';
$('#main_sortable').sortable({ connectWith: connect });
$('div').sortable({ connectWith: connect} );
0 голосов
/ 20 января 2010

Я провел весь день на этом, и я стал намного ближе, но все еще не так хорошо, как хотелось бы. Теперь у меня есть нужная функциональность, но выдается ошибка Javascript.

Проблема в том, что сортируемый список возвращается на прежнюю позицию, если элемент сбрасывается в отбрасываемый объект, а не в список. В настоящее время я сохраняю html onmousedown, а затем переписываю html в функцию drop для 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...