YUI Library Home

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

DataTable Control: Reorder Rows with Drag and Drop

Reorder rows of a DataTable with Drag and Drop.

id
date
quantity
amount
title
YUI Datatable/DragDrop
po-0167
03/24/1980
1
$4.00
A Book About Nothing
po-0783
01/03/1983
0
$12.12
The Meaning of Life
po-0297
12/12/1978
12
$1.25
This Book Was Meant to Be Read Aloud
po-1482
03/11/1985
6
$3.50
Read Me Twice

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.

1YAHOO.example.DDRows = function(id, sGroup, config) { 
2    YAHOO.example.DDRows.superclass.constructor.call(this, id, sGroup, config); 
3    Dom.addClass(this.getDragEl(),"custom-class"); 
4}; 
5 
6////////////////////////////////////////////////////////////////////////////// 
7// DDRows extends DDProxy 
8////////////////////////////////////////////////////////////////////////////// 
9YAHOO.extend(YAHOO.example.DDRows, YAHOO.util.DDProxy, { 
10          .......... 
11
view plain | print | ?

Initializing draggability

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

1myDataTable.subscribe("initEvent"function() { 
2    var i, id, 
3        allRows = this.getTbodyEl().rows; 
4 
5    for(i=0; i<allRows.length; i++) { 
6        id = allRows[i].id; 
7        // Clean up any existing Drag instances 
8        if (myDTDrags[id]) { 
9             myDTDrags[id].unreg(); 
10             delete myDTDrags[id]; 
11        } 
12        // Create a Drag instance for each row 
13        myDTDrags[id] = new YAHOO.example.DDRows(id); 
14    } 
15}); 
view plain | print | ?

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.

1myDataTable.subscribe("rowAddEvent",function(e){ 
2    var id = e.record.getId(); 
3    myDTDrags[id] = new YAHOO.example.DDRows(id); 
4}); 
view plain | print | ?

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:

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

CSS:

1.custom-class { 
2    opacity0.6;filter:alpha(opacity=60); 
3    color:blue
4    border2px solid gray
5} 
6
7#datatable tr { 
8    cursorpointer
9} 
view plain | print | ?

Markup:

1<div id="datatable"></div> 
view plain | print | ?

JavaScript:

1YAHOO.util.Event.addListener(window, "load"function() { 
2    YAHOO.example.ReorderRows = function() { 
3        var Dom = YAHOO.util.Dom, 
4            Event = YAHOO.util.Event, 
5            DDM = YAHOO.util.DragDropMgr, 
6            myColumnDefs = [ 
7                {key:"id"}, 
8                {key:"date", formatter:"date"}, 
9                {key:"quantity", formatter:"number"}, 
10                {key:"amount", formatter:"currency"}, 
11                {key:"title"
12            ], 
13            myDataSource = new YAHOO.util.LocalDataSource( 
14                YAHOO.example.Data.bookorders, 
15                {responseSchema: {fields: ["id","date","quantity","amount","title"]}} 
16            ), 
17            myDataTable = new YAHOO.widget.DataTable("datatable", myColumnDefs, myDataSource, {caption:"YUI Datatable/DragDrop"}), 
18            myDTDrags = {}; 
19 
20        ////////////////////////////////////////////////////////////////////////////// 
21        // Custom drag and drop class 
22        ////////////////////////////////////////////////////////////////////////////// 
23        YAHOO.example.DDRows = function(id, sGroup, config) { 
24            YAHOO.example.DDRows.superclass.constructor.call(this, id, sGroup, config); 
25            Dom.addClass(this.getDragEl(),"custom-class"); 
26            this.goingUp = false
27            this.lastY = 0; 
28        }; 
29 
30        ////////////////////////////////////////////////////////////////////////////// 
31        // DDRows extends DDProxy 
32        ////////////////////////////////////////////////////////////////////////////// 
33        YAHOO.extend(YAHOO.example.DDRows, YAHOO.util.DDProxy, { 
34            proxyEl: null
35            srcEl:null
36            srcData:null
37            srcIndex: null
38            tmpIndex:null
39 
40            startDrag: function(x, y) { 
41                var    proxyEl = this.proxyEl = this.getDragEl(), 
42                    srcEl = this.srcEl = this.getEl(); 
43 
44                this.srcData = myDataTable.getRecord(this.srcEl).getData(); 
45                this.srcIndex = srcEl.sectionRowIndex; 
46                // Make the proxy look like the source element 
47                Dom.setStyle(srcEl, "visibility""hidden"); 
48                proxyEl.innerHTML = "<table><tbody>"+srcEl.innerHTML+"</tbody></table>"
49            }, 
50 
51            endDrag: function(x,y) { 
52                var position, 
53                    srcEl = this.srcEl; 
54 
55                Dom.setStyle(this.proxyEl, "visibility""hidden"); 
56                Dom.setStyle(srcEl, "visibility"""); 
57            }, 
58 
59             onDrag: function(e) { 
60                // Keep track of the direction of the drag for use during onDragOver 
61                var y = Event.getPageY(e); 
62 
63                if (y < this.lastY) { 
64                    this.goingUp = true
65                } else if (y > this.lastY) { 
66                    this.goingUp = false
67                } 
68 
69                this.lastY = y; 
70           }, 
71 
72            onDragOver: function(e, id) { 
73                // Reorder rows as user drags 
74                var srcIndex = this.srcIndex, 
75                    destEl = Dom.get(id), 
76                    destIndex = destEl.sectionRowIndex, 
77                    tmpIndex = this.tmpIndex; 
78 
79                if (destEl.nodeName.toLowerCase() === "tr") { 
80                    if(tmpIndex !== null) { 
81                        myDataTable.deleteRow(tmpIndex); 
82                    } 
83                    else { 
84                        myDataTable.deleteRow(this.srcIndex); 
85                    } 
86 
87                    myDataTable.addRow(this.srcData, destIndex); 
88                    this.tmpIndex = destIndex; 
89 
90                    DDM.refreshCache(); 
91                } 
92            } 
93        }); 
94 
95        ////////////////////////////////////////////////////////////////////////////// 
96        // Create DDRows instances when DataTable is initialized 
97        ////////////////////////////////////////////////////////////////////////////// 
98        myDataTable.subscribe("initEvent"function() { 
99            var i, id, 
100                allRows = this.getTbodyEl().rows; 
101 
102            for(i=0; i<allRows.length; i++) { 
103                id = allRows[i].id; 
104                // Clean up any existing Drag instances 
105                if (myDTDrags[id]) { 
106                     myDTDrags[id].unreg(); 
107                     delete myDTDrags[id]; 
108                } 
109                // Create a Drag instance for each row 
110                myDTDrags[id] = new YAHOO.example.DDRows(id); 
111            } 
112        }); 
113 
114        ////////////////////////////////////////////////////////////////////////////// 
115        // Create DDRows instances when new row is added 
116        ////////////////////////////////////////////////////////////////////////////// 
117        myDataTable.subscribe("rowAddEvent",function(e){ 
118            var id = e.record.getId(); 
119            myDTDrags[id] = new YAHOO.example.DDRows(id); 
120        }) 
121    }(); 
122}); 
view plain | print | ?

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:

Logger Console

INFO 585ms (+585) 11:19:29 PM:

LogReader instance0

LogReader initialized

INFO 0ms (+0) 11:19:29 PM:

global

Logger initialized

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

Reload with logging
and debugging disabled.

More DataTable Control Resources:

Copyright © 2010 Yahoo! Inc. All rights reserved.

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