2010-06-21 32 views
28

Tôi có phần tử có thể kéo và phần tử có thể phân đoạn. Một khi các mục kéo rơi trên vùng thả tôi đang cố gắng để thực hiện mã giả jquery sau:cách hoàn nguyên vị trí của giao diện người dùng jquery có thể kéo được dựa trên điều kiện

if(draggedelement == value){ 

$(draggedelement).hide(); 

} 
else{ 

$(draggedelement).revert(); 

} 

nơi revert() chức năng sẽ di chuyển mục kéo trở lại postion ban đầu của nó.

Làm cách nào để thực hiện điều này?

P.S. Tôi nhận thức được tùy chọn 'hoàn nguyên' có thể kéo được, tuy nhiên điều này chỉ kích hoạt nếu mục được kéo không làm cho nó rơi vào vùng thả xuống.

Trả lời

70

Có là một số tùy chọn tích hợp cho điều này, trên .draggable() của bạn, đặt revert option thành 'invalid' và tùy chọn sẽ quay lại nếu không giảm thành công vào một droppable, như thế này:

$("#draggable").draggable({ revert: 'invalid' }); 

Sau đó, trong .droppable() thiết lập của bạn những gì có giá trị trong một thả bằng cách sử dụng accept option, ví dụ:

$("#droppable").droppable({ accept: '#draggable' });​ 

Bất cứ điều gì không phù hợp với chọn này được thiết lập lại khi bạn cho phép đi, you can see a full demo here. Các tùy chọn chấp nhận cũng có một hàm nếu bạn cần lọc một selector không thể cung cấp, như thế này:

$("#droppable").droppable({ 
    accept: function(dropElem) { 
    //dropElem was the dropped element, return true or false to accept/refuse it 
    } 
});​ 
+2

+1 trợ giúp tuyệt vời! Cảm ơn! – Sisir

4

Thử thêm mã đó vào sự kiện "thả". Đây là demo.

HTML

<div class="draggable ui-widget-content correct"><p>1</p></div> 
<div class="draggable ui-widget-content"><p>2</p></div> 
<div class="draggable ui-widget-content"><p>3</p></div> 
<div class="draggable ui-widget-content"><p>4</p></div> 
<br style="clear: both"> 
<div id="droppable" class="ui-widget-header"> 
    <p>Drop me here</p> 
</div> 

Script

$(function() { 

$(".draggable").draggable({ revert: true }); 

$("#droppable").droppable({ 
    activeClass: 'ui-state-hover', 
    hoverClass: 'ui-state-active', 
    // uncomment the line below to only accept the .correct class.. 
    // Note: the "drop" function will not be called if not ".correct" 
    // accept : '.correct', 
    drop: function(event, ui) { 
    // alternative method: 
    // if (ui.draggable.find('p').text() == "1") { 
    if (ui.draggable.is('.correct')) { 
    $(this).addClass('ui-state-highlight').find('p').html('You got it!'); 
    // cloning and appending prevents the revert animation from still occurring 
    ui.draggable.clone(true).css('position', 'inherit').appendTo($(this)); 
    ui.draggable.remove(); 
    } else { 
    $('#droppable > p').html('Not that one!') 
    setTimeout(function(){ $('#droppable > p').html('Drop here'); }, 1000); 
    } 
    } 
}); 

}); 

Như bạn thấy trong kịch bản, bạn có thể tìm kiếm các lớp .correct hoặc văn bản bên trong (nhận xét ra dòng)

1
$("#droppable").droppable({ 
    accept: function(dropElem) { 
     //dropElem was the dropped element, return true or false to accept/refuse it 
     if($(this).data('stoneclass') == dropElem.attr("id")){ 
      return true; 
    } 
} 
});​ 

này đã được sử dụng để chỉ chấp nhận một kéo, từ một nhóm các draggables; với một giọt có thể phân hủy chính xác, trong một nhóm các vật phẩm có thể phân hủy.

