2011-08-19 29 views
11

Tengo una lista ordenable de videos y un conjunto de videos arrastrables. Básicamente quiero asegurarme de que los videos arrastrados no estén en los primeros 5 minutos de video. Como las duraciones de los videos varían, quiero probar esto en la caída: sume el tiempo hasta ese momento y, si no es así, revertiré 5 minutos y mostraré un error.jQuery Draggable + ordenable - ¿Cómo rechazar una caída en el género?

He intentado conectar todas las devoluciones de llamadas arrastrables y ordenables (incluida la devolución de llamada revertida no documentada) para hacer mi prueba, pero procure lo que intente, el dom siempre se cambia (y las llamadas clasificables se actualizan)

¿Alguien tiene alguna sugerencia?

Respuesta

10

puede revertir la operación de arrastre llamando al método cancel del widget draggable (método que no está documentado, pero su nombre no comienza con un guión bajo, lo que sin duda hace que sea "más seguro" para utilizar de forma fiable). Sin embargo, solo funciona durante el evento start, ya que otros eventos ocurren demasiado tarde para activar la animación de revertir.

Sin embargo, el widget sortable todavía registrará una caída incluso si la operación de arrastre se cancela, por lo que también tiene que quitar el elemento recién añadido (durante el evento stop, ya que se produce el evento start demasiado pronto):

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

Puede ver los resultados en this fiddle (el cuarto elemento siempre se revertirá).

Actualización: Como John Kurlak señala con razón en los comentarios, el elemento no revierten a causa de la llamada a draggable("cancel"), sino porque es ui.sendernull en nuestro caso. Arrojar algo resulta en el mismo comportamiento.

Por desgracia, todas las otras combinaciones que intentó resultado en el elemento que se está revertido sin la animación que tiene lugar, así que tal vez nuestra mejor apuesta es evitar el acceso ui.sender y en lugar de escribir algo como:

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

La excepción no detectada todavía aparecerá en la consola.

+0

¡Hola, gracias por la respuesta! Sin embargo, estoy luchando para que funcione: la prueba (canDropThatVideo) necesita encontrar la posición en la lista para que se pueda comparar con los videos adyacentes. Intenté algo como: // obtener los vids adyacentes var nextVid = $ (ui.item) .next(); var prevVid = $ (ui.item) .prev(); pero estos no parecen obtener los correctos, probablemente porque está en el evento de inicio ... ¿Debería funcionar? – lopsided

+0

@ user612911, es más complicado pero puede funcionar. Debes enlazar al evento 'sort' en lugar de' start' y usar 'ui.placeholder.next()' y 'ui.placeholder.prev()', respectivamente. Probablemente también deba recordar la decisión que tomó sobre el elemento de alguna manera (tal vez con 'data()'), para que el manejador 'stop' sepa qué hacer. (Por otro lado, no es necesario llamar '$()' a los miembros 'ui': ya son objetos jQuery.) –

+0

Genial, lo tengo funcionando bien ahora.También adjunté un poco de lógica al evento 'start' del arrastrable para agregar algunas clases 'cantDropHere' a los elementos que no son espacios drop válidos y luego excluí esas clases del ordenable. ¡Gracias! – lopsided

3

Encontré una manera diferente. Si no te importa no tener la animación de la misma flota de nuevo a su lugar original siempre se puede utilizar este

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

he usado esto porque necesitaba el evento de colocación de cualquier manera.

Cuestiones relacionadas