:: Forum >> Version 2 >>

This example shows how to Drag and Drop Rows in a v2.0 Grid to change the row order

I hacked away at other examples and finally have a very basic example of reordering rows in a grid using drag and drop. This works in V2.0 beta 4.

Give it a try and please post enhancements. To make it easy to save to your hard drive I have uploaded it to:
http://epixpro.com/aw/dragdroprow.txt

Save that file to your ActiveWidgets directory as a html file.

Here is the code (keeping my fingers crossed that it will post right)

<html
<
head
    <
script src="runtime/lib/aw.js"></script
    <
link href="runtime/styles/xp/aw.css" rel="stylesheet"></link
</
head
<
body
This is a very simple drag and drop example to move rows. <b>Click and drag a cell to move a row to a new location</b>.
<
hr>
<
style
    
#myGrid width600pxheight:350px;  margin0pxpadding0px
    
#myGrid .aw-alternate-even .aw-column-{background#E0E0E0;} 
    
#myGrid .aw-alternate-odd  .aw-column-{background#E0E0E0;} 
    
#myGrid .aw-alternate-even {background#E7E7D6;} 
    
#myGrid .aw-alternate-odd  {background#F7F3E7;} 
    
#myGrid .aw-rows-selected {background#316ac5;}
    
#myGrid .aw-rows-selected .aw-column-{background#316ac5;}
</
style

<
script

    var 
HeaderText = ["Number","Description"]; 
    var 
CellText = [ 
        [
"1","Description 1"], 
        [
"2","Description 2"], 
        [
"3","Description 3"], 
        [
"4","Description 4"], 
        [
"5","Description 5"], 
        [
"6","Description 6"], 
        [
"7","Description 7"], 
        [
"8","Description 8"], 
        [
"9","Description 9"], 
        [
"10","Description 10"], 
        [
"11","Description 11"], 
        [
"12","Description 12"], 
        [
"13","Description 13"], 
        [
"14","Description 14"], 
        [
"15","Description 15"]
    ]; 

    var 
obj = new AW.UI.Grid;

    
obj.setId("myGrid");  // necessary for CSS rules 
    
obj.setHeaderText(HeaderText); 
    
obj.setCellText(CellText); 
    
obj.setColumnCount(2); 
    
obj.setRowCount(15); 

    
// DISABLE SORTING - This simple example will not work if sorted
    
obj.onHeaderClicked = function(event,index){return 'disabled'};

    
obj.setSelectionMode("single-row");

    
document.write(obj); 

    
// THESE ARE CALLED TO START AND STOP THE DRAG AND DROP OF ROWS
    
obj.onCellMouseDown        = function(eventcolumnrow){ if (column>0dragstart(eventcolumnrow) }; 
    
obj.onCellMouseUp        = function(eventcolumnrow){ dragstop(columnrow) }; 


    
// DRAGGING FUNCTIONS
    
var startrowendrow
     
    
function dragstart(ecolumnrow){ 
        
startrow=row;
        
window.status "Drag Start Row:"+row;
    } 
     
    function 
dragstop(columnrow){ 

        if (
document.getElementById("myGrid")) document.getElementById("myGrid").onmousemove=null
        
stoprow=row;
        
window.status window.status " dragstop row=" stoprow;

        
// NOTE: THE TIMES 1 (*1) IN ALL CODE BELOW 
        // IS TO MAKE SURE JAVASCRIPT TREATS THE VARS
        // AS NUMBERS INSTEAD OF STRINGS
        //
        // THIS CODE ONLY WORKS FOR A GRID BASED ON AN ARRAY.
        // IT USES THE "splice" COMMAND TO ADD AND DELETE
        // ROWS DIRECTLY IN THE ARRAY.
        //
        // ex. splice (start position, num of rows to delete, optional data to insert)
        // To delete 1 row use splice(rowindex,1)
        // To add a row without deleting another use spice(rowindex,0,newdata)

        // GET CONTENTS OF DRAG ROW... NOTE THIS GETS THE ENTIRE ROW
        // SUCH AS ["7","Description 7"]
        
var startrowcontents CellText[startrow];

        if ( (
stoprow*1) > (startrow*1)) {
            
// DRAG AND DROP IN DOWNWARD DIRECTION
            
CellText.splice((stoprow*1)+1,0,startrowcontents); //INSERT DRAG ROW BELOW DROP ROW
            
CellText.splice(startrow,1); // DELETE DRAG ROW

        // DRAG AND DROP IN UPWARD DIRECTION
        
} else if ((stoprow*1) < (startrow*1)) {
            
CellText.splice((stoprow*1),0,startrowcontents); // INSERT DRAG ROW ABOVE DROP ROW
            
CellText.splice((startrow*1)+1,1); // DELETE DRAG ROW, NOTE IT IS PUSHED DOWN 1 BECAUSE OF THE INSERT ABOVE

        // DRAG AND DROP TO SAME ROW (IGNORE)
        
} else { 
            
window.status "Don't Move ... Start and Stop Row are the same ("+startrow+","+stoprow+")"
        }

        
// FYI... IF YOU WANTED TO HARD CODE THE DATA TO INSERT IT WOULD LOOK LIKE THIS
        //  CellText.splice(stoprow,0,["17","Description 17"]);

        
obj.refresh();
    } 

</
script

<
hr>
I tested it using AW 2.0 beta 4 and IE and Firefox 1.0It has several limitations
<ul>
<
li>Only works on ARRAY based grid.
<
li>Array is manipulated directly using spliceI wanted to use addRow and deleteRow but I couldn't figure out how to set the insert location for addRow (it was always inserting at the end of the grid).
<li>No visual feedback when dragging the row ... please someone figure out how to add that :)
<li>Sorting is not supported so it is disabled
</ul>

