2010-06-21 3 views
28

Ho un elemento che è trascinabile e un elemento che è trascinabile. Una volta che l'elemento trascinato è caduta sulla zona di lancio che sto cercando di eseguire il seguente codice pseudo jquery:come ripristinare la posizione di un'interfaccia utente jquery trascinabile in base alla condizione

if(draggedelement == value){ 

$(draggedelement).hide(); 

} 
else{ 

$(draggedelement).revert(); 

} 

in cui la funzione revert() sposta l'elemento trascinato al suo postion originale.

Come si compirebbe questo?

P.S. Sono a conoscenza dell'opzione 'revert' trascinabile, tuttavia questa opzione si attiva solo se l'elemento trascinato non arriva alla dropzone.

risposta

70

Ci sono alcune opzioni integrate per questo, sul tuo .draggable(), imposta revert option su 'invalid', e tornerà indietro se non fosse caduto con successo su un droppable, come questo:

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

Poi, nel tuo .droppable() insieme ciò che è valido per una goccia utilizzando il accept option, ad esempio:

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

Tutto ciò che non corrisponde questo selettore si resetta quando si lascia vai, you can see a full demo here. L'opzione di accettare prende anche una funzione se avete bisogno di filtrare un selettore non è in grado di fornire, in questo modo:

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

+1 ottimo aiuto! Grazie! – Sisir

4

Prova ad aggiungere quel codice all'evento "drop". Ecco uno 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); 
    } 
    } 
}); 

}); 

Come si può vedere nello script, è possibile cercare per la classe .correct o il testo all'interno (commentata linea)

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

questo è stato utilizzato per accettare un solo trascinabili, da un gruppo di draggables; a un droppable corretto, in un gruppo di droppable.

P.S dispiace per la lingua se non è comprensibile =)

4

Ho avuto un caso d'uso in cui ho dovuto correre una certa logica nel metodo della caduta del droppable per determinare se il trascinabile dovrebbe ritornare. Ho usato il seguente per raggiungere questo obiettivo:

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

mio caso d'uso è una tabella in cui ogni cella è un droppable che rappresenta un periodo di 5 minuti. I miei draggable sono prenotazioni che iniziano in una cella, ma passano su molte celle di fila per rappresentare il tempo di prenotazione.

Non volevo che nessun oggetto trascinabile si sovrapponesse, in quanto ciò rappresenterebbe una doppia prenotazione. Quindi, dopo la caduta, trovo tutti i draggables nella riga, escluso quello che ho appena spostato, e controllo eventuali sovrapposizioni.Se si verifica una sovrapposizione, la mia logica condizionale restituisce true e ripristino il trascinamento.

Il passaggio successivo consiste nel generare una chiamata ajax per aggiornare il database, se la logica lato server indica che lo spostamento non è valido, spero di restituire uno stato di errore e di ripristinare il trascinamento.

P.S. questa è la mia prima risposta, scusate se ho fatto qualcosa di sbagliato. Suggerimenti su come fornire buone risposte accettate volentieri.

Modifica: dopo aver provato la mia chiamata AJAX, mi sono reso conto che esiste una finestra di opportunità per la funzione droppable.drop per eseguire la sua operazione prima dell'esecuzione della funzione draggable.revert. Quando la mia chiamata AJAX ha restituito false, la finestra era passata e la classe veniva aggiunta troppo tardi per essere trascinata.

Come tale, non sono più basandosi sulla funzione draggable.revert, invece che agisce esclusivamente in risposta AJAX e se falsa, utilizzando animate() per restituire il draggable alla sua posizione originale, come segue:

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

potrebbe essere necessario avere draggable.start/trascinare aggiungere l'originale sinistra ed i valori superiori della trascinabile come attributi dei dati, ma per me quanto sopra ha funzionato bene.

0

Ho trovato che se avessi impostato semplicemente in alto: 0 e lasciato: 0, l'oggetto non è più trascinabile. Per "forzare" un ripristino, ho dovuto eseguire questa operazione:

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