YUI Library Home

Site Search (YDN & YUIBlog):

# YUI Library Examples: Drag & Drop: Reordering a List

# Drag & Drop: Reordering a List

This example demonstrates how to create a list that can have the order changed with the Drag & Drop Utility.

View example in new window.

### List 1

- list 1, item 1
- list 1, item 2
- list 1, item 3

### List 2

- list 2, item 1
- list 2, item 2
- list 2, item 3

## Drag and Drop List Ordering

The YUI Drag & Drop Utility lets you make HTML elements draggable.

In this example, list reordering is implemented by extending `YAHOO.util.DDProxy` instead of `YAHOO.util.DD` so that we can use the source element as the "insertion point". When the drag starts, the proxy element style and content is adjusted to match the source element, and `visibility:hidden` is applied to the source element.

To facilitate dragging into an empty list, we make the two list elements `DDTarget`s. When interacting with the list items, we will get two notifications (one for the list, one for the list item). We ignore all `dragOver` events that happen on the list and ignore all `dragDrop` events unless the drop was in the list's negative space (not over another list item).

Create the elements:

<div class="workarea"> <h3>List 1</h3> <ul id="ul1" class="draglist"> <li class="list1" id="li1_1">list 1, item 1</li> <li class="list1" id="li1_2">list 1, item 2</li> <li class="list1" id="li1_3">list 1, item 3</li> </ul> </div> <div class="workarea"> <h3>List 2</h3> <ul id="ul2" class="draglist"> <li class="list2" id="li2_1">list 2, item 1</li> <li class="list2" id="li2_2">list 2, item 2</li> <li class="list2" id="li2_3">list 2, item 3</li> </ul> </div>

Now we create the instances of `YAHOO.util.DDProxy`, passing the element ids or references for our demo elements.

<script type="text/javascript"> (function() { var Dom = YAHOO.util.Dom; var Event = YAHOO.util.Event; var DDM = YAHOO.util.DragDropMgr; ////////////////////////////////////////////////////////////////////////////// // example app ////////////////////////////////////////////////////////////////////////////// YAHOO.example.DDApp = { init: function() { var rows=3,cols=2,i,j; for (i=1;i<cols+1;i=i+1) { new YAHOO.util.DDTarget("ul"+i); } for (i=1;i<cols+1;i=i+1) { for (j=1;j<rows+1;j=j+1) { new YAHOO.example.DDList("li" + i + "_" + j); } } Event.on("showButton", "click", this.showOrder); Event.on("switchButton", "click", this.switchStyles); }, showOrder: function() { var parseList = function(ul, title) { var items = ul.getElementsByTagName("li"); var out = title + ": "; for (i=0;i<items.length;i=i+1) { out += items[i].id + " "; } return out; }; var ul1=Dom.get("ul1"), ul2=Dom.get("ul2"); alert(parseList(ul1, "List 1") + "\n" + parseList(ul2, "List 2")); }, switchStyles: function() { Dom.get("ul1").className = "draglist_alt"; Dom.get("ul2").className = "draglist_alt"; } }; ////////////////////////////////////////////////////////////////////////////// // custom drag and drop implementation ////////////////////////////////////////////////////////////////////////////// YAHOO.example.DDList = function(id, sGroup, config) { YAHOO.example.DDList.superclass.constructor.call(this, id, sGroup, config); this.logger = this.logger || YAHOO; var el = this.getDragEl(); Dom.setStyle(el, "opacity", 0.67); // The proxy is slightly transparent this.goingUp = false; this.lastY = 0; }; YAHOO.extend(YAHOO.example.DDList, YAHOO.util.DDProxy, { startDrag: function(x, y) { this.logger.log(this.id + " startDrag"); // make the proxy look like the source element var dragEl = this.getDragEl(); var clickEl = this.getEl(); Dom.setStyle(clickEl, "visibility", "hidden"); dragEl.innerHTML = clickEl.innerHTML; Dom.setStyle(dragEl, "color", Dom.getStyle(clickEl, "color")); Dom.setStyle(dragEl, "backgroundColor", Dom.getStyle(clickEl, "backgroundColor")); Dom.setStyle(dragEl, "border", "2px solid gray"); }, endDrag: function(e) { var srcEl = this.getEl(); var proxy = this.getDragEl(); // Show the proxy element and animate it to the src element's location Dom.setStyle(proxy, "visibility", ""); var a = new YAHOO.util.Motion( proxy, { points: { to: Dom.getXY(srcEl) } }, 0.2, YAHOO.util.Easing.easeOut ) var proxyid = proxy.id; var thisid = this.id; // Hide the proxy and show the source element when finished with the animation a.onComplete.subscribe(function() { Dom.setStyle(proxyid, "visibility", "hidden"); Dom.setStyle(thisid, "visibility", ""); }); a.animate(); }, onDragDrop: function(e, id) { // If there is one drop interaction, the li was dropped either on the list, // or it was dropped on the current location of the source element. if (DDM.interactionInfo.drop.length === 1) { // The position of the cursor at the time of the drop (YAHOO.util.Point) var pt = DDM.interactionInfo.point; // The region occupied by the source element at the time of the drop var region = DDM.interactionInfo.sourceRegion; // Check to see if we are over the source element's location. We will // append to the bottom of the list once we are sure it was a drop in // the negative space (the area of the list without any list items) if (!region.intersect(pt)) { var destEl = Dom.get(id); var destDD = DDM.getDDById(id); destEl.appendChild(this.getEl()); destDD.isEmpty = false; DDM.refreshCache(); } } }, onDrag: function(e) { // Keep track of the direction of the drag for use during onDragOver var y = Event.getPageY(e); if (y < this.lastY) { this.goingUp = true; } else if (y > this.lastY) { this.goingUp = false; } this.lastY = y; }, onDragOver: function(e, id) { var srcEl = this.getEl(); var destEl = Dom.get(id); // We are only concerned with list items, we ignore the dragover // notifications for the list. if (destEl.nodeName.toLowerCase() == "li") { var orig_p = srcEl.parentNode; var p = destEl.parentNode; if (this.goingUp) { p.insertBefore(srcEl, destEl); // insert above } else { p.insertBefore(srcEl, destEl.nextSibling); // insert below } DDM.refreshCache(); } } }); Event.onDOMReady(YAHOO.example.DDApp.init, YAHOO.example.DDApp, true); })(); </script>

### YUI Logger Output:

Note: You are viewing this example in debug mode with logging enabled. This can significantly slow performance.

Reload with logging
and debugging disabled.

### Drag & Drop Examples:

- Basic Drag and Drop
- Using Handles
- Dragged Element on Top
- Using a Proxy Element
- Reordering a List
- Using Interaction Groups
- Custom Click Validator
- Staying in a Region
- Using the Drag Shim

### More Drag & Drop Resources:

- User's Guide (external)
- API Documentation
- Cheat Sheet PDF (external)

Copyright © 2008 Yahoo! Inc. All rights reserved.

Privacy Policy - Terms of Service - Copyright Policy - Job Openings