YUI Library Home

Site Search (YDN & YUIBlog):

# YUI Library Examples: DataTable Control: Reorder Rows with Drag and Drop

The code for the `DDRows` class and this example has been contributed to YUI by Gonzalo Cordero, Juku graduate and Front-End Engineer on the Yahoo! Flex Force team who is currently working on the next generation of Yahoo! homepage.

# DataTable Control: Reorder Rows with Drag and Drop

Reorder rows of a DataTable with Drag and Drop.

View example in new window.

## Re-orderable table rows

The DDRows class defined in this example allows users to easily re-order table rows. There are some cases where the initial ordering of rows doesn't produce the desired output. By using this DDRows class, users can manually order data by simply dragging and dropping to rearrange the rows.

## The DDRows class

The DDrows class extends the DDProxy class, so that it can will use proxy elements for all the dragging operations.

YAHOO.example.DDRows = function(id, sGroup, config) { YAHOO.example.DDRows.superclass.constructor.call(this, id, sGroup, config); Dom.addClass(this.getDragEl(),"custom-class"); }; ////////////////////////////////////////////////////////////////////////////// // DDRows extends DDProxy ////////////////////////////////////////////////////////////////////////////// YAHOO.extend(YAHOO.example.DDRows, YAHOO.util.DDProxy, { .......... }

## Initializing draggability

A custom init event handler is attached to make a DataTable's rows draggable:

myDataTable.subscribe("initEvent", function() { var i, id, allRows = this.getTbodyEl().rows; for(i=0; i<allRows.length; i++) { id = allRows[i].id; // Clean up any existing Drag instances if (myDTDrags[id]) { myDTDrags[id].unreg(); delete myDTDrags[id]; } // Create a Drag instance for each row myDTDrags[id] = new YAHOO.example.DDRows(id); } });

Also, it’s important to know that whenever a drag/drop operation occurs, DataTable fires a "rowAddEvent" event, which is used to re-attach the dragdrop object to the newly created table row.

myDataTable.subscribe("rowAddEvent",function(e){ var id = e.record.getId(); myDTDrags[id] = new YAHOO.example.DDRows(id); });

## Interesting DD moments

startDrag:
  This is when the proxy element gets created and the source element we’re dragging gets cached.
endDrag:
  We adjust the visibility of the proxy and drag elements.
onDrag:
  Determine the direction the drag element is going.
onDragOver:
  This is when row and data order manipulation happens. As a table row is dragged over another table row, the two elements and underlying data get swapped.

## Sample Code for this Example

Data:

YAHOO.example.Data = { bookorders: [ {id:"po-0167", date:new Date(1980, 2, 24), quantity:1, amount:4, title:"A Book About Nothing"}, {id:"po-0783", date:new Date("January 3, 1983"), quantity:null, amount:12.12345, title:"The Meaning of Life"}, {id:"po-0297", date:new Date(1978, 11, 12), quantity:12, amount:1.25, title:"This Book Was Meant to Be Read Aloud"}, {id:"po-1482", date:new Date("March 11, 1985"), quantity:6, amount:3.5, title:"Read Me Twice"} ] }

CSS:

.custom-class { opacity: 0.6;filter:alpha(opacity=60); color:blue; border: 2px solid gray; } #datatable tr { cursor: pointer; }

Markup:

<div id="datatable"></div>

JavaScript:

YAHOO.util.Event.addListener(window, "load", function() { YAHOO.example.ReorderRows = function() { var Dom = YAHOO.util.Dom, Event = YAHOO.util.Event, DDM = YAHOO.util.DragDropMgr, myColumnDefs = [ {key:"id"}, {key:"date", formatter:"date"}, {key:"quantity", formatter:"number"}, {key:"amount", formatter:"currency"}, {key:"title"} ], myDataSource = new YAHOO.util.LocalDataSource( YAHOO.example.Data.bookorders, {responseSchema: {fields: ["id","date","quantity","amount","title"]}} ), myDataTable = new YAHOO.widget.DataTable("datatable", myColumnDefs, myDataSource, {caption:"YUI Datatable/DragDrop"}), myDTDrags = {}; ////////////////////////////////////////////////////////////////////////////// // Custom drag and drop class ////////////////////////////////////////////////////////////////////////////// YAHOO.example.DDRows = function(id, sGroup, config) { YAHOO.example.DDRows.superclass.constructor.call(this, id, sGroup, config); Dom.addClass(this.getDragEl(),"custom-class"); this.goingUp = false; this.lastY = 0; }; ////////////////////////////////////////////////////////////////////////////// // DDRows extends DDProxy ////////////////////////////////////////////////////////////////////////////// YAHOO.extend(YAHOO.example.DDRows, YAHOO.util.DDProxy, { proxyEl: null, srcEl:null, srcData:null, srcIndex: null, tmpIndex:null, startDrag: function(x, y) { var proxyEl = this.proxyEl = this.getDragEl(), srcEl = this.srcEl = this.getEl(); this.srcData = myDataTable.getRecord(this.srcEl).getData(); this.srcIndex = srcEl.sectionRowIndex; // Make the proxy look like the source element Dom.setStyle(srcEl, "visibility", "hidden"); proxyEl.innerHTML = "<table><tbody>"+srcEl.innerHTML+"</tbody></table>"; }, endDrag: function(x,y) { var position, srcEl = this.srcEl; Dom.setStyle(this.proxyEl, "visibility", "hidden"); Dom.setStyle(srcEl, "visibility", ""); }, 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) { // Reorder rows as user drags var srcIndex = this.srcIndex, destEl = Dom.get(id), destIndex = destEl.sectionRowIndex, tmpIndex = this.tmpIndex; if (destEl.nodeName.toLowerCase() === "tr") { if(tmpIndex !== null) { myDataTable.deleteRow(tmpIndex); } else { myDataTable.deleteRow(this.srcIndex); } myDataTable.addRow(this.srcData, destIndex); this.tmpIndex = destIndex; DDM.refreshCache(); } } }); ////////////////////////////////////////////////////////////////////////////// // Create DDRows instances when DataTable is initialized ////////////////////////////////////////////////////////////////////////////// myDataTable.subscribe("initEvent", function() { var i, id, allRows = this.getTbodyEl().rows; for(i=0; i<allRows.length; i++) { id = allRows[i].id; // Clean up any existing Drag instances if (myDTDrags[id]) { myDTDrags[id].unreg(); delete myDTDrags[id]; } // Create a Drag instance for each row myDTDrags[id] = new YAHOO.example.DDRows(id); } }); ////////////////////////////////////////////////////////////////////////////// // Create DDRows instances when new row is added ////////////////////////////////////////////////////////////////////////////// myDataTable.subscribe("rowAddEvent",function(e){ var id = e.record.getId(); myDTDrags[id] = new YAHOO.example.DDRows(id); }) }(); });

## Configuration for This Example

You can load the necessary JavaScript and CSS for this example from Yahoo's servers. Click here to load the YUI Dependency Configurator with all of this example's dependencies preconfigured.

### 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.

### DataTable Control Examples:

### More DataTable Control Resources:

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

Copyright © 2010 Yahoo! Inc. All rights reserved.

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