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
Expand|Select|Wrap|Line Numbers
- /*
- 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"
- }
- }
Expand|Select|Wrap|Line Numbers
- 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}
Expand|Select|Wrap|Line Numbers
- <!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('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