Pierre Syraud

Navigation

Skip navigation.

Search

Site navigation

Email conversation

FromPierre Syraud
ToMe
SubjectNews on Dragable table cell enhancement
Date16 February 2007 00:02
Hello!

First off let me say a big thank you for your site.  It's a fantastic
resource!  It's helped me a lot while trying to learn javascript and the DOM
and so forth.I have modify some thing on script for include thead, tfoot,
th, tbody elements can be moved width.I also include remarks of Bryan Harris
for deselect object when his moved.A bug persist on Ie, can't move a columns
on the last columns because insertBefore need a before element....Contact me
on [email] for new functionnality or new debug.
//sort type: 0 = row, 1 = column, 2 = column (for one row only)
//this number can be changed at any time (even after the page has loaded),
except while actually
//dragging something
var tableSortType = 1,undefined;
//column sorting is based on TD elements only, not TH (if the table contains
any TH elements, the script
//will not be able to sort all rows of the table)
//this does not work in IE 5 Mac because it incorrectly calculates positions
of table cells.
//unfortunately the workaround would make this script more difficult;
//all calls to MWJ_getPosition must instead get the position of an element
that is inside the TD and
//completely filling the TD - a DIV is useful here. it will still crash if
you try to move elements to
//the end of their row or table.
//thankfully this browser has been almost completely replaced by Safari, so
I do not recommend trying
function start_col_modif(a){
if( document.getElementById && document.createElement && document.childNodes
) {
 var theTable = document.getElementById(a),y;
 for( var i = 0, x = theTable.getElementsByTagName('tr'); x[i]; i++ ) {
 y=x[i].childNodes;j=0;
  // for each elements of TR , clean spacing between
  for( var p = 0; 1;p++ ) {if(y[p]==null){break;}else
if(y[p].nodeType!=1){x[i].removeChild(y[p]);--p;continue;}
   //all table cells must watch for the mouse to click on them
   //every time you add a new cell, you must also run these two functions on
them
   if(i==0&&!y[j].id){y[j].id='cello'+j;cello=j;}// fixe a id for memory
compare columns are moved
   MWJ_monitorButton( y[j], 'mousedown', startDrag );
   y[j].onselectstart = function () { return false; };
  j++;}}}}
