Este es un script que fácilmente puede modificarse para crear un carrito de compras, un sistema de widgets como el de wordpress entre otras opciones. Yo lo uso para seleccionar atributos de una lista.

Las listas

El código de las listas no tiene nada especial, sólo debemos asegurarnos que los id sean correctos

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="demo-frame">
<ul id="lista1" class="gallery">
    <li>Item1</li>
    <li>Item2</li>
    <li>Item3</li>
    <li>Item4</li>
</ul>
<ul id="lista2">
    <li>Item5</li>
    <li>Item6</li>
    <li>Item7</li>
</ul>
</div>

Estilo de las listas

Yo voy a usar un estilo simple en las listas, haciendolas flotar para que este una al lado de la otra además de agregarle una altura mínima para cuando no tenga elementos la lista.

1
2
3
4
5
6
7
8
9
10
body {
    color: #333333;
}
#lista1, #lista2 {
    width:200px;
    border:1px solid #990000;
    height:auto;
    float:left;
    margin-right:5px;
}

Jquery para las listas

Ahora si vamos a la parte importante del post, básicamente lo que voy a hacer es que que ambas listas tengan activo dragable y acepten el drop de la otra lista; además debo hacer que al recibir el drop se agregue el item correspondiente y se borre de la lista de donde proviene. Es posible añadir más opciones como cambiar el estilo entre listas o que el item cambie de forma, etc. Todo es cosa de jugar un poco con el código.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<script language="javascript" src="js/jquery-1.3.1.min.js"></script>
<script language="javascript" src="js/jquery-ui-personalized-1.6rc6.min.js"></script>
<script language="javascript">
$(document).ready(function(){
     // para ahorrar un poco de espacio voy a definir a las listas como variables
    var $lista1 = $('#lista1'), $lista2 = $('#lista2');
    // Activo draggable a la primera lista
    $('li',$lista1).draggable({
        revert: 'invalid',     
        helper: 'clone',       
        cursor: 'move'
    });
       // asigno droppable en la lista1 hacia la lista2
    $lista1.droppable({
        accept: '#lista2 li',
        drop: function(ev, ui) {
                       // Al hacer drop se borra el elemento
            deleteLista2(ui.draggable);
        }
    });
    // Asigno draggable a la lista2
    $('li',$lista2).draggable({
        revert: 'invalid',
        helper: 'clone',   
        cursor: 'move'
    });
       // Genero droppable para la segunda lista
    $lista2.droppable({
        accept: '#lista1 > li',
        drop: function(ev, ui) {
            deleteLista1(ui.draggable);    
        }
    });
    // Genero el borrado de items con el evento drop
    function deleteLista1($item) {
        $item.fadeOut(function() {
                     // Agrego el item dropeado y lo hago aparecer
            $($item).appendTo($lista2).fadeIn();
        });
        $item.fadeIn();
    }
    function deleteLista2($item) {
        $item.fadeOut(function() {         
                        /// Agrego el item dropeado y lo hago aparecer
            $item.appendTo($lista1).fadeIn();
        });
    }
});
</script>

Y eso es todo el código para la forma más simple de intercambiar items entre listas, se le pueden ñadir muchas más opciones como nos muestra la documentación del Jquery UI

Sobre Jquery UI

Para el ejemplo he usado Jquery 1.3.1 y JqueryUI 1.6rc6, si deseas usar una versión de Jquery 1.6.x, debes usar Jquery UI 1.5 de lo contrario no funcionará, la programación funciona en ambas versiones sin ningún cambio eso por un cambio que hizo jquery en el manejo de eventos drag and drop.