2010-06-21 16 views
28

Mam element, który jest przeciągalny i element, który jest droppable. Gdy przeciągany element zostanie upuszczony na zrzutowiska próbuję wykonać następujący kod jquery psuedo:Jak przywrócić położenie jquery UI przeciągalne na podstawie warunku

if(draggedelement == value){ 

$(draggedelement).hide(); 

} 
else{ 

$(draggedelement).revert(); 

} 

gdzie funkcja revert() przemieszcza przeciągany element z powrotem do pierwotnego świetnym miejscu.

Jak można to osiągnąć?

P.S. Zdaję sobie sprawę, że opcja "cofnij" jest możliwa do przeciągnięcia, ale aktywuje się tylko wtedy, gdy przeciągnięty element nie trafi do strefy zrzutu.

Odpowiedz

70

Nie jest kilka wbudowanych opcji do tego, na twoim .draggable(), ustaw revert option na 'invalid' i wróci, jeśli nie było powodzeniem spada na droppable, tak:

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

Następnie w .droppable() zestawu Co znajduje się ważna dla spadku używając accept option, na przykład:

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

coś nie pasuje to selektor zostanie zresetowany, kiedy pozwoliłeś idź, you can see a full demo here. Opcja zaakceptować wykonuje również funkcję filtrowania jeśli trzeba selektor nie może zapewnić, na przykład:

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

+1 świetna pomoc! Dzięki! – Sisir

4

Spróbuj dodać ten kod do zdarzenia "upuść". Oto 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); 
    } 
    } 
}); 

}); 

Jak widać w skrypcie, można spojrzeć na klasę .correct lub tekstu wewnątrz (wykomentowane linia)

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

ten został wykorzystany do przyjęcia tylko jeden przeciągany z grupy draggables; do jednego poprawnego droppable, w grupie droppables.

P.S przepraszam za język, jeśli nie jest zrozumiałe =)

4

miałem przypadek użycia gdzie musiałem uruchomić jakąś logikę w metodzie upuść droppable w celu określenia, czy przeciągany powinna powrócić. Użyłem następujących czynności, aby to osiągnąć:

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

Moje przypadek użycia jest tabela, gdzie każda komórka jest droppable reprezentujący okres 5 minut. Moje draggables to rezerwacje, które rozpoczynają się w jednej komórce, ale przechodzą przez wiele komórek z rzędu, aby reprezentować czas rezerwacji.

Nie chciałem, aby przeciągane elementy zachodziły na siebie, ponieważ oznaczałoby to podwójną rezerwację. Tak więc po upuszczeniu znajduję wszystkie przeciągane w rzędzie, z wyjątkiem tego, które właśnie przesunąłem i sprawdzam, czy się nie pokrywają.Jeśli występuje nakładanie się, moja logika warunkowa zwraca wartość true, a ja cofam opcję przeciągania.

Następnym etapem jest wywołanie wywołania ajax, aby zaktualizować bazę danych, jeśli logika po stronie serwera mówi, że ruch jest nieważny Mam nadzieję, że zwróci stan błędu i przywróci działanie przeciągane.

P.S. to jest moja pierwsza odpowiedź, przepraszam, jeśli zrobiłem coś złego. Wskazówki, jak zapewnić dobre odpowiedzi, chętnie akceptowane.

Edycja: Po wypróbowaniu mojego wywołania AJAX zdałem sobie sprawę, że istnieje możliwość skorzystania z funkcji droppable.drop, zanim uruchomiona zostanie funkcja draggable.revert. Do czasu, gdy moje wywołanie AJAX zwróciło wartość false, okno minęło, a klasa została dodana zbyt późno, aby można było przeciągnąć komendę.

Jako takie, ja już nie opierając się na funkcji draggable.revert zamiast działając wyłącznie na odpowiedzi AJAX i czy fałsz, używając animate(), aby powrócić do przesunięcia do jej pierwotnego położenia, co następuje:

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

może trzeba mieć draggable.start/drag dodać oryginalny lewy i najlepszymi wartościami przeciągać jako atrybuty danych, ale dla mnie powyżej działało.

0

Znalazłem, że jeśli po prostu ustawię wierzchołek: 0 i lewo: 0, element nie jest już przeciągalny. Aby "wymusić" odwrócenie, musiałem to zrobić:

$draggedObj.css({ top: 0, left: 0 }) 
$draggedObj.draggable("destroy") 
$draggedObj.draggable({...whatever my draggable options are...}); 
Powiązane problemy