2011-08-19 10 views
11

Ho una lista ordinata di video e una serie trascinabile di video. Fondamentalmente voglio assicurarmi che i video trascinati non siano nei primi 5 minuti di video. Dato che le lunghezze del video variano, voglio testarlo alla caduta - sommare il tempo fino a quel momento e, se non farlo, ripristinare 5mins e mostrare un errore.jQuery Draggable + Sortable - Come rifiutare una goccia nell'ordinamento?

Ho provato ad agganciare tutti i callback per il draggable e il sortable (incluso il callback non documentato) per fare il test ma qualsiasi cosa provi, la dom viene sempre cambiata (e sortable chiama il suo callback di aggiornamento) ...

Qualcuno ha qualche suggerimento?

risposta

10

È possibile annullare l'operazione di trascinamento chiamando il metodo cancel del widget draggable (il metodo non è documentato, ma il suo nome non inizia con un carattere di sottolineatura, che lo rende probabilmente più "sicuro" da utilizzare in modo affidabile). Funziona solo durante l'evento start, tuttavia, poiché gli altri eventi si verificano troppo tardi per attivare l'animazione di annullamento.

Tuttavia, il widget sortable sarà ancora registrare un calo, anche se l'operazione di trascinamento viene annullata, in modo da avere anche rimuovere l'elemento appena aggiunto (durante la manifestazione stop, come si verifica l'evento start troppo presto):

$("#yourSortable").sortable({ 
    start: function(event, ui) { 
     if (!canDropThatVideo(ui.item)) { 
      ui.sender.draggable("cancel"); 
     } 
    }, 
    stop: function(event, ui) { 
     if (!canDropThatVideo(ui.item)) { 
      ui.item.remove(); 
      // Show an error... 
     } 
    } 
}); 

È possibile visualizzare i risultati in this fiddle (il quarto elemento verrà sempre ripristinato).

Aggiornamento: Come John Kurlak sottolinea giustamente nei commenti, l'articolo non fa revert a causa della chiamata a draggable("cancel"), ma perché è ui.sendernull nel nostro caso. Lanciare qualcosa porta allo stesso comportamento.

Ahimè, tutte le altre combinazioni ho provato risultato nella voce di essere ripristinato senza l'animazione che si svolgono, quindi forse la nostra migliore scommessa è quella di evitare l'accesso a ui.sender invece scrivere qualcosa di simile:

start: function(event, ui) { 
    if (!canDropThatVideo(ui.item)) { 
     throw "cancel"; 
    } 
} 

L'eccezione non identificata apparirà comunque nella console, però.

+0

Hey Grazie per la risposta! Sto lottando per farlo funzionare - il test (canDropThatVideo) ha bisogno di trovare la posizione che è stata eliminata nella lista in modo che possa comparare con i video adiacenti. Ho provato qualcosa del tipo: // get vids adiacenti var nextVid = $ (ui.item) .next(); var prevVid = $ (ui.item) .prev(); ma questi non sembrano ottenere quelli corretti - probabilmente perché è nell'evento di inizio ... Dovrebbe funzionare? – lopsided

+0

@ user612911, è più complicato ma può funzionare. Devi associare l'evento 'sort' invece di' start' e usare 'ui.placeholder.next()' e 'ui.placeholder.prev()', rispettivamente. Probabilmente dovrai anche ricordare la decisione che hai preso sull'oggetto in qualche modo (magari con 'data()'), in modo che il gestore di 'stop' sappia cosa fare. (Per inciso, non è necessario chiamare '$()' sui membri 'ui': sono già oggetti jQuery.) –

+0

Grande, ho funzionato bene ora.Ho anche allegato alcune logiche all'evento 'start' del trascinamento per aggiungere alcune classi 'cantDropHere' agli elementi che non sono drop spaces validi e quindi hanno escluso quelle classi dall'ordinata. Grazie! – lopsided

3

Ho trovato un modo diverso. Se non vi dispiace non avere l'animazione di galleggiare di nuovo al suo posto originale è sempre possibile utilizzare questo

.droppable({ 
    drop: function (event, ui) { 

     var canDrop = false; 

     //if you need more calculations for 
     //validation, like me, put them here 

     if (/*your validation here*/) 
      canDrop = true; 

     if (!canDrop) { 
      ui.draggable.remove(); 
     } 
     else{ 
      //you can put whatever else you need here 
      //in case you needed the drop anyway 
     } 
    } 
}).sortable({ 
    //your choice of sortable options 
}); 

ho usato questo perché mi serviva l'evento calo in entrambi i casi.

Problemi correlati