Tái bút: xin lỗi vì ngôn ngữ nếu nó không phải là dễ hiểu =)

4

Tôi đã có một trường hợp sử dụng mà tôi đã phải chạy một số logic trong phương pháp thả của droppable để xác định xem có thể kéo nên hoàn nguyên. Tôi đã sử dụng sau đây để đạt được điều này:

$('.draggable-elements').draggable({ 
 
    revert: function() { 
 
    if ($(this).hasClass('drag-revert')) { 
 
     $(this).removeClass('drag-revert'); 
 
     return true; 
 
    } 
 
    } 
 
}); 
 

 
$('.droppable-elements').droppable({ 
 
    drop: function(event, ui) { 
 
    if (% conditional logic check here %) { 
 
     return $(ui.draggable).addClass('drag-revert'); 
 
    } 
 
    } 
 
});

trường hợp sử dụng của tôi là một bảng trong đó mỗi tế bào là một droppable đại diện cho một khoảng thời gian 5 phút. Kéo của tôi là các đặt chỗ bắt đầu trong một ô, nhưng chạy qua nhiều ô liên tiếp để thể hiện thời gian đặt trước.

Tôi không muốn bất kỳ hình thu nhỏ nào có thể chồng lên nhau, vì điều đó sẽ đại diện cho đặt phòng đôi. Vì vậy, sau khi thả, tôi tìm thấy tất cả các vật kéo trong hàng, ngoại trừ cái tôi vừa di chuyển và kiểm tra bất kỳ sự chồng chéo nào.Nếu có một chồng chéo, logic điều kiện của tôi trả về true và tôi hoàn nguyên khả năng kéo được.

Giai đoạn tiếp theo là kích hoạt cuộc gọi ajax để cập nhật cơ sở dữ liệu, nếu logic phía máy chủ cho biết di chuyển không hợp lệ, tôi hy vọng trả lại trạng thái lỗi và hoàn nguyên khả năng kéo.

P.S. đây là câu trả lời đầu tiên của tôi, xin lỗi nếu tôi đã làm bất cứ điều gì sai trái. Lời khuyên về cách cung cấp câu trả lời tốt sẵn sàng chấp nhận.

Chỉnh sửa: Sau khi thử cuộc gọi AJAX, tôi nhận ra có một cửa sổ cơ hội cho hàm droppable.drop thực hiện điều đó trước khi chức năng draggable.revert chạy. Vào lúc cuộc gọi AJAX của tôi trả về false, cửa sổ đã trôi qua và lớp được thêm vào quá muộn để draggable.revert phản ứng lại.

Như vậy, tôi không còn dựa vào chức năng draggable.revert, thay vì diễn xuất hoàn toàn vào các phản ứng AJAX và nếu sai sự thật, sử dụng animate() để trả lại kéo đến vị trí ban đầu, như sau:

$('.draggable-elements').draggable(); 
 

 
$('.droppable-elements').droppable({ 
 
    drop: function(event, ui) { 
 
    var postData = { 
 
     id: 1, 
 
     ... 
 
    }; 
 
    $.post('/ajax/url', postData, function(response) { 
 
     var response = $.parseJSON(response); 
 
     if (response.status != 1) { 
 
     return ui.draggable.animate({left: 0, top: 0}, 500); 
 
     } 
 
    } 
 
    } 
 
});

Bạn có thể cần phải có draggable.start/kéo thêm trái gốc và giá trị hàng đầu của kéo như dữ liệu thuộc tính, nhưng đối với tôi là làm việc tốt ở trên.

0

Tôi thấy rằng nếu tôi chỉ đơn giản là thiết lập hàng đầu: 0 và trái: 0, mục không còn có thể kéo được nữa. Để "buộc" trở lại, tôi phải làm điều này:

$draggedObj.css({ top: 0, left: 0 }) 
$draggedObj.draggable("destroy") 
$draggedObj.draggable({...whatever my draggable options are...}); 
Các vấn đề liên quan