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.
Reorder rows of a DataTable with Drag and Drop.
id | date | quantity | amount | title |
---|---|---|---|---|
Loading... | ||||
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 |
This example shows users how to combine the Drag and Drop Utility with the Datatable widget to easily re-order table rows. There are some cases where the initial ordering of rows doesn't produce the desired output, but with this example we illustrate how users can manually order data by simply dragging and dropping to rearrange the rows.
In order to make your rows draggable, the only thing you need to do is to subscribe to the cellMousedownEvent
, then operate on the target row with a custom handler. In this case, onRowSelect
is the function we have defined to do all the row dragging.
1 | myDataTable.subscribe('cellMousedownEvent', onRowSelect); |
view plain | print | ? |
Our function, onRowSelect
, will create a DDProxy for each row we are trying to drag. We define the custom action for all the predefined DD interesting moments: startDrag
, endDrag
and onDragOver
.
A custom init
event handler is attached to make a DataTable's rows drag targets:
1 | ////////////////////////////////////////////////////////////////////////////// |
2 | // Create DDRows instances when DataTable is initialized |
3 | ////////////////////////////////////////////////////////////////////////////// |
4 | myDataTable.subscribe("initEvent", function() { |
5 | |
6 | var i, id, |
7 | allRows = this.getTbodyEl().rows; |
8 | |
9 | for(i=0; i<allRows.length; i++) { |
10 | id = allRows[i].id; |
11 | // Clean up any existing Drag instances |
12 | if (myDTDTargets[id]) { |
13 | myDTDTargets[id].unreg(); |
14 | delete myDTDTargets[id]; |
15 | } |
16 | // Create a Drag instance for each row |
17 | myDTDTargets[id] = new YAHOO.util.DDTarget(id); |
18 | } |
19 | }); |
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 trigger the creation of that new row as a drag target:
1 | ////////////////////////////////////////////////////////////////////////////// |
2 | // Create DDRows instances when new row is added |
3 | ////////////////////////////////////////////////////////////////////////////// |
4 | myDataTable.subscribe("rowAddEvent",function(e){ |
5 | var id = e.record.getId(); |
6 | |
7 | myDTDTargets[id] = new YAHOO.util.DDTarget(id); |
8 | }) |
view plain | print | ? |
Data:
1 | YAHOO.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 | opacity: 0.6;filter:alpha(opacity=60); |
3 | color:blue; |
4 | border: 2px solid gray; |
5 | } |
6 | |
7 | #datatable tr { |
8 | cursor: pointer; |
9 | } |
view plain | print | ? |
Markup:
1 | <div id="datatable"></div> |
view plain | print | ? |
JavaScript:
1 | YAHOO.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 | myDTDTargets = {}, |
19 | onRowSelect = function(ev) { |
20 | var par = myDataTable.getTrEl(Event.getTarget(ev)), |
21 | srcData, |
22 | srcIndex, |
23 | tmpIndex = null, |
24 | ddRow = new YAHOO.util.DDProxy(par.id); |
25 | |
26 | ddRow.handleMouseDown(ev.event); |
27 | |
28 | |
29 | /** |
30 | * Once we start dragging a row, we make the proxyEl look like the src Element. We get also cache all the data related to the |
31 | * @return void |
32 | * @static |
33 | * @method startDrag |
34 | */ |
35 | ddRow.startDrag = function () { |
36 | proxyEl = this.getDragEl(); |
37 | srcEl = this.getEl(); |
38 | srcData = myDataTable.getRecord(srcEl).getData(); |
39 | srcIndex = srcEl.sectionRowIndex; |
40 | // Make the proxy look like the source element |
41 | Dom.setStyle(srcEl, "visibility", "hidden"); |
42 | proxyEl.innerHTML = "<table><tbody>"+srcEl.innerHTML+"</tbody></table>"; |
43 | }; |
44 | |
45 | /** |
46 | * Once we end dragging a row, we swap the proxy with the real element. |
47 | * @param x : The x Coordinate |
48 | * @param y : The y Coordinate |
49 | * @return void |
50 | * @static |
51 | * @method endDrag |
52 | */ |
53 | ddRow.endDrag = function(x,y) { |
54 | Dom.setStyle(proxyEl, "visibility", "hidden"); |
55 | Dom.setStyle(srcEl, "visibility", ""); |
56 | }; |
57 | |
58 | |
59 | /** |
60 | * This is the function that does the trick of swapping one row with another. |
61 | * @param e : The drag event |
62 | * @param id : The id of the row being dragged |
63 | * @return void |
64 | * @static |
65 | * @method onDragOver |
66 | */ |
67 | ddRow.onDragOver = function(e, id) { |
68 | // Reorder rows as user drags |
69 | |
70 | var destEl = Dom.get(id), |
71 | destIndex = destEl.sectionRowIndex; |
72 | |
73 | |
74 | |
75 | if (destEl.nodeName.toLowerCase() === "tr") { |
76 | if(tmpIndex !==null) { |
77 | myDataTable.deleteRow(tmpIndex); |
78 | } |
79 | else { |
80 | myDataTable.deleteRow(srcIndex); |
81 | } |
82 | |
83 | myDataTable.addRow(srcData, destIndex); |
84 | tmpIndex = destIndex; |
85 | |
86 | |
87 | DDM.refreshCache(); |
88 | } |
89 | }; |
90 | }; |
91 | |
92 | |
93 | myDataTable.subscribe('cellMousedownEvent', onRowSelect); |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | ////////////////////////////////////////////////////////////////////////////// |
100 | // Create DDTarget instances when DataTable is initialized |
101 | ////////////////////////////////////////////////////////////////////////////// |
102 | myDataTable.subscribe("initEvent", function() { |
103 | |
104 | var i, id, |
105 | allRows = this.getTbodyEl().rows; |
106 | |
107 | |
108 | for(i=0; i<allRows.length; i++) { |
109 | id = allRows[i].id; |
110 | // Clean up any existing Drag instances |
111 | if (myDTDTargets[id]) { |
112 | myDTDTargets[id].unreg(); |
113 | delete myDTDTargets[id]; |
114 | } |
115 | // Create a Drag instance for each row |
116 | myDTDTargets[id] = new YAHOO.util.DDTarget(id); |
117 | } |
118 | }); |
119 | |
120 | ////////////////////////////////////////////////////////////////////////////// |
121 | // Create DDTarget instances when new row is added |
122 | ////////////////////////////////////////////////////////////////////////////// |
123 | myDataTable.subscribe("rowAddEvent",function(e){ |
124 | var id = e.record.getId(); |
125 | |
126 | myDTDTargets[id] = new YAHOO.util.DDTarget(id); |
127 | }); |
128 | }(); |
129 | }); |
view plain | print | ? |
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.
Note: Logging and debugging is currently turned off for this example.
Copyright © 2011 Yahoo! Inc. All rights reserved.
Privacy Policy - Terms of Service - Copyright Policy - Job Openings