Crysfel’s Blog

Drag and Drop con mootools

Wednesday, October 31, 2007, 06:46:20 pm

Featured, JavaScript, Tutoriales

El día de hoy quiero mostrar como realizar un Drag and Drop utilizando mootools, el ejemplo será sencillo pero se muestran los eventos necesarios para realizar algo más complejo. El ejemplo siguiente muestra lo que se planea realizar, arrastra la carpeta de la izquierda sobre cualquiera de los botes azules.

Hacer esto es muy sencillo, antes que nada hay que descargar la ultima versión de mootools (mootools-release-1.11.js actualmente), luego de esto la importamos al documento así:

<script type="text/javascript" src="mootools-release-1.11.js"></script>

El siguiente paso es crear el objeto que se arrastrara y los botecitos donde se soltará la carpeta, el HTML quedará de la siguiente manera.

<div id="mover"></div>
<div id="cubos">
    <div class="drop"></div>
    <div class="drop"></div>
    <div class="drop"></div>
    <div class="drop"></div>
</div>

Ahora mediante CSS acomodamos al tamaño correcto y le ponemos las imágenes respectivas.

#mover{
    width:64px;
    height:64px;
    background-image:url(folder.png);
}
#cubos{
    width:400px;
    margin:100px auto;
}
.drop{
    float:left;
    margin:3px;
    width:128px;
    height:128px;
    background-image:url(boteBacio.png);
}

Una vez lista la interfase, viene lo divertido, pues es hora de programar las acciones y eventos a realizar.

Mootools tiene una forma muy sencilla de realizar el Drag and Drop, simplemente al elemento que se hace “dragable” se le asignan los elementos que serán “dropables” para este elemento mediante un arreglo.

Con esto en mente tomamos todos los elementos que contengan la clase “drop”, para esto simplemente utilizamos la función doble dólar y le pasamos la expresión que necesitamos.

var drops = $$('#cubos .drop');
var clon;

Hasta aquí contamos con un arreglo de elementos, además de que se ha creado una variable llamada clon, la cual no contiene nada por ahora, esta variable clon lo que contendrá es una copia del elemento mover y se le modificará su propiedad de la transparencia, todo esto se realizará cuando se le presiona el Mouse sobre el elemento mover.

El pseudo código es el siguiente:

$('mover').addEvent('mousedown',function(event){
    //detenemos la propagación del evento
    //si no existe una instancia del clon, se copia el elemento mover
    //asignamos las mismas coordenadas al clon del objeto mover
    //agregamos el clon al dom
    //le asignamos una opacidad al clon del 70%
    //hacemos al clon dragable e iniciamos el evento manualmente
    //asignamos el evento emptydrop al clon, el cual se ejecuta cuando
          //se ha soltado el clon fuera de los elementos dropables, de esta manera
          //podemos desaparecer al clon cuando se suelta en un lugar no deseado.
}});

Esto en javascript se escribe de la siguiente manera:

$('mover').addEvent('mousedown',function(event){
    event = new Event(event).stop();
    if(!$chk(clon)) clon = this.clone();
    clon.setStyles(this.getCoordinates());
    clon.inject(document.body);
    clon.setStyle('opacity',0.7);
    clon.makeDraggable({droppables:drops}).start(event);
    clon.addEvent('emptydrop',function(){
        if($chk(clon)){ clon.remove(); clon= null;}
    });
});

Lo único importante para comentar, es prestar atención a la función makeDraggable, pues esta es la responsable de que los elementos se puedan arrastrar en el documento, además, dentro de las opciones que se le pasan esta la de droppables, la cual es el arreglo de elementos en los que puede ser soltado el elemento que estamos arrastrando.

Lo que sigue es programar los eventos para los elementos dropables, los cuales son tres, el over, que se ejecuta cuando el elemento que se esta arrastrando esta sobre el elemento en cuestión, el leave, que se ejecuta cada vez que el elemento que se esta arrastrando sale del elemento en cuestión, y el mas importante, el drop se ejecuta cuando el elemento que se esta arrastrando es soltado sobre el elemento en cuestión.

