27

Chcę mieć listę, która jest sortable, ale chcę też elementy w tym wykazie być droppable do div Mam zdefiniowane jako droppable. Nie mogę znaleźć sposobu, żeby to zrobić. Jakieś pomysły?jQuery Sortable i Droppable

+0

mam podniesioną do [Reportaż prośbę tutaj] (http://bugs.jqueryui.com/ticket/10628) –

Odpowiedz

21

Oto uproszczona wersja rozwiązania Colina.

Największa różnica polega na tym, że to rozwiązanie nie przechowuje całego html elementów sortowalnych, a jedynie aktualnie przeciągany element. Następnie zostaje wstawiony do pierwotnej pozycji, jeśli przedmiot zostanie upuszczony na obszar zrzucany.

W każdym razie, oto kod:

<!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> 

To wciąż cierpi na ten sam problem jak roztwór Colina jeśli element jest przeciągnięty do nowej pozycji na liście, a następnie spadła poza zarówno <ul> i droppable <div>. Element nie zostanie zresetowany, ale zajmie ostatnią pozycję na liście (testowane w Google Chrome). W każdym razie można to łatwo rozwiązać za pomocą myszki wykrywającej wykrycie lub nawet pożądanego zachowania.

+1

Użyłem odmiany tego w moim projekcie. Dziękujemy +1 –

+0

Kod z góry http://codepen.io/tcosentino/pen/myVEEJ <- nie wiesz, jak to się skończyło z "VEEJ" –

+0

Czy naprawdę trzeba zapisać stan i zależy od jego poprawności? Wydaje się, że możliwa jest praca z wartościami przesunięcia/przesunięcia myszy. –

0

spędziłem cały dzień na to, i stałam się dużo bliżej, ale wciąż nie robi, jak chciałbym. Mam teraz funkcję, której potrzebuję, ale pojawia się błąd JavaScript.

Problem jest coraz listy sortable, aby powrócić do swojej poprzedniej pozycji, jeśli element jest odrzucany w droppable, zamiast na liście. Obecnie zapisuję plik HTML, a następnie przepisuję go w funkcji upuszczania. To działa, ale jego podanie mi zmiennej jquery jest błędem zerowym. Czy ktoś może znaleźć lepsze rozwiązanie?

Kod:

<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

O ile mogę powiedzieć, problem z poprzednim kodem napisałem jest to, że funkcja Kropla droppable był już nazywany przed mouseUp z sortable, a ponieważ przepisał lista, którą sortable się gniewała (z powodu braku lepszych warunków). To trochę przypuszczenie.

Patrząc na końcowym kodu:

<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> 

Mnóstwo dziwactw zaangażowane są tutaj.

Próbowałem zapisać #sortable html na początku zdarzenia sortable, ale to get jest wywoływane po zastosowaniu wszystkich ui-css, a skończyło się umieszczaniem elementów listy w zwariowanych miejscach. Musiałem więc użyć funkcji mousedown na LI.

setSortable jest w funkcję, ponieważ zdarzeniem przystanek przepisuje sortable, która jest „recursive” chyba. Nie jestem pewien dokładnej terminologii tutaj, ale możemy przejść irytująco mylące.

Na szczęście funkcja upuszczania droppable zostaje wywołana przed funkcją zatrzymywania sortowania, więc udało mi się ustawić globalną "zrzuconą" zmienną, która była używana do sprawdzenia, czy element został upuszczony.

nadal jestem zaskoczony nie było łatwiej zrobić, myślałem jQuery miałby funkcje do obsługi to dużo lepiej. Być może czegoś brakuje?

+0

Proszę o moją nieco uproszczoną wersję. – Reimund

+0

Proszę [edytuj] i zaktualizuj swoją odpowiedź zamiast tworzyć nowe ... –

0

był w stanie uzyskać podobny rezultat końcowy poprzez nadanie każdej tarczy div własnych sortables.

I wtedy, poprzez connectWith, uczyniłem wszystkie sortable zdolne do łączenia i udostępniania draggables.

Coś jak:

var connects = '#main_sortable, div.target'; 
$('#main_sortable').sortable({ connectWith: connect }); 
$('div').sortable({ connectWith: connect}); 
0

Jeśli można zezwolić inne obszary droppable być sortable jak dobrze można użyć connectWith option ze wspólnym selektora:

<div id="droppable1" class="droppable-area"></div> 
<div id="droppable2" class="droppable-area"></div> 
<div id="droppable3" class="droppable-area"></div> 

kod jQuery by następnie być:

$('.droppable-area').sortable({ connectWith: '.droppable-area' }); 

To rozwiązanie sprawdziło się doskonale dla mnie tak.

1

Nie dokładnie to, o co prosiłeś, ale potrzebowałem początkowego pojemnika, w którym przedmioty mogły zostać przeciągnięte do innego sortowalnego pojemnika - i pomyślałem, że powinienem się nim podzielić. Był to, jak się go osiągnąć (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/

Powiązane problemy