Implementar la acción de soltar, de drag & drop, con droppable de jQueryUI

  • Por
Cómo utilizar las librerías jQueryUI y el plugin droppable para realizar cosas cuando un usuario suelte un elemento sobre otro, en una operación de arrastrar y soltar (drag & drop).

En la operación de arrastrar y soltar participan dos elementos: El primero es el elemento que arrastras y el segundo es el elemento donde sueltas el primero. Por ello, las librerías jQueryUI mantienen dos clases distintas para realizar un ejercicio completo de arrastrar y soltar. Por un lado tenemos el plugin draggable, que se aplica sobre los elementos que quieres que se arrastren, y por otro el plugin droppable, que se aplica sobre aquellos elementos que quieres que se enteren cuando les sueltas algo encima.

En los artículos anteriores del Manual de jQueryUI estuvimos hablando en profundidad sobre los elementos draggable, de modo que ahora vamos a ver la otra parte que nos queda, es decir, los elementos droppable. Aunque sean dos clases distintas, lo cierto es que si has podido entender bien como funciona draggable, no tendrás ningún problema en entender los detalles sobre droppable.

Usando el plugin droppable

Quizás nos sorprendió lo sencillo que era conseguir que un elemento se pudiera arrastrar con jQueryUI, así que ahora no nos sorprenderá tanto la facilidad de detectar que se ha soltado en un lugar determinado. Para ello usamos este sencillo código.

$("#soltable").droppable();

Con esto conseguimos que el elemento con id="soltable" detecte cuando algún elemento draggable se suelte encima de él. Claro que para hacer algo cuando arrastren un elemento hasta él, no nos servirá con invocar al plugin droppable, sino que tendremos que realizar alguna otra acción y para ello entran en juego los eventos.

Si queremos hacer algo cuando se suelte un elemento encima de un droppable, tendremos que definir el evento "drop", de esta manera.

$("#soltable").droppable({
   drop: function( evento, ui ) {
      $(this).html("Lo soltaste!!!");
   }
});

Ese evento "drop" provocaría que, al soltar un elemento arrastrable encima del dropable, se cambie el texto que hay escrito en el elemento droppable.

Se puede ver un ejemplo de draggable que se puede soltar en un droppable.

Opciones de personalización de un elemento droppable

Existen diversas opciones de configuración de los elementos droppable que se pueden asignar, tanto en el momento de invocar el plugin, como después de haber sido creado el droppable por medio del método "option" del plugin.

Al invocar el plugin indicamos las opciones de configuración tal como estamos acostumbrados a hacer en jQuery, con notación de objeto y por medio de una serie de propiedades. Por ejemplo, podemos configurar la tolerancia con la que un elemento se acepta un elemento soltado con la propiedad de configuración "tolerance".

$("#soltable").droppable({
   tolerance: "fit"
});

Con esto conseguimos que el elemento que soltamos, sólo se considere soltado en el objetivo cuando está completamente dentro del mismo.

Nota: La configuración por defecto de tolerance es "intersect", que significa que el elemento también se puede soltar en cualquier intersección, con tal que el 50% del área del elemento soltado esté dentro del elemento que lo recibe. Consultar otras posibilidades de configuración en la documentación de jQueryUI.

Interesante es también la opción "accept" o "scope" (ambas sirven para lo mismo). Con ellas indicamos el rango de elementos aceptaría recibir un droppable, por medio de un selector. Se tiene que configurar como valor a alguna de esas dos propiedades, o las dos, el selector o selectores que sí se aceptarían.

Nota: En el caso de la opción "accept" también te permite indicar una función, que se ejecutaría -una vez por cada elemento de manera independiente- para saber si se acepta un elemento o no. La función debería devolver true para saber si ese elemento está o no permitido soltar y recibe como parámetro el elemento que se está soltando.
$("#soltable").droppable({
   accept: ".tarea"
});

Ese elemento solo aceptaría que se le soltasen elementos con el class "tarea". Para ser más exactos, sólo esos elementos de clase "tarea" provocarían que se lanzase el evento drop.

En la propia documentación de jQueryUI encontraréis otra serie de opciones interesantes.

Eventos en los elementos droppable

Podemos definir varios eventos distintos relacionados con los elementos droppable. Son los siguientes:

  • Evento create: ocurre cuando se crea el elemento droppable.
  • Evento activate: se produce cuando un elemento draggable que se podría aceptar por el droppable empieza a arrastrarse.
  • Evento deactivate: ocurre cuando un elemento draggable que se podría hacer aceptado se deja de arrastrar.
  • Evento over: ocurre cuando un elemento draggable que fuese le aceptable entra en un área de tolerancia donde se podría soltar sobre el droppable.
  • Evento out: lo mismo que over pero cuando sale de la tolerancia.
  • Evento drop: cuando se suelta un elemento draggable sobre un droppable, siempre y cuando el draggable sea aceptado por el droppable y se suelte dentro del área definida por la tolerancia.

Así se definiría un evento en el momento de creación del droppable.

$("#soltable").droppable({
   out: function( evento, ui ) {
      $(this).html("Ahora saliste...");
   }
});