function startDrag(e,oCode,oButton,oElement) {
 if( oButton != 'left' ) { return; }
 if( !e ) { e = window.event; }
 if( e.preventDefault ) { e.preventDefault(); }
 //they have clicked down. must store position and watch to see if they drag
it
 window.storeMousePos = MWJ_getMouseCoords(e);
 window.mouseIsDown = tableSortType ? oElement : oElement.parentNode;
 MWJ_monitorMouse(mouseismove);
 MWJ_monitorButton( document, 'mouseup', stopDrag );
}
function mouseismove() {
 if( !window.mouseIsDown ) { return; }
 //they have started dragging
 //moving table cells causes many problems so create a false element for
them to move
 if( !window.falseElement ) {
  window.falseElement = document.createElement('div');
  falseElement.style.position = 'absolute';
  falseElement.style.width = mouseIsDown.offsetWidth + 'px';
  falseElement.style.height = mouseIsDown.offsetHeight + 'px';
  falseElement.style.border = '1px solid #00f';
  document.body.appendChild(falseElement);
 }
 deselect ();// deselect the selection (bug select....)
 //move the false element to the calculated position
 var cellXY = MWJ_getPosition( mouseIsDown );
 falseElement.style.left = tableSortType ? (
((MWJ_getMouse[0]-storeMousePos[0])+cellXY[0])+'px' ) : ( cellXY[0]+'px' );
 falseElement.style.top = tableSortType ? ( cellXY[1]+'px' ) : (
((MWJ_getMouse[1]-storeMousePos[1])+cellXY[1])+'px' );
}
function stopDrag() {
 if( window.falseElement ) {
  //stop monitoring the mouse
  document.onmousemove = null;
  document.body.removeChild(falseElement);
  window.falseElement = false;
  //work out what orders they should be in, based on the position of the
left edge of the cell, or top position of the row
  var currentPosition = tableSortType ? (
(MWJ_getMouse[0]-storeMousePos[0])+MWJ_getPosition( mouseIsDown )[0] ) : (
(MWJ_getMouse[1]-storeMousePos[1])+MWJ_getPosition( mouseIsDown )[1] );
  //find out the index of the cell they dragged
 if(!tableSortType){// For Rows
   for( var dragCellPos = 0, x =
mouseIsDown.parentNode.getElementsByTagName('tr'); x[dragCellPos] !=
mouseIsDown; dragCellPos++ ) { }
  for( var i = 0, x = mouseIsDown.parentNode.getElementsByTagName('tr'),
beforeThis = x.length; x[i]; i++ ) {
   var cellPosition = MWJ_getPosition( x[i] )[1];
   if( x[i] != mouseIsDown && currentPosition < cellPosition && !(
beforeThis - x.length ) ) {
    //we are not dealing with the actual cell that is being dragged and the
dragged cell must be inserted before this one
    beforeThis = i;
   }
  }
 }else{ // For Cells
  var x=mouseIsDown.parentNode.childNodes,dragCellPos=0,i=0,k=0,p;
  for(p=0;1;p++){if(x[p]==null){break;}else if(x[dragCellPos] !=
mouseIsDown){dragCellPos++;}k++;}
  beforeThis = k;          
  for(p=0;1;p++){if(x[p]==null){break;}
  var cellPosition = MWJ_getPosition( x[i] )[0];
  if( x[i] != mouseIsDown && currentPosition < cellPosition && !( beforeThis
- k ) ) {
    //we are not dealing with the actual cell that is being dragged and the
dragged cell must be inserted before this one
    beforeThis = i;
   }
i++;}
 }
 
  //find out the index of the cell it must be put before (I could just swap
directly, but this way, I can swap them for all rows)
 
  //we now have the new ordering that is required - stored as the index of
the cell it must be inserted before
  if( beforeThis != dragCellPos + 1 ) {
   //a move is required
   //now decide if we should re-arrange the whole table or just that row -
this is up to the person who uses this script
   switch( tableSortType ) {
    case 0:
     //re-arrange rows in the body
     var trs = mouseIsDown.parentNode.getElementsByTagName('tr');
     mouseIsDown.parentNode.insertBefore(mouseIsDown,trs[beforeThis]);
     break;
    case 1:
     //re-arrange cells in all rows
     for( var i = 0, y =
mouseIsDown.parentNode.parentNode.parentNode.getElementsByTagName('tr'), oE;
oE = y[i]; i++ ) {
      //for each row
      var tds1=oE.childNodes,j=0,jj=0,tds=new Array();
      for(p=0;1;p++){if(tds1[p]==null||jj>1){break;}else
if(j==dragCellPos||j==beforeThis){jj++;tds[j]=tds1[p];}
       j++;}
     
if(jj!=2){if(jj==0){continue;}else{if(tds[beforeThis]==undefined){alert('bug
IE');
       tds[beforeThis]=oE.lastChild;}}}
      oE.insertBefore(tds[dragCellPos],tds[beforeThis]);
      }
     break;
    default:
     //re-arrange cells in just this row
     var tds = mouseIsDown.parentNode.getElementsByTagName('td');
     mouseIsDown.parentNode.insertBefore(mouseIsDown,tds[beforeThis]);
   }
  }
 }
 window.mouseIsDown = false;
}
function deselect () {
  if (document.selection)
    document.selection.empty();
  else if (window.getSelection)
    window.getSelection().removeAllRanges();
}

start_col_modif('canBeSorted');
FromMe
ToPierre Syraud
SubjectRe: News on Dragable table cell enhancement
Date17 February 2007 12:04
Hi,

> I have modify some thing on script for include
> thead, tfoot, th, tbody elements can be moved width.

Nice.

> I also include
> remarks of Bryan Harris for deselect object when his moved.

This is more easily done using:
falseElement.onselectstart = function () { return false; };

> A bug
> persist on Ie, can't move a columns on the last columns because
> insertBefore need a before element.

Ouch, that bug is supposed to be IE mac only. Maybe the windows version also
has it for table elements. In any case, I have added a fix for this in my
version of the script:
http://www.howtocreate.co.uk/emails/swapColumns.html

Thanks for letting me know.


Mark 'Tarquin' Wilton-Jones - author of http://www.howtocreate.co.uk/
This site was created by Mark "Tarquin" Wilton-Jones.
Don't click this link unless you want to be banned from our site.