7

RESOLVEDziehbar Element Make sortierbar innerhalb abwerfbaren mit jQuery UI

So studierte ich sortable() mit den connectWith Attribute ein bisschen mehr und fand die Lösung einfacher war als ich erwartet hatte, aber ich war darüber Art von rückwärts zu denken, weil von draggable() und droppable().

Hier ist die Geige: http://jsfiddle.net/DKBU9/12/


Original Frage folgt:

Dies ist eine Erweiterung einer früheren SO Frage, die ich fühlte getrennt gehalten werden sollte.

Die ursprüngliche Frage ist hier: jQuery UI - Clone droppable/sortable list after drop event. Es betrachtet die Reinitialisierung des Drop-Handlers auf geklonte Elemente.

Obendrein versuche ich, die Elemente, die aus der ursprünglichen Liste gezogen wurden, in den Dropdown-Listen zu sortieren. Hier

ist eine Geige im Wesentlichen das aktuelle Verhalten als Ergebnis der ursprünglichen Frage darstellt: http://jsfiddle.net/DKBU9/7/

und den erforderlichen Code, weil so mag diese Stellen beschweren und aufblasen:

HTML

<ul id="draggables"> 

    <li>foo1</li> 
    <li>foo2</li> 
    <li>foo3</li> 

</ul> 

<ul class="droppable new"> 

</ul> 

JS

$(function() { 

    $('#draggables > li').draggable({ 
     appendTo: 'document', 
     revert: 'invalid' 
    }); 

    $('.droppable > li').draggable({ 
     appendTo: 'document', 
     revert: 'invalid' 
    }); 

    $('#draggables').droppable({ 
     accept: '.droppable > li', 
     drop: function(event, ui) { 
      ui.draggable.detach().css({top: 0,left: 0}).appendTo($(this)); 
      cleanUp(); 
     } 
    }); 

    initDrop($('.droppable')); 

}); 

function initDrop($element) { 

    $element.droppable({ 
     accept: function(event, ui) { 
      return true; 
     }, 
     drop: function(event, ui) { 
      if($(this).hasClass('new')) { 
       var clone = $(this).clone();     
       $(this).after(clone); 
       $(this).removeClass('new'); 
       initDrop(clone); 
      } 
      ui.draggable.detach().css({top: 0,left: 0}).appendTo($(this)); 
      cleanUp(); 
     } 
    }).sortable({ 
     items: 'li', 
     revert: false, 
     update: function() { 
      cleanUp(); 
     } 
    }); 

} 

function cleanUp() { 

    $('.droppable').not('.new').each(function() { 
     if($(this).find('li').length == 0) { 
      $(this).remove(); 
     } 
    }); 

} 

Referenzfrage: Jquery UI combine sortable and draggable

Ich habe versucht, diese SO-Frage zu verwenden, um mein Problem zu lösen, da das Ergebnis genau das ist, was ich erreichen möchte, insbesondere die letzte Geige in den Kommentaren der angenommenen Antwort Ich kann mir nicht vorstellen, wie ich es angesichts der kleinen Unterschiede an meinen Code anpassen kann. Zum Beispiel klont die Geige in dieser Frage das Ziehbare, anstatt das eigentliche Element zu ziehen, und im Gegensatz zu meinem erlaubt es nicht, Elemente in die Anfangsliste zurück zu ziehen.

Also jede Hilfe zu versuchen, dieses Ergebnis für meinen Code zu erhalten würde sehr geschätzt werden.

Auch in diesem Beispiel wird das Attribut accept als eine Funktion gesetzt, die true zurückgibt. Was ist der Grund dafür? Bedeutet das nicht, dass es irgendetwas oder irgendein ziehbares Element akzeptieren wird?

EDIT: Ich las ein paar Antworten, die nur sortierbar() mit dem connectWith-Attribut verwendet, aber aus irgendeinem Grund habe ich nicht gedacht, was ich getan habe, teilweise weil ich nicht wollte, dass die erste Liste sein sortierbar. Die Verwendung von sortable() allein scheint jedoch die Funktionalität zu erhalten, nach der ich gesucht habe, aber ich habe noch nicht alle Event-Handler angepasst.

