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
[code=javascript]
/*
Author: Romulo do Nascimento Ferreira
E-mail: romulo.nf@mgmai l.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.draggedCel l = null
// true if ghostTd exists
this.ghostCreat ed = false
// store the table itselfs
this.table = document.getEle mentById(id)
// store every row of the table
this.tableRows = this.table.getE lementsByTagNam e("tr")
// create a handler array, usualy the ths in the thead, if not possible the first row of tds
this.handler = this.table.getE lementsByTagNam e("th").lengt h > 0 ? this.table.getE lementsByTagNam e("th") : this.table.tBod ies[0].rows[0].getElementsByT agName("td")
// create a cell array
this.cells = this.table.getE lementsByTagNam e("td")
// store the max index of the column when dropped
this.maxIndex = this.handler.le ngth
// 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.dr ag(this,e); return false }
// visual effect
this.handler[x].onmouseover = function(e) { this.dragObj.dr agEffect(this,e ) }
this.handler[x].onmouseout = function(e) { this.dragObj.dr agEffect(this,e ) }
this.handler[x].onmouseup = function(e) { this.dragObj.dr agEffect(this,e ) }
}
for (x=0; x<this.cells.le ngth; x++) {
this.cells[x].dragObj = this
// visual effect
this.cells[x].onmouseover = function(e) { this.dragObj.dr agEffect(this,e ) }
this.cells[x].onmouseout = function(e) { this.dragObj.dr agEffect(this,e ) }
this.cells[x].onmouseup = function(e) { this.dragObj.dr agEffect(this,e ) }
}
}
dragTable.proto type.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.draggedCe ll) {
// change class to give a visual effect
e.type == "mouseover" ? this.handler[cell.cellIndex].className = "hovering" : this.handler[cell.cellIndex].className = ""
}
}
}
dragTable.proto type.drag = function(cell,e ) {
// reference of the cell that is being dragged
this.draggedCel l = cell
// change class for visual effect
this.draggedCel l.className = "dragging"
// store the index of the cell that is being dragged
this.oldIndex = cell.cellIndex
// create the ghost td
this.createGhos tTd(e)
// start the engine
this.dragEngine (true)
}
dragTable.proto type.createGhos tTd = function(e) {
// if ghost exists return
if (this.ghostCrea ted) return
// assign event to variable e
if (!e) e = window.event
// horizontal position
this.x = e.pageX ? e.pageX : e.clientX + document.docume ntElement.scrol lLeft
// vertical position
this.y = e.pageY ? e.pageY : e.clientY + document.docume ntElement.scrol lTop
// create the ghost td (visual effect)
this.ghostTd = document.create Element("div")
this.ghostTd.cl assName = "ghostTd"
this.ghostTd.st yle.top = this.y + 5 + "px"
this.ghostTd.st yle.left = this.x + 10 + "px"
// ghost td receives the content of the dragged cell
this.ghostTd.in nerHTML = this.handler[this.oldIndex].innerHTML
document.getEle mentsByTagName( "body")[0].appendChild(th is.ghostTd)
// assign a flag to see if ghost is created
this.ghostCreat ed = true
}
dragTable.proto type.drop = function(dragOb j,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.dragEng ine(false,dragO bj)
// remove the ghostTd
dragObj.ghostTd .parentNode.rem oveChild(dragOb j.ghostTd)
// remove ghost created flag
this.ghostCreat ed = false
// store the index of the target, if it have one
if (e.targElm.cell Index !="undefined" ) {
checkTable = e.targElm
// ascend in the dom beggining in the targeted element and ending in a table or the body tag
while (checkTable.tag Name.toLowerCas e() !="table") {
if (checkTable.tag Name.toLowerCas e() == "html") break
checkTable = checkTable.pare ntNode
}
// check if the table where the column was dropped is equal to the object table
checkTable == this.table ? this.newIndex = e.targElm.cellI ndex : false
}
// start the function to sort the column
dragObj.sortCol umn(this.oldInd ex,this.newInde x)
// remove visual effect from column being dragged
this.draggedCel l.className = ""
// clear the variable
this.draggedCel l = null
}
dragTable.proto type.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.tableRow s.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(td s[o])
// insert the cell in the new index
if (d + 1 >= this.maxIndex) {
this.tableRows[x].appendChild(ce ll)
}
else {
this.tableRows[x].insertBefore(c ell, tds[d])
}
}
}
dragTable.proto type.dragEngine = function(boolea n,dragObj) {
var _this = this
// fire the drop function
document.docume ntElement.onmou seup = boolean ? function(e) { _this.drop(_thi s,e) } : null
// capture the mouse coords
document.docume ntElement.onmou semove = boolean ? function(e) { _this.getCoords (_this,e) } : null
}
dragTable.proto type.getCoords = function(dragOb j,e) {
if (!e) e = window.event
// horizontal position
dragObj.x = e.pageX ? e.pageX : e.clientX + document.docume ntElement.scrol lLeft
// vertical position
dragObj.y = e.pageY ? e.pageY : e.clientY + document.docume ntElement.scrol lTop
if (dragObj.ghostT d) {
// make the ghostTd follow the mouse
dragObj.ghostTd .style.top = dragObj.y + 5 + "px"
dragObj.ghostTd .style.left = dragObj.x + 10 + "px"
}
}
[/code]
[code=css]
table {border-collapse:collap se; table-layout:fixed; width:800px; font:normal 11px arial; border:1px solid #aaa}
table thead th {background:#aa a; 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:absolu te; font:normal 10px arial; background:#eee ;}
.dragging {background:#ee e; color:#000}
.hovering {background:#cc c; color:#555}
[/code]
To init the script, call the dragTable function and pass the id of the table as a parameter. Ex:
t1 = new dragTable('tabl eOne')
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
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
[code=javascript]
/*
Author: Romulo do Nascimento Ferreira
E-mail: romulo.nf@mgmai l.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.draggedCel l = null
// true if ghostTd exists
this.ghostCreat ed = false
// store the table itselfs
this.table = document.getEle mentById(id)
// store every row of the table
this.tableRows = this.table.getE lementsByTagNam e("tr")
// create a handler array, usualy the ths in the thead, if not possible the first row of tds
this.handler = this.table.getE lementsByTagNam e("th").lengt h > 0 ? this.table.getE lementsByTagNam e("th") : this.table.tBod ies[0].rows[0].getElementsByT agName("td")
// create a cell array
this.cells = this.table.getE lementsByTagNam e("td")
// store the max index of the column when dropped
this.maxIndex = this.handler.le ngth
// 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.dr ag(this,e); return false }
// visual effect
this.handler[x].onmouseover = function(e) { this.dragObj.dr agEffect(this,e ) }
this.handler[x].onmouseout = function(e) { this.dragObj.dr agEffect(this,e ) }
this.handler[x].onmouseup = function(e) { this.dragObj.dr agEffect(this,e ) }
}
for (x=0; x<this.cells.le ngth; x++) {
this.cells[x].dragObj = this
// visual effect
this.cells[x].onmouseover = function(e) { this.dragObj.dr agEffect(this,e ) }
this.cells[x].onmouseout = function(e) { this.dragObj.dr agEffect(this,e ) }
this.cells[x].onmouseup = function(e) { this.dragObj.dr agEffect(this,e ) }
}
}
dragTable.proto type.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.draggedCe ll) {
// change class to give a visual effect
e.type == "mouseover" ? this.handler[cell.cellIndex].className = "hovering" : this.handler[cell.cellIndex].className = ""
}
}
}
dragTable.proto type.drag = function(cell,e ) {
// reference of the cell that is being dragged
this.draggedCel l = cell
// change class for visual effect
this.draggedCel l.className = "dragging"
// store the index of the cell that is being dragged
this.oldIndex = cell.cellIndex
// create the ghost td
this.createGhos tTd(e)
// start the engine
this.dragEngine (true)
}
dragTable.proto type.createGhos tTd = function(e) {
// if ghost exists return
if (this.ghostCrea ted) return
// assign event to variable e
if (!e) e = window.event
// horizontal position
this.x = e.pageX ? e.pageX : e.clientX + document.docume ntElement.scrol lLeft
// vertical position
this.y = e.pageY ? e.pageY : e.clientY + document.docume ntElement.scrol lTop
// create the ghost td (visual effect)
this.ghostTd = document.create Element("div")
this.ghostTd.cl assName = "ghostTd"
this.ghostTd.st yle.top = this.y + 5 + "px"
this.ghostTd.st yle.left = this.x + 10 + "px"
// ghost td receives the content of the dragged cell
this.ghostTd.in nerHTML = this.handler[this.oldIndex].innerHTML
document.getEle mentsByTagName( "body")[0].appendChild(th is.ghostTd)
// assign a flag to see if ghost is created
this.ghostCreat ed = true
}
dragTable.proto type.drop = function(dragOb j,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.dragEng ine(false,dragO bj)
// remove the ghostTd
dragObj.ghostTd .parentNode.rem oveChild(dragOb j.ghostTd)
// remove ghost created flag
this.ghostCreat ed = false
// store the index of the target, if it have one
if (e.targElm.cell Index !="undefined" ) {
checkTable = e.targElm
// ascend in the dom beggining in the targeted element and ending in a table or the body tag
while (checkTable.tag Name.toLowerCas e() !="table") {
if (checkTable.tag Name.toLowerCas e() == "html") break
checkTable = checkTable.pare ntNode
}
// check if the table where the column was dropped is equal to the object table
checkTable == this.table ? this.newIndex = e.targElm.cellI ndex : false
}
// start the function to sort the column
dragObj.sortCol umn(this.oldInd ex,this.newInde x)
// remove visual effect from column being dragged
this.draggedCel l.className = ""
// clear the variable
this.draggedCel l = null
}
dragTable.proto type.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.tableRow s.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(td s[o])
// insert the cell in the new index
if (d + 1 >= this.maxIndex) {
this.tableRows[x].appendChild(ce ll)
}
else {
this.tableRows[x].insertBefore(c ell, tds[d])
}
}
}
dragTable.proto type.dragEngine = function(boolea n,dragObj) {
var _this = this
// fire the drop function
document.docume ntElement.onmou seup = boolean ? function(e) { _this.drop(_thi s,e) } : null
// capture the mouse coords
document.docume ntElement.onmou semove = boolean ? function(e) { _this.getCoords (_this,e) } : null
}
dragTable.proto type.getCoords = function(dragOb j,e) {
if (!e) e = window.event
// horizontal position
dragObj.x = e.pageX ? e.pageX : e.clientX + document.docume ntElement.scrol lLeft
// vertical position
dragObj.y = e.pageY ? e.pageY : e.clientY + document.docume ntElement.scrol lTop
if (dragObj.ghostT d) {
// make the ghostTd follow the mouse
dragObj.ghostTd .style.top = dragObj.y + 5 + "px"
dragObj.ghostTd .style.left = dragObj.x + 10 + "px"
}
}
[/code]
[code=css]
table {border-collapse:collap se; table-layout:fixed; width:800px; font:normal 11px arial; border:1px solid #aaa}
table thead th {background:#aa a; 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:absolu te; font:normal 10px arial; background:#eee ;}
.dragging {background:#ee e; color:#000}
.hovering {background:#cc c; color:#555}
[/code]
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Drag N' Drop Table Columns</title>
<script src="dragndrop.js"></script>
<link rel="stylesheet" href="dragndrop.css">
<script>
// init the script
window.onload = function() {
// create a variable for the object
t1 = new dragTable('tableOne')
}
</script>
</head>
<body>
<table id="tableOne">
<thead>
<tr>
<th>HEADER 1</th>
<th>HEADER 2</th>
<th>HEADER 3</th>
<th>HEADER 4</th>
<th>HEADER 5</th>
<th>HEADER 6</th>
<th>HEADER 7</th>
<th>HEADER 8</th>
<th>HEADER 9</th>
<th>HEADER 10</th>
</tr>
</thead>
<tbody>
<tr>
<td>Dummy 1</td>
<td>Dummy 2</td>
<td>Dummy 3</td>
<td>Dummy 4</td>
<td>Dummy 5</td>
<td>Dummy 6</td>
<td>Dummy 7</td>
<td>Dummy 8</td>
<td>Dummy 9</td>
<td>Dummy 10</td>
</tr>
<tr>
<td>Dummy 1</td>
<td>Dummy 2</td>
<td>Dummy 3</td>
<td>Dummy 4</td>
<td>Dummy 5</td>
<td>Dummy 6</td>
<td>Dummy 7</td>
<td>Dummy 8</td>
<td>Dummy 9</td>
<td>Dummy 10</td>
</tr>
<tr>
<td>Dummy 1</td>
<td>Dummy 2</td>
<td>Dummy 3</td>
<td>Dummy 4</td>
<td>Dummy 5</td>
<td>Dummy 6</td>
<td>Dummy 7</td>
<td>Dummy 8</td>
<td>Dummy 9</td>
<td>Dummy 10</td>
</tr>
<tr>
<td>Dummy 1</td>
<td>Dummy 2</td>
<td>Dummy 3</td>
<td>Dummy 4</td>
<td>Dummy 5</td>
<td>Dummy 6</td>
<td>Dummy 7</td>
<td>Dummy 8</td>
<td>Dummy 9</td>
<td>Dummy 10</td>
</tr>
<tr>
<td>Dummy 1</td>
<td>Dummy 2</td>
<td>Dummy 3</td>
<td>Dummy 4</td>
<td>Dummy 5</td>
<td>Dummy 6</td>
<td>Dummy 7</td>
<td>Dummy 8</td>
<td>Dummy 9</td>
<td>Dummy 10</td>
</tr>
<tr>
<td>Dummy 1</td>
<td>Dummy 2</td>
<td>Dummy 3</td>
<td>Dummy 4</td>
<td>Dummy 5</td>
<td>Dummy 6</td>
<td>Dummy 7</td>
<td>Dummy 8</td>
<td>Dummy 9</td>
<td>Dummy 10</td>
</tr>
<tr>
<td>Dummy 1</td>
<td>Dummy 2</td>
<td>Dummy 3</td>
<td>Dummy 4</td>
<td>Dummy 5</td>
<td>Dummy 6</td>
<td>Dummy 7</td>
<td>Dummy 8</td>
<td>Dummy 9</td>
<td>Dummy 10</td>
</tr>
<tr>
<td>Dummy 1</td>
<td>Dummy 2</td>
<td>Dummy 3</td>
<td>Dummy 4</td>
<td>Dummy 5</td>
<td>Dummy 6</td>
<td>Dummy 7</td>
<td>Dummy 8</td>
<td>Dummy 9</td>
<td>Dummy 10</td>
</tr>
<tr>
<td>Dummy 1</td>
<td>Dummy 2</td>
<td>Dummy 3</td>
<td>Dummy 4</td>
<td>Dummy 5</td>
<td>Dummy 6</td>
<td>Dummy 7</td>
<td>Dummy 8</td>
<td>Dummy 9</td>
<td>Dummy 10</td>
</tr>
</tbody>
</table>
</body>
</html>
t1 = new dragTable('tabl eOne')
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
Comment