</body> 
</html> 
 
I hope this is a good starting point and useful for others. I found some great 1.0 examples on the forum but not much for 2.0. All you great coders out there please submit a more generic and flexible example :)

Thanks!
Rob Francis
Wednesday, February 1, 2006
Rob, nice example. This will give others a place to start from. Do I have your permission to post this to the Demo page on my site. www.FriendsOfAW.com?

Thanks for the fine effort!
Jim Hunter
Wednesday, February 1, 2006
Hey Jim ... yes please post it over there for me!

Rob Francis
Wednesday, February 1, 2006
I have it added now so if anyone want to see the demo but doesn't want to go through the trouble of editing the file to fit your computer, you can check it out at:

http://friendsofaw.com/nuke/modules.php?name=Demos

Thanks Rob!
Jim Hunter
Wednesday, February 1, 2006
Great example!!! Before looking at this code I was always thinking that drag-and-drop is something very complex :-)
Alex (ActiveWidgets)
Wednesday, February 1, 2006
To make it working with RC1 add #myGrid {-moz-user-select: none} to the style block.
Alex (ActiveWidgets)
Wednesday, February 1, 2006
Alex ... That worked! Plus a quick run through of my other V2 code is looking good under RC1 too.

I also added a add row and delete row button to this example with the code below:

Added this Javascript
function del(){
      var 
insertindex=obj.getCurrentRow();
          
CellText.splice(insertindex,1);
      
obj.setRowCount(obj.getRowCount()-1);

      
obj.refresh();
    }


    function 
add(){
      var 
insertindex=obj.getCurrentRow();
          
CellText.splice((insertindex*1)+1,0,["new","new"]);

      
obj.setRowCount(obj.getRowCount()+1);

      
obj.refresh();

    }
 
Added this HTML
<button onclick="add()">add row below current</button>
<
button onclick="del()">delete current row</button>
 
The full updated version is at:
http://www.epixpro.com/aw/dragdroprow.txt
Rob Francis
Wednesday, February 1, 2006
Hi Rob,
Thanks , it's a Nice & very useful Sample:
I just discovered a small bug in this sample ( it happens after dragging any row in col-1 and then do a row-drag in col-0 "intend to be disabled").
It can be easy solved by doing a little change in oncellMouseDown/oncellMouseUp functions by:

// THESE ARE CALLED TO START AND STOP THE DRAG AND DROP OF ROWS
    
obj.onCellMouseDown        = function(eventcolumnrow){ 
    if (
column>0) {dragstart(eventcolumnrow) }
    else { 
startrow null }
    }; 
    
obj.onCellMouseUp        = function(eventcolumnrow){
     if (
startrow) { dragstop(columnrow) }
      }; 
  
And here is (as requested) ;-) my first attempt to add a visual row-drag-effect :
It is based on a great Austin Mayberry's sample page enhancement drag-drop-columns (which I'm currently triyng to convert too )
(but in this case adapted for rows and V2.0):
/javascript.forum.3258.21/dropdown-grid-template.html