+0

Meine Antwort wird erlauben, dass die ursprüngliche Liste nicht sortiert werden kann wie bei Ihrer Bearbeitung, aber wenn Sie damit einverstanden sind, dass sie sortierbar ist, dann sollten Sie mit Ihrer gehen, da es einfacher ist. – acarlon

+0

Ja, ich schätze deine Zeit und deinen Einsatz sehr, aber ich werde dabei bleiben, da es nicht wirklich eine große Sache ist, dass die anfängliche Liste sortierbar ist. – Bobe

Antwort

4

Siehe this fiddle.

Es wird die Elemente in den neuen Listen ablegen und sortierbar machen, aber nicht in der ursprünglichen (wie Sie bearbeiten).

Es gibt ein paar Tricks:

1) Beginnend mit dem ziehbar, habe ich eine neue Funktion, weil wir einen Platzhalter (verwenden Sie einen Klon), so dass die Behälter über nicht während des Drag springen lassen müssen und Wir müssen das neue Element als ziehbar initialisieren.

function initDraggable($element) 
{ 
    $($element).draggable({ 
     connectToSortable: '.droppable',  
     revert: function(droppableObj) 
     { 
      if(droppableObj === false) 
      {     
       $(this).removeClass('dragging'); 
       return true; 
      } 
      else 
      {    
       return false; 
      } 
     }, 
     helper: 'clone', 
     start: function(e, ui) 
     {   
      $draggingParent = $(this).parent(); 
      $(this).addClass('dragging'); 
     } 
    }); 
} 

Notiere die connectToSortable: mit .droppable (Als Bereinigungs, ich glaube, Sie abwerfbaren sortierbar ändern sollte);

Beachten Sie auch revert: - dies gibt uns die Möglichkeit, die 'Drag' -Klasse (die das ursprüngliche (geklonte) Element unsichtbar macht) beim Zurücksetzen zu entfernen.

Schließlich gibt es start, die die "Ziehen" -Klasse hinzufügt, die das ursprüngliche (geklonte) Element beim Ziehen unsichtbar macht. Außerdem wird das $ draggingParent festgelegt, mit dem überprüft wird, ob das Element von #draggables oder .droppables gezogen wird.

2) Dann gibt es die droppable() für die #draggables:

$("#draggables").droppable({  
    drop: function(ev, ui) { 
     if($draggingParent[0] === $(ui.helper).parent()[0]) 
     { 
      //dragged from draggables to draggables 
      $(ui.draggable).removeClass('dragging'); 
     } 
     else 
     {    
      if(ui.draggable.parent()) 
      var $clone = $(ui.draggable).clone(); 
      $(ui.draggable).remove(); 
      $clone.removeClass(); 
      $clone.removeAttr('style'); 
      initDraggable($clone); 
      $(this).append($clone);   
     } 
    } 

Beachten Sie, dass die drop Prozedur prüft, ob dieses Element aus #draggables oder .droppables fallen gelassen wird und entsprechend agiert.

3) Schließlich, wie Sie bereits erwähnt, wollen wir wirklich die abwerfbaren sortierbar sein:

function initDroppableSort($element) {  
    $element.sortable({ 
     items: 'li', 
     connectWith: ".droppable,#draggables", 
     revert: true, 
     stop: function(event, ui) { 
      $(ui.item).removeClass('dragging'); 
      $('.dragging').remove(); 
      if($(this).hasClass('new')) { 
       var clone = $(this).clone();     
       clone.empty(); 
       $(this).after(clone); 
       $(this).removeClass('new'); 
       initDroppableSort(clone); 
      }    
      cleanUp(); 
     } 
    }); 

} 

Notiere die connectWith und speziell, dass es sowohl auf .droppable und #draggables bezieht.

Verwandte Themen