27

Ich möchte eine sortierbare Liste haben, aber ich möchte auch, dass die Elemente in dieser Liste auf die von mir definierten drop-fähigen divaps abgesetzt werden können. Ich kann keinen Weg finden, es zu tun. Irgendwelche Ideen?jQuery Sortierbar und löschbar

+0

ich eine [Feature-Anfrage hier] angehoben haben (http://bugs.jqueryui.com/ticket/10628) –

Antwort

21

Hier ist eine vereinfachte Version von Colins Lösung.

Der größte Unterschied ist, dass diese Lösung nicht das gesamte HTML der sortierbaren Elemente speichert, sondern nur das aktuell gezogene Element. Es wird dann in seine ursprüngliche Position eingefügt, wenn der Gegenstand auf den abwerfbaren Bereich fällt.

Wie auch immer, hier ist der Code:

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

Es ist immer noch das gleiche Problem wie Colins Lösung leidet, wenn ein Element in eine neue Position in der Liste gezogen wird und dann nach außen fiel sowohl die <ul> und die abwerfbaren <div>. Das Objekt wird dann nicht zurückgesetzt, sondern nimmt die letzte Position in der Liste ein (getestet in Google Chrome). Wie auch immer, dies kann leicht mit einer Mausübererkennung gelöst werden oder es kann sogar ein wünschenswertes Verhalten sein.

+1

Eine Variation davon auf meinem Projekt verwendet. Danke +1 –

+0

Code von oben http://codepen.io/tcosentino/pen/myVEEJ <- nicht sicher, wie es mit "VEEJ" landete –

+0

Ist es wirklich notwendig, einen Zustand zu speichern und von seiner Richtigkeit abhängen? Es scheint, als könnte es möglich sein, mit den Drop-Maus-Ereignispositions-/Versatzwerten zu arbeiten. –

0

Ich habe den ganzen Tag damit verbracht, und ich bin viel näher gekommen, aber immer noch nicht so gut, wie ich es möchte. Ich habe jetzt die Funktionalität, die ich brauche, aber ein Javascript-Fehler wird geworfen.

Das Problem besteht darin, dass die sortierbare Liste an die vorherige Position zurückkehrt, wenn das Element in der Dropdown-Liste und nicht in der Liste abgelegt wird. Zur Zeit speichere ich den HTML-Code onmousedown und schreibe dann den HTML-Code in die Drop-Funktion des Droppable um. Dies funktioniert, aber es gibt mir eine JQuery-Variable ist Null-Fehler. Kann jemand eine bessere Lösung finden?

Code:

<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

Soweit ich sagen könnte, das Problem mit dem vorherigen Code, den ich geschrieben ist, dass die Drop-Funktion des abwerfbaren wurde vor dem mouseup der sortierbare genannt zu werden, und da ich neu geschrieben die Liste der Sortierung wurde wütend (aus Mangel an besseren Bedingungen). Das ist eine Vermutung.

Mit Blick auf die endgültige Code:

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

Tonnen Macken sind hier beteiligt.

Ich habe versucht, die #sortable html auf das Start-Ereignis von sortierbar zu speichern, aber das wird aufgerufen, nachdem alle der UI-CSS angewendet wurde, und landete Listenelemente an verrückten Orten. Also musste ich die Mousedown-Funktion auf den LIs verwenden.

Die setSortable ist in einer Funktion, weil das stop-Ereignis die sortierbare umschreibt, die "rekursiv" ist, denke ich. Nicht sicher, die genaue Terminologie hier, aber wir können mit ärgerlich verwirrend gehen.

Glücklicherweise wird die Drop-Funktion des Droppable vor der Funktion zum Stoppen der Sortierung aufgerufen, sodass ich eine globale Variable "droped" festlegen konnte, die verwendet wurde, um festzustellen, ob das Element gelöscht wurde.

Ich bin immer noch überrascht, das war nicht einfacher zu tun, ich dachte, jQuery hätte Funktionen, um es viel besser zu behandeln. Vielleicht vermisse ich etwas?

+0

Bitte meine etwas vereinfachte Version. – Reimund

+0

Bitte [bearbeiten] und aktualisieren Sie Ihre Antwort, anstatt neue zu erstellen ... –

0

Konnte ein ähnliches Endergebnis erzielen, indem jeder der Ziel-DIVs seine eigenen Sorables machte.

Ich dann, über connectWith, machte alle Sortierbar in der Lage zu verbinden und ziehbaren teilen.

Etwas wie:

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

Wenn Sie Ihren anderen abwerfbaren Bereiche als auch sortierbar sein lassen können, können Sie die connectWith option mit einem gemeinsamen Selektor verwenden:

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

Code jQuery würde dann be:

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

Diese Lösung funktionierte wunderbar für mich Ja.

1

Nicht genau das, wonach Sie gefragt haben, aber ich brauchte einen ersten Container, wo die Artikel in einen anderen sortierbaren Container gezogen werden konnten - und dachte, ich sollte es teilen. Das war, wie ich es erreicht (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/