Con esto en mente codificamos lo siguiente

drops.setStyle('opacity',0.7);
drops.each(function(drop){
    var fx = new Fx.Styles(drop, {duration:300, wait:false});
    drop.addEvent('drop',function(){
        if($chk(clon)){ clon.remove(); clon= null;}
        this.setStyle('background-image','url(boteLleno.png)');
    });
    drop.addEvent('over',function(){
        fx.start({'opacity':1});
    });
    drop.addEvent('leave',function(){
        fx.start({'opacity':0.7});
    });
});

Primero se ponen con opacidad en 70%, luego se itera el arreglo y a cada elemento se le asigna los eventos de los que he hablado anteriormente (drop, over, leave), en los eventos leave y over, únicamente se cambia la opacidad mediante una transición, esto es gracias a la clase Fx.Styles, y en el evento drop se verifica que exista una instancia del clon, de ser así se elimina, luego se cambia la imagen del bote vacío por el bote lleno.

Pues esto es todo, realmente sencillo, espero que todo este claro, a continuación pongo el código completo del ejemplo, simplemente copia y pega.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>Crysfel's Blog</title>
<script type="text/javascript" src="mootools-release-1.11.js"></script>
<style type="text/css">
html,body{
    text-align:center;
}
#mover{
    width:64px;
    height:64px;
    background-image:url(folder.png);
}
#cubos{
    width:400px;
    margin:100px auto;
}
.drop{
    float:left;
    margin:3px;
    width:128px;
    height:128px;
    background-image:url(boteBacio.png);
}
</style>
</head>

<body>
<div id="mover"></div>
<div id="cubos">
    <div class="drop"></div>
    <div class="drop"></div>
    <div class="drop"></div>
    <div class="drop"></div>
</div>
<script type="text/javascript">
var drops = $$('#cubos .drop');
var clon;

$('mover').addEvent('mousedown',function(event){
    event = new Event(event).stop();
    if(!$chk(clon)) clon = this.clone();
    clon.setStyles(this.getCoordinates());
    clon.inject(document.body);
    clon.setStyle('opacity',0.7);
    clon.makeDraggable({droppables:drops}).start(event);
    clon.addEvent('emptydrop',function(){
        if($chk(clon)){ clon.remove(); clon= null;}
    });
});

drops.setStyle('opacity',0.7);
drops.each(function(drop){
    var fx = new Fx.Styles(drop, {duration:300, wait:false});
    drop.addEvent('drop',function(){
        if($chk(clon)){ clon.remove(); clon= null;}
        this.setStyle('background-image','url(boteLleno.png)');
    });
    drop.addEvent('over',function(){
        fx.start({'opacity':1});
    });
    drop.addEvent('leave',function(){
        fx.start({'opacity':0.7});
    });
});
</script>
</body>
</html>

Imprimir Comentarios (7) Leer mas

7 Respuestas para este tema

gallloo

Thursday, November 1, 2007, 6:53 am

Muy buen efecto.
Gracias por el ejemplo , lo estaba buscando :D

baldemar

Thursday, November 1, 2007, 5:35 pm

Tas pesado!!!!, cuando sea grande quiero ser como tu,
Saludos.

Bock

Monday, December 17, 2007, 3:25 am

Copiar y pegar del código facilitado no funciona.

crysfel

Wednesday, December 19, 2007, 2:14 pm

Para que funcione correctamente asegurate de tener en el mismo directorio la libreria de mootools, ademas de tener las imagenes necesarias.

Saludos.

romina

Tuesday, June 17, 2008, 9:10 pm

buenisimo! hacia mucho q estaba buscando una explicacion clara de como funcionaba drag&drop porq necesito programar una aplicacion q “maneje y diferecie varios drops y drags”…Felicitaciones muy buen articulo.

Miguel

Monday, September 22, 2008, 3:30 pm

Gracias esta muy bueno el script lo necesitaba!!!!!!!!

Gerardo

Friday, September 26, 2008, 9:33 pm

Me esta sirviendo de base para realizar una evaluacion interactiva en la cual arrastras la respuesta hacia un contenedor.

Deja una respuesta