2009-04-01 24 views
27

Tôi đang tìm cách triển khai giao diện web với một số mục có thể được chọn và kéo xung quanh để định vị chúng, hoặc theo nhóm hoặc đơn lẻ. Thay vì giống như Windows Desktop, thực sự.Có một plugin JQuery kết hợp Draggable và có thể chọn

Chúng tôi đang sử dụng JQuery, vì vậy việc bổ sung vào đó sẽ là lựa chọn đầu tiên. JQuery UI Draggables và Selectables cá nhân làm được nhiều thứ mà chúng ta muốn, nhưng không thực sự làm việc cùng nhau để tạo ra hiệu ứng mà chúng ta đang tìm kiếm.

Tôi hoàn toàn bị choáng ngợp bởi trang web plugin JQ (thuật toán 'phổ biến' dường như không hữu ích), và sẽ hướng dẫn cách tốt nhất để tránh nhiều bánh xe tái tạo ở đây, như tôi đoán rằng ẩn dụ này đã được thực hiện.

+0

Mã trong http://stackoverflow.com/questions/34698117/elements-became-randomly-non-resizable-after-dragging queston cũng chứa câu trả lời cho câu hỏi này Tuy nhiên mã trong câu trả lời gây mất ngẫu nhiên có thể thay đổi kích thước khi kéo – Andrus

Trả lời

19

Tôi cũng cần làm điều tương tự và tôi không muốn sử dụng tiện ích mở rộng giao diện từ eyecon.ro. Sau một số nghiên cứu, tôi tìm thấy Combining Selectables And Draggables Using jQuery UI. Nó là độc đáo nói nhưng để làm cho đoạn mã chạy bạn phải đào sâu vào nó. Tôi đã có thể làm cho nó hoạt động. Tôi hơi thay đổi nó, đây là cách của tôi để làm cho nó được thực hiện. Nó cần sửa đổi để sử dụng trên mức sản xuất, nhưng tôi hy vọng nó sẽ giúp.

// this creates the selected variable 
// we are going to store the selected objects in here 
var selected = $([]), offset = {top:0, left:0}; 

// initiate the selectable id to be recognized by UI 
$("#selectable").selectable({ 
    filter: 'div', 
}); 

// declare draggable UI and what we are going to be doing on start 
$("#selectable div").draggable({ 
    start: function(ev, ui) { 
     selected = $(".ui-selected").each(function() { 
      var el = $(this); 
      el.data("offset", el.offset()); 
     }); 

     if(!$(this).hasClass("ui-selected")) $(this).addClass("ui-selected"); 
     offset = $(this).offset(); 
    }, 
    drag: function(ev, ui) { 
     var dt = ui.position.top - offset.top, dl = ui.position.left - offset.left; 

     // take all the elements that are selected expect $("this"), which is the element being dragged and loop through each. 
     selected.not(this).each(function() { 
      // create the variable for we don't need to keep calling $("this") 
      // el = current element we are on 
      // off = what position was this element at when it was selected, before drag 
      var el = $(this), off = el.data("offset"); 
      el.css({top: off.top + dt, left: off.left + dl}); 
     }); 
    } 
}); 

CSS Styles để có thể xem những gì đang xảy ra:

#selectable { width: 100%; height: 100%;} 
#selectable div { 
    background: #ffc; 
    line-height: 25px; 
    height: 25px; 
    width: 200px; 
    border: 1px solid #fcc; 
    } 
#selectable div.ui-selected { 
    background: #fcaf3e; 
    } 
#selectable div.ui-selecting { 
    background: #8ae234; 
    } 

HTML Markup:

<div id="selectable"> 
    <div>item 1</div> 
    <div>item 2</div> 
    <div>item 3</div> 
    <div>item 4</div> 
</div> 
+2

vấn đề chính với mã này nó không cho phép bạn kiểm soát nhấp để thêm các mục bổ sung. –

+2

Điều này dường như chỉ cho phép bạn kéo nhiều mục đã chọn, tôi không thể chọn bất kỳ mục nào có thể chọn với một cú nhấp chuột (hãy để một lần nhấp ctrl) – digout

+0

Mã này gây mất ngẫu nhiên có thể thay đổi kích thước khi kéo. Điều này được đăng trong http://stackoverflow.com/questions/34698117/elements-became-randomly-non-resizable-after-dragging Cách khắc phục? – Andrus

4

Tôi đã thực hiện một số sửa đổi để câu trả lời được đưa ra bởi Sinan Yasar. Nó không hoàn hảo nhưng nó đã cư xử nhiều hơn như tôi sẽ ngoại trừ.

Một bổ sung chính là trình nghe nhấp chuột gọi là chọn.