( Did not test it a lot (especially inside div/table and many other situations, so could be buggy also).
Please report any issue found:
HTH

var RowsArea obj.getRowsTemplate();
var 
mouseCelldown false;
var 
RowTarget;
var 
CellTarget;
var 
TopRowTG;
var 
rightScroll;
var 
bottomScroll;

/*****************/
 
var dragColStart = function(event) {       

if(!
AW.ie) {  CellTarget event.target  }
else{ 
CellTarget event.srcElement  }

 var 
sECId CellTarget.id ;
 if (
sECId.indexOf("-box-text") > ){ RowTarget CellTarget.parentNode.parentNode }
else { 
RowTarget CellTarget.parentNode }

rightScroll obj.getScrollLeft();
bottomScroll obj.getScrollTop();

TopRowTG RowTarget.parentNode.firstChild;

RowTarget.width=RowTarget.offsetWidth;
RowTarget.height=RowTarget.offsetHeight;

///get column number
 
var arrofcolumns CellTarget.id.split("-");

//disable row-drag visual effect on some rows (IN CURRENT SAMPLE ROW 0 IS DISABLED)
if ( arrofcolumns[2] >){    mouseCelldown true }
else {
mouseCelldown false }
}

/********************************/    

var dragCol = function(event) {

if(!
AW.ie) { var event.pageX  ; var event.pageY ; }
else{ var 
event.screenX ; var y=event.screenY }

var 
DragRow document.getElementById('DragRow');
if(
DragRow) {  

  if(!
AW.ie){ 
  if(
rightScroll==0){ DragRow.style.left AW.getLeft(CellTarget)  - obj.getSelectorWidth() }
  else{ 
DragRow.style.left x   rightScroll AW.getLeft(CellTarget) - obj.getSelectorWidth() }
  if(
bottomScroll==0){ DragRow.style.top AW.getTop(TopRowTG) + 3; }
  else{ 
DragRow.style.top bottomScroll AW.getTop(TopRowTG) + }
  }
  
  if( 
AW.ie){ 
 
DragRow.style.left window.screenLeft  AW.getLeft(CellTarget) -  obj.getSelectorWidth() + ;
 
DragRow.style.top window.screenTop AW.getTop(TopRowTG) + ;
  }
    }

else if(
mouseCelldown){

var 
DragRow RowTarget.cloneNode(true)
DragRow.id "DragRow";
DragRow.style.position "absolute";
DragRow.style.width RowTarget.width;
DragRow.style.height RowTarget.height;
DragRow.style.zIndex 1000000;
DragRow.style.MozOpacity 0.7
DragRow.style.filter "alpha(opacity=70)" 

RowTarget.parentNode.appendChild(DragRow);
  }
 }
/***********************/
obj.setEvent("onmousemove"dragCol);
RowsArea.setEvent("onmousedown"dragColStart);
 
Carlos
Thursday, February 9, 2006
Uppps SORRY, Comented line:
//disable row-drag visual effect on some rows (IN CURRENT SAMPLE ROW 0 IS DISABLED)
Should say COLUMNS
Thursday, February 9, 2006
Hi Carlos,

Thanks for the bug fix... actually the code that disables (ignores) column zero is left over from the sample I started with. I didn't intend that have that in there but I missed it :)

I would really like to see your visual feedback enhancement but I can't get it to work. I tried adding it to my sample but I must have something wrong.

Can you post the full example.

Thanks!
Rob Francis
Thursday, February 9, 2006
I forgot to say that documnet.write(obj) must be at the bottom of all, (if not the first click on the grid does not fire the visual-e), but after that any dragging works . Could be this ???
I could not locate any other change than I commented your line :
// if (document.getElementById("myGrid")) document.getElementById("myGrid").onmousemove=null;
But if I un-commet it works also.
Anyway here is the complete sample :
Carlos.
<html>  
<
head>  
<
script src="../../runtime/lib/aw.js"></script>
    <
link href="../../runtime/styles/xp/aw.css" rel="stylesheet"></link>
</
head>  
<
body
This is a very simple drag and drop example to move rows. <b>Click and drag a cell to move a row to a new location</b>.
<
hr>
<
style
    
#myGrid width300pxheight:150px;  margin0pxpadding0px
    
#myGrid .aw-alternate-even .aw-column-{background#E0E0E0;} 
    
#myGrid .aw-alternate-odd  .aw-column-{background#E0E0E0;} 
    
#myGrid .aw-alternate-even {background#E7E7D6;} 
    
#myGrid .aw-alternate-odd  {background#F7F3E7;} 
    
#myGrid .aw-rows-selected {background#316ac5;}
    
#myGrid .aw-rows-selected .aw-column-{background#316ac5;}
    
#myGrid {-moz-user-selectnone}
</
style
<
script
    var 
HeaderText = ["Number","Description"]; 
    var 
CellText = [ 
        [
"1","Description 1"], 
        [
"2","Description 2"], 
        [
"3","Description 3"], 
        [
"4","Description 4"], 
        [
"5","Description 5"], 
        [
"6","Description 6"], 
        [
"7","Description 7"], 
        [
"8","Description 8"], 
        [
"9","Description 9"], 
        [
"10","Description 10"], 
        [
"11","Description 11"], 
        [
"12","Description 12"], 
        [
"13","Description 13"], 
        [
"14","Description 14"], 
        [
"15","Description 15"]
    ]; 

    var 
obj = new AW.UI.Grid;

    
obj.setId("myGrid");  // necessary for CSS rules 
    
obj.setHeaderText(HeaderText); 
    
obj.setCellText(CellText); 
    
obj.setColumnCount(2); 
    
obj.setRowCount(15); 

    
// DISABLE SORTING - This simple example will not work if sorted
    
obj.onHeaderClicked = function(event,index){return 'disabled'};

    
obj.setSelectionMode("single-row");

    
obj.setSelectorVisible(true);
//    obj.setSelectorResizable(true);
    
obj.setSelectorWidth(25);

//    obj.setControlSize(100, 200);    // width, height
//    obj.setControlPosition(327, 50);    // left, top - adds 'position:absolute'

//    document.write(obj); 

    // THESE ARE CALLED TO START AND STOP THE DRAG AND DROP OF ROWS
    
obj.onCellMouseDown        = function(eventcolumnrow){ 
    if (
column>0) {dragstart(eventcolumnrow) }
    else { 
startrow null }
    }; 
    
obj.onCellMouseUp        = function(eventcolumnrow){
     if (
startrow) { dragstop(columnrow) }
      }; 


    
// DRAGGING FUNCTIONS
    
var startrowendrow ;
    
    
/**********************/
    
        
function dragstart(ecolumnrow){ 
        
startrow=row;
        
window.status "Drag Start Row:"+row;
 }       

    function 
dragstop(columnrow){ 

//        if (document.getElementById("myGrid")) document.getElementById("myGrid").onmousemove=null; 
        
stoprow=row;
        
window.status window.status " dragstop row=" stoprow;

        
// NOTE: THE TIMES 1 (*1) IN ALL CODE BELOW 
        // IS TO MAKE SURE JAVASCRIPT TREATS THE VARS
        // AS NUMBERS INSTEAD OF STRINGS
        //
        // THIS CODE ONLY WORKS FOR A GRID BASED ON AN ARRAY.
        // IT USES THE "splice" COMMAND TO ADD AND DELETE
        // ROWS DIRECTLY IN THE ARRAY.
        //
        // ex. splice (start position, num of rows to delete, optional data to insert)
        // To delete 1 row use splice(rowindex,1)
        // To add a row without deleting another use spice(rowindex,0,newdata)

        // GET CONTENTS OF DRAG ROW... NOTE THIS GETS THE ENTIRE ROW
        // SUCH AS ["7","Description 7"]
        
var startrowcontents CellText[startrow];

        if ( (
stoprow*1) > (startrow*1)) {
            
// DRAG AND DROP IN DOWNWARD DIRECTION
            
CellText.splice((stoprow*1)+1,0,startrowcontents); //INSERT DRAG ROW BELOW DROP ROW
            
CellText.splice(startrow,1); // DELETE DRAG ROW

        // DRAG AND DROP IN UPWARD DIRECTION
        
} else if ((stoprow*1) < (startrow*1)) {
            
CellText.splice((stoprow*1),0,startrowcontents); // INSERT DRAG ROW ABOVE DROP ROW
            
CellText.splice((startrow*1)+1,1); // DELETE DRAG ROW, NOTE IT IS PUSHED DOWN 1 BECAUSE OF THE INSERT ABOVE

        // DRAG AND DROP TO SAME ROW (IGNORE)
        
} else { 
            
window.status "Don't Move ... Start and Stop Row are the same ("+startrow+","+stoprow+")"
        }

        
// FYI... IF YOU WANTED TO HARD CODE THE DATA TO INSERT IT WOULD LOOK LIKE THIS
        //  CellText.splice(stoprow,0,["17","Description 17"]);


    
obj.setSelectedRows([stoprow]);
    
mouseCelldown false;
        
obj.refresh();
    } 

    function 
del(){
      var 
insertindex=obj.getCurrentRow();
          
CellText.splice(insertindex,1);
      
obj.setRowCount(obj.getRowCount()-1);

      
obj.refresh();
    }

    function 
add(){
      var 
insertindex=obj.getCurrentRow();
          
CellText.splice((insertindex*1)+1,0,["new","new"]);

      
obj.setRowCount(obj.getRowCount()+1);

      
obj.refresh();

    }

/************************/

var RowsArea obj.getRowsTemplate(); 
var 
mouseCelldown false
var 
RowTarget
var 
CellTarget
var 
TopRowTG
var 
rightScroll
var 
bottomScroll

/*****************/ 
 
var dragColStart = function(event) {        

if(!
AW.ie) {  CellTarget event.target  
else{ 
CellTarget event.srcElement  

 var 
sECId CellTarget.id 
 if (
sECId.indexOf("-box-text") > ){ RowTarget CellTarget.parentNode.parentNode 
else { 
RowTarget CellTarget.parentNode 

rightScroll obj.getScrollLeft(); 
bottomScroll obj.getScrollTop(); 

TopRowTG RowTarget.parentNode.firstChild

RowTarget.width=RowTarget.offsetWidth
RowTarget.height=RowTarget.offsetHeight

///get column number 
 
var arrofcolumns CellTarget.id.split("-"); 

//disable row-drag visual effect on some COLUMNS (IN CURRENT SAMPLE DRAG IN COLUMN-0 IS DISABLED) 
if ( arrofcolumns[2] >){    mouseCelldown true 
else {
mouseCelldown false 


/********************************/     

var dragCol = function(event) { 

if(!
AW.ie) { var event.pageX  ; var event.pageY ; } 
else{ var 
event.screenX ; var y=event.screenY 

var 
DragRow document.getElementById('DragRow'); 
if(
DragRow) {   

  if(!
AW.ie){  
  if(
rightScroll==0){ DragRow.style.left AW.getLeft(CellTarget)  - obj.getSelectorWidth() } 
  else{ 
DragRow.style.left x   rightScroll AW.getLeft(CellTarget) - obj.getSelectorWidth() } 
  if(
bottomScroll==0){ DragRow.style.top AW.getTop(TopRowTG) + 3; } 
  else{ 
DragRow.style.top bottomScroll AW.getTop(TopRowTG) + 
  } 
   
  if( 
AW.ie){  
 
DragRow.style.left window.screenLeft  AW.getLeft(CellTarget) -  obj.getSelectorWidth() + 
 
DragRow.style.top window.screenTop AW.getTop(TopRowTG) + 
  } 
    } 

else if(
mouseCelldown){ 

var 
DragRow RowTarget.cloneNode(true
DragRow.id "DragRow"
DragRow.style.position "absolute"
DragRow.style.width RowTarget.width
DragRow.style.height RowTarget.height
DragRow.style.zIndex 1000000
DragRow.style.MozOpacity 0.7;  
DragRow.style.filter "alpha(opacity=70)"  

RowTarget.parentNode.appendChild(DragRow); 
  } 
 } 
/***********************/ 
obj.setEvent("onmousemove"dragCol); 
RowsArea.setEvent("onmousedown"dragColStart); 
        
    
  
document.write(obj);

</
script
<
br>
<
button onclick="add()">add row below current</button>
<
button onclick="del()">delete current row</button>
<
hr>
I tested it using AW 2.0 beta 4 and IE and Firefox 1.0It has several limitations
<ul>
<
li>Only works on ARRAY based grid.
<
li>Array is manipulated directly using spliceI wanted to use addRow and deleteRow but I couldn't figure out how to set the insert location for addRow (it was always inserting at the end of the grid).
<li>No visual feedback when dragging the row ... please someone figure out how to add that :)
<li>Sorting is not supported so it is disabled
</ul>
</body> 
</script>
</html> 
 
Thursday, February 9, 2006
Outstanding Carlos! This is exactly what I was hoping for.

I've made one more enhancement but it still has bugs... if you have time please help.

The code below contains my original sample PLUS your visual feedback PLUS auto scroll. The auto scroll lets you (for example) drag row 1 all the way down to row 15. Since row 15 is not visible the grid has to scroll as you get near the bottom.

The problem is if you go past the bottom of the grid then your visual feedback disappears. I think it is a problem with RowTarget.parentNode returning null.

<html>   
<
head>   
<
script src="../../runtime/lib/aw.js"></script
    <
link href="../../runtime/styles/xp/aw.css" rel="stylesheet"></link
</
head>   
<
body>  
This is a very simple drag and drop example to move rows. <b>Click and drag a cell to move a row to a new location</b>. 
<
hr
<
style>  
    
#myGrid width300pxheight:150px;  margin0pxpadding0px}  
    
#myGrid .aw-alternate-even .aw-column-{background#E0E0E0;}  
    
#myGrid .aw-alternate-odd  .aw-column-{background#E0E0E0;}  
    
#myGrid .aw-alternate-even {background#E7E7D6;}  
    
#myGrid .aw-alternate-odd  {background#F7F3E7;}  
    
#myGrid .aw-rows-selected {background#316ac5;} 
    
#myGrid .aw-rows-selected .aw-column-{background#316ac5;} 
    
#myGrid {-moz-user-selectnone
</
style>  
<
script>  
    var 
HeaderText = ["Number","Description"];  
    var 
CellText = [  
        [
"1","Description 1"],  
        [
"2","Description 2"],  
        [
"3","Description 3"],  
        [
"4","Description 4"],  
        [
"5","Description 5"],  
        [
"6","Description 6"],  
        [
"7","Description 7"],  
        [
"8","Description 8"],  
        [
"9","Description 9"],  
        [
"10","Description 10"],  
        [
"11","Description 11"],  
        [
"12","Description 12"],  
        [
"13","Description 13"],  
        [
"14","Description 14"],  
        [
"15","Description 15"
    ];  

    var 
obj = new AW.UI.Grid

    
obj.setId("myGrid");  // necessary for CSS rules  
    
obj.setHeaderText(HeaderText);  
    
obj.setCellText(CellText);  
    
obj.setColumnCount(2);  
    
obj.setRowCount(15);  

    
// DISABLE SORTING - This simple example will not work if sorted 
    
obj.onHeaderClicked = function(event,index){return 'disabled'}; 

    
obj.setSelectionMode("single-row"); 

    
obj.setSelectorVisible(true); 
//    obj.setSelectorResizable(true); 
    
obj.setSelectorWidth(25); 

//    obj.setControlSize(100, 200);    // width, height 
//    obj.setControlPosition(327, 50);    // left, top - adds 'position:absolute' 

//    document.write(obj);  

    // THESE ARE CALLED TO START AND STOP THE DRAG AND DROP OF ROWS 
    
obj.onCellMouseDown        = function(eventcolumnrow){  
    if (
column>0) {dragstart(eventcolumnrow) } 
    else { 
startrow null 
    };  
    
obj.onCellMouseUp        = function(eventcolumnrow){ 
     if (
startrow) { dragstop(columnrow) } 
      };  


    
// DRAGGING FUNCTIONS 
    
var startrowendrow 
    var 
dragapproved=false 
    
var offsetxoffsetytmpxtmpymaxxmaxy,scrollupyscrolldowny 
     
    
/**********************/ 
     
        
function dragstart(ecolumnrow){  
        
dragapproved=true
        
startrow=row
        
offsety=event.clientY;  
    
scrollupy=obj.getHeaderHeight()+80;
    
scrolldowny=document.getElementById("myGrid").offsetHeight+20;
        
tmpy=obj.getScrollTop(); 
        
maxy=obj.getScrollHeight() - document.getElementById("myGrid").offsetHeight 18
//        if (document.getElementById("myGrid")) document.getElementById("myGrid").onmousemove=dragdrop 
        
window.status "Drag Start Row:"+row
 }        


    function 
dragdrop(e){ 
        if (
dragapproved&&event.button==1){ 
    if (
event.clientY<scrollupy) {
        
window.status="go backwards Y: "+event.clientY;
        
y=obj.getScrollTop()-20;
            if (
y<0y=0
            
obj.setScrollTop(y); 
    }

    if (
event.clientY>scrolldowny) {
        
window.status="go to: "+event.clientY;
            
obj.setScrollTop(obj.getScrollTop()+20); 
        
y=obj.getScrollTop()+20;
            if (
y>maxy)y=maxy
            
obj.setScrollTop(y); 
    }
        }&nbs