Sunday, April 3, 2011

Reorder Table Control Rows with "Drag and Drop"

Introduction

Suppose you need to design a page for users to order a list of items, for example, assigning priorities to a list of tasks, or ordering questions in a questionnaire. ISD's out-of-box solution is an edit table control, in which a textbox is for entering each item's order. An obvious drawback of the solution is that users have to manually maintain the integrity of all orders, and  a change in one row may result in changes in other rows.

A slightly better design is to replace the textbox with a pair of up and down arrows. You can use custom code in the arrows' event handlers to switch order between the clicked item and its previous or next one. When the page is regenerated, the items are sorted on their new orders. This design guarantees order integrity, but is inefficient. In order to move an item from bottom to top of the list, it requires quite some clicks.

Wouldn't it be nice that user simply drag and drop an item to its desired position and its new order, as well as other affected items', is reassigned automatically? This post will show you how to implement it in ISD.

Solution

There are two candidate implementations for drag-n-drop ordering, AjaxToolkit's ReorderList and a jQuery plugin Table Drag and Drop (TableDnD). ReorderList is a data-bound server control. It asks for a list of items as data source, and takes full control of data-binding and rendering. ISD has little help to offer. On the other hand, TableDnD is a pure client-side solution, leaving ISD with full control at server-side. Therefore, I will use TableDnD in this implementation.

Implementation

Step 1: Create a regular EditTable page
Create a plain vanilla EditTable page as shown below. Nothing fancy.


Step 2: Add jQuery and TableDnD libraries
In the page's prologue, insert 2 script references (lines 1 and 2):
Step 3: Configure HTML  table for DnD
Since ISD-generated pages are heavily loaded with HTML tables, it could be a little bit tricky to find the right one to configure. It is the inner most Fields table, as shown below.


First, give the table an unique ID. TableDnD will use the ID to locate the table and attach DnD behavior.


Then, add 2 classes (nodrag and nodrop) to the header row. This notifies TableDnD not to attach DnD behavior to the header row.

Step 4: Add CssClass to order field
Add CssClass (orderbox) to the textbox that holds the order field.

Step 5: Customize background color for the row in DnD
Add the following css class in Styles.css:
tr.tDnD_whileDrag td
{
  background-color: #CCCCCC;
}                                               
Step 6: Attach DnD behavior
Finally, insert the following script into the page's epilogue:

Conclusion

It seems a lot of steps. But your users' uh-ah reaction makes it all worth the trouble. You can download the demo here.

8 comments:

John said...

Very nice.

This opens a wide range of possibilities.

Hugh said...
This comment has been removed by the author.
Josh G. said...

Thank you, for this great idea. I have used this afew times now. I only wish that I knew more javasript so that I could modify this to not start at one, but start at the lowest number/first row. If that were the case it could be used with pagination.

John said...

I have used this useful post in the past. This time when I went to look it up the script for Step 2 and Step 6 are missing.

John said...

I have used this useful post in the past. This time when I went to look it up the script for Step 2 and Step 6 are missing.

Anonymous said...

Hi any chance of an update sample app for the and the checklist box demos
I can seem to get them to work in the later versions of ISD
Thanks
Gerard

Anonymous said...

I have been using this right up until Version 11 of Ironspeed and then it has stopped. Any Ideas why?

Anonymous said...

http://sjc.ironspeed.com/post/drag-and-drop-7159412?pid=1284979240#post1284979240&gsc.tab=0
update on Change to table ID