Ese evento produciría que se cambiase el texto del droppable por "Ahora saliste", cuando un elemento draggable, que sea aceptable, se salga del área de tolerancia.

También podemos definir eventos una vez se ha creado el droppable con el método bind() de jQuery.

$( "#soltable" ).bind( "drop", function(evento, ui) {
   //código del evento
});
Nota: al igual que el pluggin draggable, las funciones que se ejecutan a raíz de los eventos de droppable reciben dos parámetros. El primero es el propio objeto evento del navegador y el segundo es un objeto que tiene varias propiedades. Nosotros lo estamos recibiendo siempre con el nombre ui. En ese caso tendrá estas propiedades:
  • ui.draggable: el objeto jQuery que corresponde con el elemento draggable que está provocando el evento.
  • ui.helper: el helper del elemento draggable, otro objeto jQuery del elemento que se arrastra.
  • ui.position: la posición del elemento draggable, relativa a donde esté contenido.
  • ui.offset: la posición absoluta del elemento draggable.

Como se puede imaginar el lector, el evento clave a la hora de gestionar la utilidad de arrastrar y soltar es "drop". Por ejemplo, aquí tenemos un script para la definición de un evento "drop" que hace que, al soltar un elemento en el droppable, el elemento soltado cambie su color de fondo.

drop: function( event, ui ) {
   ui.draggable.css("background-color", "#ddd");
}

Si queremos hacer alguna cosa cuando el elemento se retira del área donde se podría soltar, tenemos que utilizar el evento "out". Pero ojo, que ese evento "out" se ejecuta siempre que se sale del área soltable, independientemente si antes lo habíamos soltado allí o no. Luego haremos un ejemplo para ver este asunto.

Métodos de los elementos "soltable"

Para acabar esta introducción sobre los componentes droppable de jQueryUI nos queda por comentar que existe una serie de métodos que se pueden invocar sobre ellos, para hacer cosas diversas, como habilitarlos o inhabilitarlos, cambiar sus opciones de configuración, etc.

Todos esos métodos se invocan como si estuviéramos invocando al propio plugin droppable, pero pasando como parámetro una cadena con el nombre del método a ejecutar, tal como estamos acostumbrados a hacer con diversos otros componentes jQueryUI, incluido el plugin draggable.

Por ejemplo, tenemos el método "disable" que sirve para inhabilitar un elemento droppable y se ejecutaría de la siguiente manera:

$("#elementodroppable").droppable("disable")

Otro ejemplo interesante es el método option, que sirve para definir opciones de configuración del elemento Lo ponemos en ejecución al pasar la palabra "option" y luego tenemos que indicar otro parámetro con el nombre de la opción al que queremos acceder, junto con un tercer parámetro con el nuevo valor de la opción, si es que deseábamos cambiarlo.

$("#soltable").droppable("option", "activeClass", "sueltaaqui");

Con eso conseguiríamos que, al iniciar el arrastre sobre un elemento que pueda soltarse en el elemento "#soltable", se aplique la clase "sueltaaqui". Esa clase CSS se pone en el elemento donde se puede soltar aquello que se está arrastrando, para que el usuario perciba dónde podría culminar su acción de drag&drop.

Si quisiéramos en algún momento saber qué clase se definió como "activeClass", podríamos hacerlo con:

$("#soltable").droppable("option", "activeClass")

Conclusión

Hasta el momento hemos ofrecido una introducción bastante completa sobre los componentes Droppable de jQueryUI, pero lo cierto es que las opciones de uso y configuración de los elementos "soltable" son bastante grandes. En cualquier caso, recuerda siempre que dispones de mucha más información en la propia documentación de jQuery UI.

Con lo visto hasta ahora ya debes tener una idea más o menos clara sobre cómo hacer sistemas de arrastrar y soltar medianamente complejos. No obstante, en el capítulo siguiente hacemos un nuevo ejemplo un poco más elaborado que seguramente te servirá para despejar algunas dudas que puedas tener todavía.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

Joana Rodriguez

29/1/2016
Consulta evento arrastrar
Hola Como estan?
Estoy leyendo sus diferentes articulos sobre estos eventos arrastrar y soltar. Pero no encuentro la solucion de lo que quiero, les cuento para ver si m podrian ayudar.
Estoy realizando un calendario con fullcalendar.js
El usuario va escoger d 2 listas por ejemplo: Pais y Ciudades.
Yo capturo ese Nombre y lo coloco en una cajita Que se arrastra y la suelto en Calendario.
Al soltarlo se borra el Nombre, el cual debo guardar luego en BD (MySQL) con el dia y la hora que cayo.
Por favor como hago para que al soltar No se desaparezca el Nombre.
Gracias de antemano en lo que m puedan ayudar
Joana R.
Caracas-Venezuela
UCV

Dunia

02/11/2016
Draggable
Hola cómo están, he leido muchos artículos sobre esta función, pero yo quisiera programar un boton que automáticamente me arrastrara todos los elementos dragable que tengo, como un marcar todos. En espera de su respuesta...Muchas gracias de antemano