Estoy empezando a curiosear Mootools, y aunque me está gustando bastante, si que echo en falta una documentación más detallada, no solo explicar como va el API, ya que a veces son necesarios ejemplos más básicos para no tener que estar buscando en el API.
En este caso voy a reorganizar mediante drag&drop una lista de elementos, la cual puede tener subelementos también, un tÃpico ejemplo de categorÃas y subcategorÃas. Para ello me crearé una lista cuyos elementos tendrán el estilo categoria y cuyos subelementos tendrán el estilo subcategorias, necesario para diferenciar estilos y comportamiento.

<ul id="lista_categorias">
<li class="categoria">Elemento 1</li>
<li class="categoria">Elemento 2
<ul>
<li class="subcategoria">Elemento 2.1</li>
<li class="subcategoria">Elemento 2.2</li>
<li class="subcategoria">Elemento 2.3</li>
<li class="subcategoria">Elemento 2.4</li>
<li class="subcategoria">Elemento 2.5</li>
<li class="subcategoria">Elemento 2.6</li>
</ul>
</li>
<li class="categoria">Elemento 3</li>
<li class="categoria">Elemento 4
<ul>
<li class="subcategoria">Elemento 4.1</li>
<li class="subcategoria">Elemento 4.2</li>
<li class="subcategoria">Elemento 4.3</li>
<li class="subcategoria">Elemento 4.4</li>
</ul>
</li>
<li class="categoria">Elemento 5</li>
<li class="categoria">Elemento 6</li>
<li class="categoria">Elemento 7</li>
<li class="categoria">Elemento 8</li>
<li class="categoria">Elemento 9</li>
</ul>
Para ser lo menos intrusivo que se pueda, anadiré al evento load del objeto window la carga de las funciones necesarias para ello, siempre que exista el objeto lista_categorias (el primer ul de todos).
window.addEventListener('load', function() {
_lista();
}
, false);
function _lista() {
if ($('lista_categorias')) {
...
}
Habrá tres operaciones distintas: crear efecto drag, añadir evento drop a las categorÃas y añadir evento drop a las subcategorÃas. Digo crear efecto drag porque realmente lo que se hace es que cuando se ejecuta el evento mousedown, se crea una copia del elemento, y es este el que se mueve por la pantalla, guardando una referencia al elemento original. Hay distinción entre el evento drop de las categorÃas y las subcategorÃas porque si se trata de una categorÃa se añade sin más, y si es una subcategorÃa se añade en la categorÃa. A parte, si se intenta mover una categorÃa que contiene subcategorÃas, solo se añadirán las subcategorÃas, no la categorÃa.
// Drag & Drop de listado
function _lista() {
if ($('lista_categorias')) {
// Drag de cada categoria/subcategoria
// Para cada elemento li añado el evento mousedown, para que cuando se ejecute se cree una copia de ese elemento, se le de estilo semi transparente y se permita hacer drag
$$('#lista_categorias li').each(function(elemento){
elemento.addEvent('mousedown', function(e) {
e = new Event(e).stop();
window.item = elemento;
window.categoria_clone = this.clone()
.setStyles(this.getCoordinates())
.setStyles({'opacity': 0.7, 'position': 'absolute'})
.addEvent('drop', function() {console.log('DROP')})
.addEvent('emptydrop', function() {
this.remove();
}).inject(document.body);
categoria_clone.makeDraggable({
droppables: $$('#lista_categorias li')
}).start(e);
});
});
// Drop en las categorias
// Para cada categoria, le añadimos el evento drop, que permite recibir elementos "drag". Si el elemento que se recibe tiene subcategorias, entonces se cogen estas y se añaden al elemento ul que contiene, si no lo contiene, lo creamos. Si no contiene subcategorÃas, se añade sin más.
$$('#lista_categorias li.categoria').each(function(drop){
drop.addEvents({
'drop': function() {
window.categoria_clone.remove();
var ul = window.item.getElement('ul');
if (!drop.getElement('ul')) {
(new Element('ul')).inject(drop);
}
dropul = drop.getElement('ul');
if (ul) {
ul.getElements('li').each(function(li) {
li.inject(dropul);
});
ul.remove();
} else {
window.item.inject(dropul);
}
drop.setStyle('background', '#FFFFFF');
//dropFx.start('7389AE').chain(dropFx.start.pass('ffffff', dropFx));
},
'over': function() {
drop.setStyle('background', '#DDDDFF');
//dropFx.start('98B5C1');
},
'leave': function() {
drop.setStyle('background', '#FFFFFF');
// window.categoria_clone.remove();
//dropFx.start('ffffff');
}
})
});
// Si cae el drop en una subcategoria lo inserto en el padre
$$('#lista_categorias li.subcategoria').each(function(drop){
drop.addEvents({
'drop': function() {
window.categoria_clone.remove();
var ul = window.item.getElement('ul');
dropul = drop.parentNode;
if (ul) {
ul.getElements('li').each(function(li) {
li.inject(dropul);
});
ul.remove();
} else {
window.item.inject(dropul);
}
}
})
});
}
}
Ejemplo
Descargar ódigo
Se agradece! 🙂
Como pega le pondrÃa que para páginas con ancho variable no irÃa bien, pero vamos, según cuentas es algo chapucero asà que está más que de sobra jeje!
Gracias!
PAZ!!
Existe una extension para firefox y firebug que se llama pixelperfect que hace esto mismo de manera más simple…
¡Viva firebug!
fmvilas, sÃ, incluso me han dicho que le añadiera un grid 🙂
Jaime, no la conocÃa y si hice esto es porque busqué y no encontré 🙁 Muchas gracias, instalo ya mismo… ¡viva firebug! 🙂