Javascript Drag & Drop

Working on the admin section of my Simple Content Management system (SCM ), I came accross the whish to be able to perform certain ordering operations by drag & drop within the browser. Some research quickly brought up a nice set of experimental toolman javascripts by Tim Taylor. These scripts behave quite well under different browsers, but they were suitable only for dragging items in a list and not for dragging rows in a table as what I wanted to do.

Some experimentation shows that is possible to get the desired behaviour out of ToolMan - at least for FireFox and IE7 - and the below list and table are intended to show that off. Go ahead and try to rearrange the items..

  • item one
  • item two
  • item three
  • item four
  • item five
  • item six
column1column2column3
alpha1alpha2alpha3
beta1beta2beta3
gamma1gamma2gamma3
delta1delta2delta3

Example of draggable items in a  list and in a table to facilitate intuitive re-ordering.

Of cource, the usability of this lies in the fact that after a re-order by the user, additional scripting can traverse the DOM to extract the changes and to prepare, for example, a form that should be submitted to the server. The ToolMan scripts also contain a mechansism to retain positions between reloads by way of cookies, but that is not being used here so you can do a reload to reset initial postions. The drag & drop operation on the list will work on most browsers, the modification of the Table will not be entirely successful under Opera (drag down only) or on Mac's Safari. As I've said; this is experimental..

Utilization is basically very simple. At page load, the toolman_init() function is called where the list and table elements as identified by id (here list_dd and table_dd respectively) are handed to the makeListSortable() method of instantiated class dragsort.

// Declaration of the dragsort object

var dragsort = ToolMan.dragsort();

// Start this module

function toolman_init() {
// Make the items of 'list_dd' draggable
dragsort.makeListSortable(document.getElementById("list_dd"));
// Make the rows of 'table_dd' draggable
dragsort.makeListSortable(document.getElementById("table_dd"));
}

// Cascade into any previously installed window.onload

var prev_win_onload = window.onload;

window.onload = function () {
if (prev_win_onload) prev_win_onload();
toolman_init();
}

The principal modification of the ToolMan scripts is in makeListSortable() of the _dragSortFactory() in initial file dragsort.js. Note that the changes are small but take into account that a decent HTML Table can have a row in the THead or TFoot part, so that only rows in the TBody element of the Table are being considered.

makeListSortable : function(list) {
var helpers = ToolMan.helpers()
var coordinates = ToolMan.coordinates()
// Mod JVN: next line replaced by following two lines
//var items = list.getElementsByTagName("li")
if (list.nodeName=="UL") var items = list.getElementsByTagName("li")
if (list.nodeName=="TABLE") var items = list.getElementsByTagName("tbody")[0].getElementsByTagName("tr")

helpers.map(items, function(item) {
var dragGroup = dragsort.makeSortable(item)
dragGroup.setThreshold(4)
var min, max
dragGroup.addTransform(function(coordinate, dragEvent) {
return coordinate.constrainTo(min, max)
})
dragGroup.register('dragstart', function() {
// Mod JVN: next line replaced by following two lines
//var items = list.getElementsByTagName("li")
if (list.nodeName=="UL") var items = list.getElementsByTagName("li")
if (list.nodeName=="TABLE") var items = list.getElementsByTagName("tbody")[0].getElementsByTagName("tr")
min = max = coordinates.topLeftOffset(items[0])
for (var i = 1, n = items.length; i < n; i++) {
var offset = coordinates.topLeftOffset(items[i])
min = min.min(offset)
max = max.max(offset)
}
})
})

for (var i = 1, n = arguments.length; i < n; i++)
helpers.map(items, arguments[i])
},

The source of the modified ToolMan scripts is here. This file bundles all eight original scripts into a single file for simplicity.

By the way. If you are looking for some nice generic drag & drop javascripts for positioning and resizing, do take a look at the work of Walter Zorn.

Filed under code & stuff – Published 2006 Apr 1 – Modified 2006 Nov 9 – Permalink

Top