7

排序使內可放開拖動元素議決使用jQuery UI

於是我研究sortable()connectWith屬性多一點,並找到了解決辦法是比我預想的更簡單,但我想它像是倒退,因爲draggable()droppable()

這裏的小提琴:http://jsfiddle.net/DKBU9/12/


原題如下:

這是以前的SO問題,我覺得應該保持獨立的延伸。

原始問題在這裏:jQuery UI - Clone droppable/sortable list after drop event。它認爲重新初始化克隆元素上的droppable處理程序。

最重要的是,我嘗試允許從最初列表中拖拽的元素在可拖拽列表中排序。

這裏是一個小提琴基本上是說明按照原來的問題的結果,當前的行爲:http://jsfiddle.net/DKBU9/7/

和所需的代碼,因爲這麼喜歡抱怨和臃腫這些帖子:

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

} 

參考問題:Jquery UI combine sortable and draggable

我一直在試圖用這個SO問題來解決我的問題,結果正是我想要實現的,特別是最後一個小提琴在接受答案的評論中提供的,但考慮到細微差異,我似乎無法弄清楚如何使其適應我的代碼。例如,該問題中的小提琴克隆可拖動而不是拖動實際元素,與我的不同,不允許將元素拖回初始列表。

因此,任何幫助嘗試獲得我的代碼的結果將不勝感激。

此外,在該示例中,accept屬性被設置爲返回true的函數。這是什麼原因?這不僅僅意味着它會接受任何東西,或任何可拖動的元素?

編輯:我讀了一些只是使用sortable()與connectWith屬性的答案,但由於某種原因,我不認爲它做了我所需要的,部分原因是我不想讓最初的列表成爲也可以排序。但是,單獨使用sortable()似乎獲得了我之後的功能,但我還沒有適應所有的事件處理程序。

+0

我的答案將允許最初的列表不能按照您的編輯進行排序,但如果您確定可以排序,那麼我認爲您應該隨身攜帶,因爲它更簡單。 – acarlon

+0

是的,我非常感謝你的時間和精力,但我會堅持這一點,因爲初始列表可排序並不是什麼大不了的事情。 – Bobe

回答

4

請參閱this fiddle

它會使項目在新列表中可放置和排序,但不會在最初(根據您的編輯)進行排序。

有幾個技巧:

1)可拖動開始,我添加了一個新功能,因爲我們需要留下一個佔位符(使用克隆),從而使容器不拖動過程中跳躍和左右我們需要將新元素初始化爲可拖動。

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

connectToSortable:.droppable(作爲清理,我想你應該改變投擲的可排序);

還請注意revert: - 這使我們有機會去除'拖拽'類(這會使原始(克隆)元素不可見)恢復。

最後,有start,它增加了「拖動」類,這使得原始(克隆)元素在拖動過程中不可見。它還設置了$ draggingParent,用於檢查項目是從#draggables還是.droppables被拖動。

2)再有就是droppable()#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);   
     } 
    } 

注意,drop處理程序檢查該元素是否從#draggables.droppables下降,相應地動作。

3)最後,因爲你已經提到的,我們真的希望可放開可排序:

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

} 

注意connectWith特別,它指的是.droppable#draggables