// manually trigger the "select" of clicked elements 
$("#selectable > div").click(function(e){ 
    if (e.metaKey == false) { 
     // if command key is pressed don't deselect existing elements 
     $("#selectable > div").removeClass("ui-selected"); 
     $(this).addClass("ui-selecting"); 
    } 
    else { 
     if ($(this).hasClass("ui-selected")) { 
      // remove selected class from element if already selected 
      $(this).removeClass("ui-selected"); 
     } 
     else { 
      // add selecting class if not 
      $(this).addClass("ui-selecting"); 
     } 
    } 

    $("#selectable").data("selectable")._mouseStop(null); 
}); 

Bạn có thể thấy một ví dụ làm việc đầy đủ ở đây: http://jsfiddle.net/DXrNn/4/

Ngoài ra còn có một plugin jquery-ui có sẵn mà không chỉ rằng: http://code.google.com/p/jqdragdropmultiselect/ Các probleme là nó không nhìn duy trì.

chỉnh sửa: nếu bạn xác định tùy chọn "bộ lọc" của đối tượng có thể kéo, bạn sẽ cần phải gọi selectable.refresh() trước selectable._mouseStop (null).

$("#selectable > div").click(function(e){ 
    ... 
    var selectable = $("#container").data("selectable"); 
    selectable.refresh(); 
    selectable._mouseStop(null); 
    ... 
+2

Không có vấn đề bao nhiêu tôi thử giải pháp của bạn trong jsfiddle, tôi không thể có được bất kỳ yếu tố để kéo, chỉ chọn. Chrome 19. – trusktr

+1

@trusktr Hãy thử tôi với 'jQuery 1.8.3' và' jQueryUI 1.9.2' – mraaroncruz

+1

@trusktr vì http://stackoverflow.com/questions/14366322/error-jquery-ui-draggable-cannot- này read-property-msie có vẻ như bạn sẽ cần jQueryUI 1.10 để sử dụng jQuery EDGE – mraaroncruz

10

Câu hỏi này có liên quan nhưng cũ; vậy là câu trả lời. Here's an updated version của jsfiddle @ idFlood của, làm việc với jQuery 1.9.1 + jQueryUI 1.10.3:

// store selected elements and the offset of the dragged element 
var selected = $([]), offset = {top:0, left:0}; 

$("#selectable > div").draggable({ 
    start: function (event, ui) { 
     var $this = $(this); 

     if ($this.hasClass("ui-selected")) { 
      // if this is selected, attach current offset 
      // of each selected element to that element 
      selected = $(".ui-selected").each(function() { 
       var el = $(this); 
       el.data("offset", el.offset()); 
      }); 
     } else { 
      // if this is not selected, clear current selection 
      selected = $([]); 
      $("#selectable > div").removeClass("ui-selected"); 
     } 
     offset = $this.offset(); 
    }, 

    drag: function (event, ui) { 
     // drag all selected elements simultaneously 
     var dt = ui.position.top - offset.top, dl = ui.position.left - offset.left; 
     selected.not(this).each(function() { 
      var $this = $(this); 
      var elOffset = $this.data("offset"); 
      $this.css({top: elOffset.top + dt, left: elOffset.left + dl}); 
     }); 
    } 
}); 

// enable marquee selecting and deselect on outside click... 
$("#selectable").selectable(); 

// ...but manually implement selection to prevent interference from draggable() 
$("#selectable").on("click", "div", function (e) { 
    if (!e.metaKey && !e.shiftKey) { 
     // deselect other elements if meta/shift not held down 
     // $("#dc-modules .dc-module").removeClass("ui-selected"); 
     $("#selectable > div").removeClass("ui-selected"); 
     $(this).addClass("ui-selected"); 
    } else { 
     if ($(this).hasClass("ui-selected")) { 
      $(this).removeClass("ui-selected"); 
     } else { 
      $(this).addClass("ui-selected"); 
     } 
    } 
}); 

Tôi đã có một vấn đề với các _mouseStop() gọi ném một lỗi, vì vậy tôi loại bỏ nó; điều này có nghĩa là trạng thái ui-selecting không còn xảy ra khi nhấp chuột, nhưng tất cả các chức năng khác vẫn còn nguyên vẹn.

+0

Giải pháp này hoạt động rất tốt nhưng tôi gặp sự cố khi làm việc đó với khả năng phân tách. Có bất cứ điều gì nội tại đối với giải pháp mà bạn cho rằng sẽ xung đột với droppable hay tôi nên giữ đập đầu của tôi chống lại mã này? –

+0

@ericsoco Mã này gây ra loff ngẫu nhiên có thể thay đổi kích thước khi kéo. Điều này được đăng trong http://stackoverflow.com/questions/34698117/elements-became-randomly-non-resizable-after-dragging Cách khắc phục? – Andrus

Các vấn đề liên quan