Draggable DataTable Rows

About the Author:Gonzalo Cordero is a Front-End Engineer on the Yahoo! Flex Force team. He is currently working on the next generation of Yahoo! homepage. He is also a former Juku graduate, where he recently became an instructor as well. In this article he walks us through the process of adding Drag and Drop functionality to a DataTable widget.

Introduction

A recent project of mine required an implementation of DataTable where rows could be moved around with Drag and Drop functionality. After looking through the YUI gallery of examples, I realized that the feature I was trying to implement was a little bit different from the ones I saw. So I decided to implement my own solution. In this article I'll explain how I combined YUI's DataTable and Drag and Drop components, some workarounds for the challenges I encountered, and how I was able to improve upon my initial solution by using the new YUI3 codeline (which is currently available in preview mode).

Initial considerations and some possible solutions

The first question that came to my mind was how to make each table row draggable and a drop target at the same time in the most efficient way. I also knew that instantiating a Drag and DDTarget object at the same time on an element wasn't going to work. After reading through the Drag and Drop API documentation I found out that the property isTarget gets set by default to true for every Drag object we create, making that object a drop target as well. So with that, I defined a custom DDRows class to set up the interesting moment handlers and also add some CSS style for the drag proxy object to visually differentiate it from the regular rows. A proxy drag object is just a container that gets displayed once the dragging starts and it serves as a marker/guide for what is being dragged.

An important consideration is that the DOM is repainted each time we move a row, so not only does the Drag object on the original row need to be cleaned up when it is deleted, a new Drag object needs to be created for the row that is created in the new position. Here is the entire onDragDrop function that cleans up and moves a row:

It was no surprise when I discovered that with this new version I could take advantage of some of the new properties and methods to make my solution more clean and efficient. For instance, Drag and Drop in YUI 3 provides an efficient way to create the Drag/Target objects we need:

We no longer have to define our own subclass or worry about validating the element before swapping rows, as the drophit event will only be triggered when applied to elements we've defined as drop targets.

The other great new feature version 3 brings us is custom-event bubbling (which brings the power of DOM-event bubbling to the custom events that drive the library's API). Thanks to this, we can now to listen for all the Drag and Drop events at the document level using the Drag and Drop Manager, rather than having to attach several events to each individual table row. Our custom-event delegation code looks like this:

Conclusion

I hope you find these examples a useful resource on how to add Drag and Drop functionality to DataTables and on how you easily you can integrate YUI 2.7.0 and YUI 3 components in the same page. It also serves as a quick preview on all the new and exciting features that are coming with the next generation of YUI.