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:

- Basic Example
- Progressive Enhancement
- Custom Cell Formatting
- Conditional row coloring
- Nested Headers
- JSON Data Over XHR
- XML Data Over XHR With POST
- XML Data with XPath
- Textual Data Over XHR
- Polling the DataSource
- Adding, Updating, and Deleting Rows
- Client-side Pagination
- Client-side Sorting
- Server-side Pagination and Sorting for Dynamic Data
- Integrating Browser History Manager with Server-side Pagination and Sorting
- XY-scrolling, Y-scrolling, and X-scrolling
- Row Selection
- Cell Selection
- Inline Cell Editing
- Showing, Hiding, and Reordering Columns.
- Highlighting Cells, Rows, or Columns
- Reorder Rows with Drag and Drop
- Row Expansion
- Context Menu Integration
- Configuring the Paginator (included with examples for Paginator)
- TabView Integration
- Complex Example of Multiple Features
- Client-side Filtering of Local Data
- Filtering of Dynamic Data
- Datatable with Autocomplete
- Skinning Model
- Ratings (included with examples for ProgressBar Control)
- YQLDataSource (included with examples for DataSource Utility)
- Complex Application (included with examples for Layout Manager)

### More DataTable Control Resources:

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

Copyright © 2009 Yahoo! Inc. All rights reserved.

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