Improving TableDND usability

by Tamas Gal on November 10th, 2009, under General | 2 Comments »

The TableDnD jQuery plugin allows the user to reorder rows within a table, for example if they represent an ordered list (tasks by priority for example). Individual rows can be marked as non-draggable and/or non-droppable (so other rows can’t be dropped onto them). Rows can have as many cells as necessary and the cells can contain form elements.

This is a great plugin at all, but needs some attention in case of usability. The default behavior of the plugin is passing over the drag-n-drop “ghosting” effect.  (You can see an example here: http://www.gimiti.com/kltan/demo/jTree/)

It is difficult to make the ghosting work with this plugin but I found a very simple solution to do it. I used a small amount of CSS a Javascript code to reach a better usability behavior when a user drag-n-drop a table row.

The main concept was to mimic the ghosting effect in my project.

I used the following CSS lines.


/* This declarations makes a draghandle icon (a small crosshair) visible in the first cell of a table row */

td.dragHandle {padding-left:17px;}
td.showDragHandle {padding-left:17px; background:url(arrow_all_thin.png) no-repeat center center; cursor: move;}

/* The followings will format the entire table row when a user is dragging it */

tr.myDragClass td {background-color: #fff; padding-left:2px;} /* change the background color all of the table cells in the row to white */
tr.myDragClass td a {color: #aaa;} /* change the text color to grey, or just lighter - note: I'm using links in the  TDs */
tr.myDragClass td img, tr.myDragClass td .taskDelete, tr.myDragClass td.napok div {display:none;} /* Do not display any of the images and other informations in the cells. Just show the most important information for dragging and dropping. Other information, icons, etc may confuse the user. */
tr.myDragClass td span, tr.myDragClass td span span {padding:0;} /* Pull the information closer to the drag icon */

After that formatting I played with the plugin itself. I set up it on the following way.


var oldSibling;
 $("#todoList").tableDnD({
 onDragClass: "myDragClass",
 onDragStart: function(table, cell) {

// Saving the row under the dragged one
 oldSibling=$(cell).parents("tr").next();

//Set the CSS class immediately to show the "ghosting" like effect when the user clicks on the row

$(cell).parents("tr").addClass("myDragClass");
 },
 onDrop: function(table, row) {
 var aHtml=$("a", row).html();
 var f=$.getUrlVar('f');
 if(confirm("\nAre you sure to move \""+aHtml+"\" task?")) {
 // Here comes the AJAX call
 $("#cover").show();
 $("#ajaxMessage").show();
 document.getElementById("cover").style.width="100%";
 document.getElementById("cover").style.height=docHeight()+"px";
 $("#bigCal").load("setTask.php?f="+f+"&orig="+row.title+"&"+$.tableDnD.serializeT(), function(){
 $("#cover").hide();
 $("#ajaxMessage").fadeOut(200);
 });
 }
 else {

//If the user Cancel the moving we have to take back the row to the original place
 $(row).insertBefore(oldSibling);
 }
 },
 dragHandle: "dragHandle"
 });

As you can see I made the drag-n-drop cancel functionality also. :)

TODO: Handle the oldSibling if the moved row was the last row in the table.

Do you have any thoughts or question?

Tags: , , , ,

2 Responses to “Improving TableDND usability”

  1. papas says:

    great addon mate

    only question where does the js code go?

    in the tablednd.js file or in the actual page?

  2. Tamas Gal says:

    The JS goes to the actual page. (or any external JS which will handle your table and linked in the page).

    The JS code is defining tableDND for a table with ID=todoList.

Leave a Reply