Drag & Drop Table Columns (new version, explained) 
December 19th, 2007, 01:55 PM
| | Member | | Join Date: Nov 2006
Posts: 53
| |
Greetings,
I´m back here to show the new version of the drag & drop table columns ( original script ). I´ve found some issues with the old script, specially when trying to use 2 tables with drag&drop on the same page (which was not possible). Now i´ve a new concept of the script, more object oriented.
I´ve also commented the whole code so you guys can easier understand it engine.
What exactly we need when trying to make a column drag & drop? We need basically 3 things
1 - we click on a determined handler, at this time we need a function to store the original position/object to know what to move
2 - we choose a destionation and release the mouse button, at this time we need a script to find the position where to drop the element we had dragged
3 - now that we have the element we dragged, and its destination, we need a function to put that element in the new position
Great part of the code is there because of the visual effect (like creating a hover effect to show where the element will be dropped, creating a "copy" of the column that is being dragged, etc)
Here is the new code -
/*
-
Author: Romulo do Nascimento Ferreira
-
E-mail: romulo.nf@mgmail.com
-
-
Drag & Drop Table Columns
-
*/
-
-
-
/* parameters
-
-
id: id of the table that will have drag & drop function
-
-
*/
-
-
function dragTable(id) {
-
// store the cell that will be dragged
-
this.draggedCell = null
-
// true if ghostTd exists
-
this.ghostCreated = false
-
// store the table itselfs
-
this.table = document.getElementById(id)
-
// store every row of the table
-
this.tableRows = this.table.getElementsByTagName("tr")
-
// create a handler array, usualy the ths in the thead, if not possible the first row of tds
-
this.handler = this.table.getElementsByTagName("th").length > 0 ? this.table.getElementsByTagName("th") : this.table.tBodies[0].rows[0].getElementsByTagName("td")
-
// create a cell array
-
this.cells = this.table.getElementsByTagName("td")
-
// store the max index of the column when dropped
-
this.maxIndex = this.handler.length
-
// store the horizontal mouse position
-
this.x;
-
// store the vertical mouse position
-
this.y;
-
// store the index of the column that will be dragged
-
this.oldIndex;
-
// store the index of the destionation of the column
-
this.newIndex;
-
-
for (x=0; x<this.handler.length; x++) {
-
// associate the object with the cells
-
this.handler[x].dragObj = this
-
// override the default action when mousedown and dragging
-
this.handler[x].onselectstart = function() { return false }
-
// fire the drag action and return false to prevent default action of selecting the text
-
this.handler[x].onmousedown = function(e) { this.dragObj.drag(this,e); return false }
-
// visual effect
-
this.handler[x].onmouseover = function(e) { this.dragObj.dragEffect(this,e) }
-
this.handler[x].onmouseout = function(e) { this.dragObj.dragEffect(this,e) }
-
this.handler[x].onmouseup = function(e) { this.dragObj.dragEffect(this,e) }
-
}
-
-
for (x=0; x<this.cells.length; x++) {
-
this.cells[x].dragObj = this
-
// visual effect
-
this.cells[x].onmouseover = function(e) { this.dragObj.dragEffect(this,e) }
-
this.cells[x].onmouseout = function(e) { this.dragObj.dragEffect(this,e) }
-
this.cells[x].onmouseup = function(e) { this.dragObj.dragEffect(this,e) }
-
}
-
}
-
-
dragTable.prototype.dragEffect = function(cell,e) {
-
// assign event to variable e
-
if (!e) e = window.event
-
-
// return if the cell being hovered is the same as the one being dragged
-
if (cell.cellIndex == this.oldIndex) return
-
-
else {
-
// if there is a cell being dragged
-
if (this.draggedCell) {
-
// change class to give a visual effect
-
e.type == "mouseover" ? this.handler[cell.cellIndex].className = "hovering" : this.handler[cell.cellIndex].className = ""
-
}
-
}
-
}
-
-
dragTable.prototype.drag = function(cell,e) {
-
// reference of the cell that is being dragged
-
this.draggedCell = cell
-
-
// change class for visual effect
-
this.draggedCell.className = "dragging"
-
-
// store the index of the cell that is being dragged
-
this.oldIndex = cell.cellIndex
-
-
// create the ghost td
-
this.createGhostTd(e)
-
// start the engine
-
this.dragEngine(true)
-
}
-
-
dragTable.prototype.createGhostTd = function(e) {
-
// if ghost exists return
-
if (this.ghostCreated) return
-
// assign event to variable e
-
if (!e) e = window.event
-
// horizontal position
-
this.x = e.pageX ? e.pageX : e.clientX + document.documentElement.scrollLeft
-
// vertical position
-
this.y = e.pageY ? e.pageY : e.clientY + document.documentElement.scrollTop
-
-
// create the ghost td (visual effect)
-
this.ghostTd = document.createElement("div")
-
this.ghostTd.className = "ghostTd"
-
this.ghostTd.style.top = this.y + 5 + "px"
-
this.ghostTd.style.left = this.x + 10 + "px"
-
// ghost td receives the content of the dragged cell
-
this.ghostTd.innerHTML = this.handler[this.oldIndex].innerHTML
-
document.getElementsByTagName("body")[0].appendChild(this.ghostTd)
-
-
// assign a flag to see if ghost is created
-
this.ghostCreated = true
-
}
-
-
dragTable.prototype.drop = function(dragObj,e) {
-
// assign event to variable e
-
if (!e) e = window.event
-
// store the target of the event - mouseup
-
e.targElm = e.target ? e.target : e.srcElement
-
-
// end the engine
-
dragObj.dragEngine(false,dragObj)
-
-
// remove the ghostTd
-
dragObj.ghostTd.parentNode.removeChild(dragObj.ghostTd)
-
-
// remove ghost created flag
-
this.ghostCreated = false
-
-
// store the index of the target, if it have one
-
if (e.targElm.cellIndex !="undefined") {
-
checkTable = e.targElm
-
-
// ascend in the dom beggining in the targeted element and ending in a table or the body tag
-
while (checkTable.tagName.toLowerCase() !="table") {
-
if (checkTable.tagName.toLowerCase() == "html") break
-
checkTable = checkTable.parentNode
-
}
-
-
// check if the table where the column was dropped is equal to the object table
-
checkTable == this.table ? this.newIndex = e.targElm.cellIndex : false
-
}
-
-
// start the function to sort the column
-
dragObj.sortColumn(this.oldIndex,this.newIndex)
-
-
// remove visual effect from column being dragged
-
this.draggedCell.className = ""
-
// clear the variable
-
this.draggedCell = null
-
}
-
-
dragTable.prototype.sortColumn = function(o,d) {
-
// returns if destionation dont have a valid index
-
if (d == null) return
-
// returns if origin is equals to the destination
-
if (o == d) return
-
-
// loop through every row
-
for (x=0; x<this.tableRows.length; x++) {
-
// array with the cells of the row x
-
tds = this.tableRows[x].cells
-
// remove this cell from the row
-
var cell = this.tableRows[x].removeChild(tds[o])
-
// insert the cell in the new index
-
if (d + 1 >= this.maxIndex) {
-
this.tableRows[x].appendChild(cell)
-
}
-
else {
-
this.tableRows[x].insertBefore(cell, tds[d])
-
}
-
}
-
}
-
-
dragTable.prototype.dragEngine = function(boolean,dragObj) {
-
var _this = this
-
// fire the drop function
-
document.documentElement.onmouseup = boolean ? function(e) { _this.drop(_this,e) } : null
-
// capture the mouse coords
-
document.documentElement.onmousemove = boolean ? function(e) { _this.getCoords(_this,e) } : null
-
}
-
-
dragTable.prototype.getCoords = function(dragObj,e) {
-
if (!e) e = window.event
-
-
// horizontal position
-
dragObj.x = e.pageX ? e.pageX : e.clientX + document.documentElement.scrollLeft
-
// vertical position
-
dragObj.y = e.pageY ? e.pageY : e.clientY + document.documentElement.scrollTop
-
-
if (dragObj.ghostTd) {
-
// make the ghostTd follow the mouse
-
dragObj.ghostTd.style.top = dragObj.y + 5 + "px"
-
dragObj.ghostTd.style.left = dragObj.x + 10 + "px"
-
}
-
}
-
-
table {border-collapse:collapse; table-layout:fixed; width:800px; font:normal 11px arial; border:1px solid #aaa}
-
table thead th {background:#aaa; color:#fff; border:1px solid #000; cursor:pointer}
-
table tbody td {text-indent:5px; border:1px solid #aaa;}
-
-
.ghostTd {width:auto; height:auto; padding:2px 8px; border:1px solid #000; position:absolute; font:normal 10px arial; background:#eee;}
-
.dragging {background:#eee; color:#000}
-
.hovering {background:#ccc; color:#555}
-
-
To init the script, call the dragTable function and pass the id of the table as a parameter. Ex:
t1 = new dragTable('tableOne')
Where t1 will be our reference to the table object
The attachment is a sample page with a table using the drag&drop column script
Any question, comment, sugestion, etc, use the email in the script
Feel free to use and modify the script according to your needs
Just keep the credits there :)
Good luck
| 
December 31st, 2007, 01:33 PM
| | Newbie | | Join Date: Dec 2007
Posts: 1
| | | re: Drag & Drop Table Columns (new version, explained)
I tried using your code as is i.e I organised the code in the following way:
//dragndrop.css - table {border-collapse:collapse; table-layout:fixed; width:800px; font:normal 11px arial; border:1px solid #aaa}
-
table thead th {background:#aaa; color:#fff; border:1px solid #000; cursor:pointer}
-
table tbody td {text-indent:5px; border:1px solid #aaa;}
-
-
.ghostTd {width:auto; height:auto; padding:2px 8px; border:1px solid #000; position:absolute; font:normal 10px arial; background:#eee;}
-
.dragging {background:#eee; color:#000}
-
.hovering {background:#ccc; color:#555}
-
------------------------------------------------------------------
//dragndrop.js - /*
-
Author: Romulo do Nascimento Ferreira
-
E-mail: romulo.nf@mgmail.com
-
-
Drag & Drop Table Columns
-
*/
-
-
-
/* parameters
-
-
id: id of the table that will have drag & drop function
-
-
*/
-
-
function dragTable(id) {
-
// store the cell that will be dragged
-
this.draggedCell = null
-
// true if ghostTd exists
-
this.ghostCreated = false
-
// store the table itselfs
-
this.table = document.getElementById(id)
-
// store every row of the table
-
this.tableRows = this.table.getElementsByTagName("tr")
-
// create a handler array, usualy the ths in the thead, if not possible the first row of tds
-
this.handler = this.table.getElementsByTagName("th").length > 0 ? this.table.getElementsByTagName("th") : this.table.tBodies[0].rows[0].getElementsByTagName("td")
-
// create a cell array
-
this.cells = this.table.getElementsByTagName("td")
-
// store the max index of the column when dropped
-
this.maxIndex = this.handler.length
-
// store the horizontal mouse position
-
this.x;
-
// store the vertical mouse position
-
this.y;
-
// store the index of the column that will be dragged
-
this.oldIndex;
-
// store the index of the destionation of the column
-
this.newIndex;
-
-
for (x=0; x<this.handler.length; x++) {
-
// associate the object with the cells
-
this.handler[x].dragObj = this
-
// override the default action when mousedown and dragging
-
this.handler[x].onselectstart = function() { return false }
-
// fire the drag action and return false to prevent default action of selecting the text
-
this.handler[x].onmousedown = function(e) { this.dragObj.drag(this,e); return false }
-
// visual effect
-
this.handler[x].onmouseover = function(e) { this.dragObj.dragEffect(this,e) }
-
this.handler[x].onmouseout = function(e) { this.dragObj.dragEffect(this,e) }
-
this.handler[x].onmouseup = function(e) { this.dragObj.dragEffect(this,e) }
-
}
-
-
for (x=0; x<this.cells.length; x++) {
-
this.cells[x].dragObj = this
-
// visual effect
-
this.cells[x].onmouseover = function(e) { this.dragObj.dragEffect(this,e) }
-
this.cells[x].onmouseout = function(e) { this.dragObj.dragEffect(this,e) }
-
this.cells[x].onmouseup = function(e) { this.dragObj.dragEffect(this,e) }
-
}
-
}
-
-
dragTable.prototype.dragEffect = function(cell,e) {
-
// assign event to variable e
-
if (!e) e = window.event
-
-
// return if the cell being hovered is the same as the one being dragged
-
if (cell.cellIndex == this.oldIndex) return
-
-
else {
-
// if there is a cell being dragged
-
if (this.draggedCell) {
-
// change class to give a visual effect
-
e.type == "mouseover" ? this.handler[cell.cellIndex].className = "hovering" : this.handler[cell.cellIndex].className = ""
-
}
-
}
-
}
-
-
dragTable.prototype.drag = function(cell,e) {
-
// reference of the cell that is being dragged
-
this.draggedCell = cell
-
-
// change class for visual effect
-
this.draggedCell.className = "dragging"
-
-
// store the index of the cell that is being dragged
-
this.oldIndex = cell.cellIndex
-
-
// create the ghost td
-
this.createGhostTd(e)
-
// start the engine
-
this.dragEngine(true)
-
}
-
-
dragTable.prototype.createGhostTd = function(e) {
-
// if ghost exists return
-
if (this.ghostCreated) return
-
// assign event to variable e
-
if (!e) e = window.event
-
// horizontal position
-
this.x = e.pageX ? e.pageX : e.clientX + document.documentElement.scrollLeft
-
// vertical position
-
this.y = e.pageY ? e.pageY : e.clientY + document.documentElement.scrollTop
-
-
// create the ghost td (visual effect)
-
this.ghostTd = document.createElement("div")
-
this.ghostTd.className = "ghostTd"
-
this.ghostTd.style.top = this.y + 5 + "px"
-
this.ghostTd.style.left = this.x + 10 + "px"
-
// ghost td receives the content of the dragged cell
-
this.ghostTd.innerHTML = this.handler[this.oldIndex].innerHTML
-
document.getElementsByTagName("body")[0].appendChild(this.ghostTd)
-
-
// assign a flag to see if ghost is created
-
this.ghostCreated = true
-
}
-
-
dragTable.prototype.drop = function(dragObj,e) {
-
// assign event to variable e
-
if (!e) e = window.event
-
// store the target of the event - mouseup
-
e.targElm = e.target ? e.target : e.srcElement
-
-
// end the engine
-
dragObj.dragEngine(false,dragObj)
-
-
// remove the ghostTd
-
dragObj.ghostTd.parentNode.removeChild(dragObj.gho stTd)
-
-
// remove ghost created flag
-
this.ghostCreated = false
-
-
// store the index of the target, if it have one
-
if (e.targElm.cellIndex !="undefined") {
-
checkTable = e.targElm
-
-
// ascend in the dom beggining in the targeted element and ending in a table or the body tag
-
while (checkTable.tagName.toLowerCase() !="table") {
-
if (checkTable.tagName.toLowerCase() == "html") break
-
checkTable = checkTable.parentNode
-
}
-
-
// check if the table where the column was dropped is equal to the object table
-
checkTable == this.table ? this.newIndex = e.targElm.cellIndex : false
-
}
-
-
// start the function to sort the column
-
dragObj.sortColumn(this.oldIndex,this.newIndex)
-
-
// remove visual effect from column being dragged
-
this.draggedCell.className = ""
-
// clear the variable
-
this.draggedCell = null
-
}
-
-
dragTable.prototype.sortColumn = function(o,d) {
-
// returns if destionation dont have a valid index
-
if (d == null) return
-
// returns if origin is equals to the destination
-
if (o == d) return
-
-
// loop through every row
-
for (x=0; x<this.tableRows.length; x++) {
-
// array with the cells of the row x
-
tds = this.tableRows[x].cells
-
// remove this cell from the row
-
var cell = this.tableRows[x].removeChild(tds[o])
-
// insert the cell in the new index
-
if (d + 1 >= this.maxIndex) {
-
this.tableRows[x].appendChild(cell)
-
}
-
else {
-
this.tableRows[x].insertBefore(cell, tds[d])
-
}
-
}
-
}
-
-
dragTable.prototype.dragEngine = function(boolean,dragObj) {
-
var _this = this
-
// fire the drop function
-
document.documentElement.onmouseup = boolean ? function(e) { _this.drop(_this,e) } : null
-
// capture the mouse coords
-
document.documentElement.onmousemove = boolean ? function(e) { _this.getCoords(_this,e) } : null
-
}
-
-
dragTable.prototype.getCoords = function(dragObj,e) {
-
if (!e) e = window.event
-
-
// horizontal position
-
dragObj.x = e.pageX ? e.pageX : e.clientX + document.documentElement.scrollLeft
-
// vertical position
-
dragObj.y = e.pageY ? e.pageY : e.clientY + document.documentElement.scrollTop
-
-
if (dragObj.ghostTd) {
-
// make the ghostTd follow the mouse
-
dragObj.ghostTd.style.top = dragObj.y + 5 + "px"
-
dragObj.ghostTd.style.left = dragObj.x + 10 + "px"
-
}
-
}
-
-------------------------------------------------------------
//dragndrop.htm
However when I open dragndrop.htm i get a javscript error stating
Line: 17
Char: 1
Error: 'dragTable' is undefined.
Code: 0
Do I need to take care of something else as well.
Regards,
Nitin
Last edited by acoder; December 31st, 2007 at 03:59 PM.
Reason: Added code tags
| 
December 31st, 2007, 03:14 PM
| | Member | | Join Date: Nov 2006
Posts: 53
| | | re: Drag & Drop Table Columns (new version, explained)
Not really! All you need to use the script is:
- a table with standard markup (table, thead, tbody, tr, td, th)
- load the js into the page
- init the script using a onload event and passing the id of the table. i.e: dragTable(tableID)
Just make sure the js is being loaded and then call the function, everything should work fine
Good luck
| 
January 1st, 2008, 09:10 AM
|  | Site Moderator | | Join Date: Nov 2006 Location: UK
Posts: 14,517
| | | re: Drag & Drop Table Columns (new version, explained)
The most probable reason for this is the code tag bug on line 126 of the JavaScript code: - dragObj.ghostTd.parentNode.removeChild(dragObj.gho stTd)
Note spaces(s). Remove the space(s) to make it: - dragObj.ghostTd.parentNode.removeChild(dragObj.ghostTd)
Hopefully, that should fix it.
Edit: it even appears in one line of code! Argh! Well, just remove the space between 'o' and 's' in ghostTd.
| 
February 11th, 2008, 06:17 PM
| | Newbie | | Join Date: Feb 2008
Posts: 1
| | | re: Drag & Drop Table Columns (new version, explained)
after changing the 'gho stTd' to 'ghostTd' in line no 252 it is working perfectly. Great Script , keep going.............
|  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 225,662 network members.
|