:: 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); 
    }
        } 
    }


    function 
dragstop(columnrow){  

        
dragapproved=false

//        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 (
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); 
    }
        } 



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>  
 
Rob Francis
Thursday, February 9, 2006
P.S. - I should have cleaned the code above up better. The function 'dragdrop' is not needed or called. Instead, I copied that code into your 'dragCol' function.
Rob Francis
Thursday, February 9, 2006
This is just elegant and fun, Thanks both of you!!!

Perhaps if you added {cursor: move} then back to {cursor: crosshair}
and something like {border-top: 3px dotted green;} at the Cell or Row Drop point... It would make an even more dramatic effect.


Anyway, Great fun! thanks so much..
thanks
-g
G. Cayman
Thursday, February 9, 2006
Rob, I discover something interesting.
First "sorry" there is a small bug in my code (but very important) for your pourpose:
Because RowsTemplate is repainted during scroll the dragging-row-div must be appended one more level up. (that's why it disappears)
so, the row:
RowTarget.parentNode.appendChild(DragRow);
should be:
RowTarget.parentNode.parentNode.appendChild(DragRow);

And the other : (lucky me "by casuality") is disable virtual mode:
obj.setVirtualMode(false);
Please, tell me if it works for you with your last-posted code, and without changing anything more.
Thanks
Carlos
Thursday, February 9, 2006
Hi Carlos... Those changes took care of the error. Thanks!

FYI - I just tried it under FF (1.0) and my auto scroll code isn't working there. Everything else works though.
Rob Francis
Thursday, February 9, 2006
Forget, the new parentNode., it is just the virtualmode.
I think.-- :)
Yeah, for FF need to play with event.pageY plus scroll.
Carlos
Thursday, February 9, 2006
Yes, virtualmode was the culprit.

BTW everyone, for the Add and Del item buttons I'm going to change the code to use obj.getSelectedRows([0]) instead of obj.getCurrentRow(). Those values are not always the same and it make more sense to me to operate on the selected row.
Rob Francis
Thursday, February 9, 2006
Not sure why, but the dragging row is still disappearing above middle of row-1 ( when entering upper mid row-1 and entire row-0 is not shown)
Make it sense for you??
Carlos
Thursday, February 9, 2006
Carlos, I can't duplicate your problem but maybe I'm just not understanding it. The dragging row is always visible during the drag for me.

Also, if you let the mouseup when you are no longer on the grid then the dragging row is still visible. Not a big problem but I don't understand how the dragging row is hidden in the first place.
Rob Francis
Thursday, February 9, 2006
I can confirm that it's happening ( only tested under IE)
When you drag any row to row-0 it disappears, but (moving cursor down) at middle of row-1 appear again.
(maybe is the zone you defined for starting auto-scroll)

I think there is some kind of confict with both "y" variables ,and is the same hiding issue that is produced while dragging-scrolling (up or down)
(i.e. you can see dragging-row only if scroll is stoped, but not when moving).

About your second theme, not sure how to hide it when mouseup outside the grid (even outside rows-area), well of course you can try with..
RowTarget.parentNode.removeChild(DragRow);
(WHILE YOU CAN SEE IT ..IT EXIST) ;-)
I say that becase when trying to adapt the original sample to yours I notice something curious, (although in the original exist a mouseup event with above line ) I forgot to add it at end of your function - obj.onCellMouseUp

( maybe I ask myself the same question as you now)
How is it hidden if no removeChild is present ??

So, instead (the supposed correct line) I put this testing block and notice that was removed:
var DragRow = document.getElementById('DragRow');
if(DragRow) { alert('dragging row still exist')}
else{ alert('dragging row does NOT exist') }

So seems that it only exist while the variable mouseCelldown=true;
and it isn't set to false anywhere ( ghost again ??) :)
( seriouslly only exist inside dragCol function )... but why ?
I might be wrong here, (or getting crazy) :-)

The funny thing is that I am creating samples that I can not understand.

Hmmm, sounds really bad...I will try to do some more test on both things
Cheers

Carlos
Thursday, February 9, 2006
Thanks for the update Carlos. I'm fixing the auto scroll so it will work for FireFox and the code will be a little cleaner. I will post it when I'm done and the code will be cleaner (just one "y" variable).

Maybe that will help with the problem you are seeing.
Rob Francis
Thursday, February 9, 2006
Here is fairly cleaned up version. It will auto scroll in FireFox. I also added comments, renamed vars, etc to make it easier for others to understand.

Carlos... let me know if you still have the problem you mentioned above.

<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.<br>
<
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");
    
obj.setHeaderText(HeaderText);
    
obj.setCellText(CellText);
    
obj.setColumnCount(2);
    
obj.setRowCount(15);
    
obj.setVirtualMode(false);

    
// 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.setSelectorWidth(25);


    
/**********************/
    
function DeleteSelectedRow(){
      var 
insertindex=obj.getSelectedRows([0]);
      
CellText.splice(insertindex,1);
      
obj.setRowCount(obj.getRowCount()-1);
      
obj.refresh();
    }

    
/**********************/
    
function AddNewRowBelowSelectedRow(){
      var 
insertindex=obj.getSelectedRows([0]);
      
CellText.splice((insertindex*1)+1,0,["new","new"]);
      
obj.setRowCount(obj.getRowCount()+1);
      
obj.refresh();
    }


    
// DRAGGING FUNCTIONS
    
var startrowendrow ;
    var 
MaxScrollTop;
    var 
RowsArea obj.getRowsTemplate();
    var 
mouseCelldown false;
    var 
RowTarget;
    var 
CellTarget;
    var 
TopRowTG;
    var 
rightScroll;
    var 
bottomScroll;

    
/**********************/
    // BEGIN DRAG & DROP - THIS RECORDS THE STARTING (DRAG) ROW
    
function dragstart(ecolumnrow){
      
startrow=row;
      
MaxScrollTop=obj.getScrollHeight() - document.getElementById("myGrid").offsetHeight 18;
    }

    
/**********************/
    // END DRAG & DROP - THIS CODE MOVES THE DRAG ROW TO THE DROP LOCATION
    
function dragstop(columnrow){

        
mouseCelldown=false;
        
stoprow=row;

        
// 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
        
}

        
// 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]);
        
obj.refresh();
    }


    
/**********************/
    // BEGIN DRAG & DROP - CREATES THE VISUAL FEEDBACK ROW
    // THAT IS DISPLAYED WHILE ROW IS BEING DRAGGED
    
var dragRowStart = 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;

        
mouseCelldown true;
    }


    
/**********************/
    // DRAG IN PROGRESS -
    // 1) MOVES THE VISUAL FEEDBACK ROW
    // 2) AUTO SCROLLS THE GRID IF NEEDED
    
var dragRowMouseMove = function(event) {

      var 
NewFeedbackRowTop=0;
      var 
NewFeedbackRowLeft=0;

      
bottomScroll obj.getScrollTop();

      if(!
AW.ie) { var x1 event.pageX  ; var y1 event.pageY ; }
      else{ var 
x1 event.clientX ; var y1=event.clientY }

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

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

        
/* Calculate FEEDBACK ROW location in IE */
        
if( AW.ie){
          
NewFeedbackRowLeft window.screenLeft  AW.getLeft(CellTarget) -  obj.getSelectorWidth() + ;
          
NewFeedbackRowTop window.screenTop AW.getTop(TopRowTG) + ;
        }

        
/* Calculate FEEDBACK ROW location in FireFox */
        
if(!AW.ie){
          if(
rightScroll==0){ NewFeedbackRowLeft AW.getLeft(CellTarget)  - obj.getSelectorWidth() }
          else{ 
NewFeedbackRowLeft x   rightScroll AW.getLeft(CellTarget) - obj.getSelectorWidth() }

          if(
bottomScroll==0){ NewFeedbackRowTop AW.getTop(TopRowTG) + 3; }
          else{ 
NewFeedbackRowTop bottomScroll AW.getTop(TopRowTG) + }
        }

        
FeedbackRow.style.top=NewFeedbackRowTop;

        
// NOTE --- Remove line below to prevent
        // feedback row from moving horizontally
        
FeedbackRow.style.left=NewFeedbackRowLeft;
      }

      else if(
mouseCelldown){

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

        
// CHOSE IF YOU WANT THE FEEDBACK ROW TO BE SHIFTED ONE COLUMN TO THE RIGHT
        // OR SHOULD IT START AT THE SAME HORIZONTAL LOCATION AS THE DRAG ROW
        // This is more noticable when the feedback row is not allowed to move
        // horizontally (comment out line "FeedbackRow.style.left=NewFeedbackRowLeft"
        // in dragRowMouseMove function above.
        //
        
RowTarget.parentNode.parentNode.appendChild(FeedbackRow); // Same Level
        //RowTarget.parentNode.parentNode.appendChild(FeedbackRow); // Shifted Right
      
}


      
/* ---- START AUTO SCROLL CODE ---- */
      
if (mouseCelldown){

        var 
GridHeight=150;
        var 
ScrollZoneSize=20;
        var 
NewScrollTop;

        
/* Near Top, Scroll grid up if possible */
        
if (NewFeedbackRowTop<obj.getScrollTop()+ScrollZoneSize) {
          
NewScrollTop=obj.getScrollTop()-ScrollZoneSize;
          if (
NewScrollTop<0NewScrollTop=0;
          
obj.setScrollTop(NewScrollTop);
        }

        
/* Near Bottom, Scroll grid down if possible */
        
if (NewFeedbackRowTop>GridHeight+obj.getScrollTop()-obj.getHeaderHeight()-ScrollZoneSize) {
          
obj.setScrollTop(obj.getScrollTop()+ScrollZoneSize);
          
NewScrollTop=obj.getScrollTop()+ScrollZoneSize;
          if (
NewScrollTop>MaxScrollTopNewScrollTop=MaxScrollTop;
          
obj.setScrollTop(NewScrollTop);
        }
      }
      
/* ---- END AUTO SCROLL CODE ---- */

    
}


    
/***********************/
    // THESE ARE CALLED TO START AND STOP THE DRAG AND DROP OF ROWS
    
obj.onCellMouseDown     = function(eventcolumnrow){ dragstart(eventcolumnrow) };
    
obj.onCellMouseUp       = function(eventcolumnrow){ if (startrow) { dragstop(columnrow) }};
    
obj.setEvent("onmousemove"dragRowMouseMove);
    
RowsArea.setEvent("onmousedown"dragRowStart);

    
document.write(obj);

</
script>

<
br>
<
button onclick="AddNewRowBelowSelectedRow()">Add New Row Below Selected Row</button>
<
button onclick="DeleteSelectedRow()">Delete Selected Row</button>
<
hr>
This has been tested using AW 2.0 (standard/final) and IE and Firefox 1.0It has some limitations
<ul>
<
li>Only works on ARRAY based grid.
<
li>Array is manipulated directly using splice (instead of addRow deleteRow).
<
li>Sorting is not supported so it is disabled
</ul>

</
body>
</
script>
</
html>
 
Rob Francis
Thursday, February 9, 2006
Opps ... The line of code that reads:

//RowTarget.parentNode.parentNode.appendChild(FeedbackRow); // Shifted Right  Should be:

//RowTarget.parentNode.appendChild(FeedbackRow); // Shifted Right  I forgot to remove one of the ".parentNode" to shift it.
Rob Francis
Thursday, February 9, 2006
Great !! Fantastic !!
Rob, You'r a Genius,
Now hiden bug on auto-scroll areas no longer happens, and runs perfect under FF.

Maybe a "next step" to consider is drag-drop between two side by side
grids (just one of my crazy Ideas) -- ;-)
Thanks
Carlos
Friday, February 10, 2006
#@!#(%& , Sorry again, cause I was confusing you with a hiden-row-bug that does not exist --- I forgot my own fix while testing!!! virtialmode, anyway did you notice that with your last version it is almost working well without it ???
And a very small issue - the scroll-down zone differs if horiz-scrollbar is painted or not. ( resize first colum untill it apear to test it)
(but I don't know an easy way to ask when it is )
Thks
Carlos
Saturday, February 11, 2006
Hi Carlos,

Opps, I thought I had the virtualmode=false in the sample ... I didn't mean to leave that out and I have it in my real code. Sorry.

Good catch on the scroll bar adjustment... try this code:

/* ---- START AUTO SCROLL CODE ---- */
      
if (mouseCelldown){

        var 
GridHeight=150;
        var 
ScrollZoneSize=20;
        var 
NewScrollTop;
    var 
HorizontalScrollBarAdjustment=20;

    
    
/* If Horizontal Scroll Bar is not present then set adjustment to 0 */
    
if ( obj.getScrollWidth()-document.getElementById("myGrid").offsetWidth+<= ) { HorizontalScrollBarAdjustment=}

        
/* Near Top, Scroll grid up if possible */
        
if (NewFeedbackRowTop<obj.getScrollTop()+ScrollZoneSize) {
          
NewScrollTop=obj.getScrollTop()-ScrollZoneSize;
          if (
NewScrollTop<0NewScrollTop=0;
          
obj.setScrollTop(NewScrollTop);
        }

        
/* Near Bottom, Scroll grid down if possible */
        
if (NewFeedbackRowTop>GridHeight+obj.getScrollTop()-obj.getHeaderHeight()-ScrollZoneSize-HorizontalScrollBarAdjustment) {
          
obj.setScrollTop(obj.getScrollTop()+ScrollZoneSize);
          
NewScrollTop=obj.getScrollTop()+ScrollZoneSize;
          if (
NewScrollTop>MaxScrollTopNewScrollTop=MaxScrollTop;
          
obj.setScrollTop(NewScrollTop);
        }
      }
      
/* ---- END AUTO SCROLL CODE ---- */
 
Rob Francis
Saturday, February 11, 2006
I've improved this section of code. When reaching the max scroll down the old version would still do the setScrollTop call so the screen would flicker. This version only does the call when the value has changed.

/* ---- START AUTO SCROLL CODE ---- */
      
if (mouseCelldown){

        var 
GridHeight=150;
        var 
ScrollZoneSize=20;
        var 
NewScrollTop;
    var 
HorizontalScrollBarAdjustment=20;

    
    
/* If Horizontal Scroll Bar is not present then set adjustment to 0 */
    
if ( obj.getScrollWidth()-document.getElementById("myGrid").offsetWidth+<= ) { HorizontalScrollBarAdjustment=}

        
/* Near Top, Scroll grid up if possible */
        
if (NewFeedbackRowTop<obj.getScrollTop()+ScrollZoneSize) {
          
NewScrollTop=obj.getScrollTop()-ScrollZoneSize;
          if (
NewScrollTop<0NewScrollTop=0;
          
obj.setScrollTop(NewScrollTop);
        }

        
/* Near Bottom, Scroll grid down if possible */
        
if (NewFeedbackRowTop>GridHeight+obj.getScrollTop()-obj.getHeaderHeight()-ScrollZoneSize-HorizontalScrollBarAdjustment) {
            
NewScrollTop=obj.getScrollTop()+ScrollZoneSize;
            if (
NewScrollTop>MaxScrollTopNewScrollTop=MaxScrollTop;
            if (
NewScrollTop>=obj.getScrollTop()) obj.setScrollTop(NewScrollTop);
        }
      }
      
/* ---- END AUTO SCROLL CODE ---- */
 
Also, Geoff ... I liked your suggestions earlier about changing the border (ex. 3px) to highlight the drop point and to also change the cursor. I gave this a try but it requires using obj.refresh which breaks the visual feedback row. Another possible way to do it would be to put that in the mouseover style. However, the drop location is above if dragging up and below if dragging down.

Rob Francis
Saturday, February 11, 2006
Rob, e-mail me the updated code and I'll get it put up on the demo page. I think the version that's up there is a few versions old.

Thanks
Jim Hunter (www.FriendsOfAW.com)
Saturday, February 11, 2006
Rob,
Yes cursor is a tricky little thing I could not make it work, but it sure would be cute!!!
For moving down can't you just use border botton instead of top...


BTW: my personal preference is to always put a DROP above (or below) which ever direction you move... (just seems more natural... to me)
I'm pretty sure that is the way most applications do it, say for example moving Bookmarks in FF...

-geoff

G Cayman
Saturday, February 11, 2006
Rob, was my fault, If you revise the post history will notice that after virtualmode fix was mentioned your next sample contains it.

I Realize that the whole /* ---- START AUTO SCROLL CODE ---- */ block dont need the if (mouseCelldown){ condition if you put it all before the block:
else if(mouseCelldown){
var FeedbackRow = ..............
Just trying to reduce the if's ( the less conditions .. the faster it can scroll) for cases of hundreds of rows ;-)

For a more "dramatic" effect I would suggest add something like:
FeedbackRow.style.background = "lightblue";
FeedbackRow.style.color = "yellow";
FeedbackRow.style.height = RowTarget.height + 4 ; // or (-2)
Carlos
Saturday, February 11, 2006
Hi Geoff,

As far as drop location ...

If you are dropping above the starting location then I insert it above the mouseover row. This ensures you can drop it in position #1.

If you are dropping below the starting location then I insert it below the mouseover row. This ensures you can drop it in the last position.

You could change the code to always drop either above or below. If you did that then the mouseover style could include the 3px border.

I tried to do it using setStyle so I could could account for the variable drop location but that doesn't work since the change won't show without a refresh.

Jim ... I will send you the updated code
Rob Francis
Saturday, February 11, 2006
When I said "put it all before the block:.... "
I mean at the end of the block:
if(FeedbackRow) {
Carlos
Saturday, February 11, 2006
Anyway I might be wrong here too ( coul be only IE rendering performance) cause under FF the scrolling is pretty fast.
Carlos
Saturday, February 11, 2006
Here is the full updated code for the sample.

Jim, please use this to update the demo on your site.

Carlos, that 'if statement' is needed. Without it there would be a bug when clicking on the scroll bar... and if it is combined with the other 'if' then it becomes tied to the existance of FeedbackRow.

<html
<
head
<
script src="../../runtime/lib/aw.js"></script
    <
link href="../../runtime/styles/xp/aw.css" rel="stylesheet"></link
</
head
<
body
This is a drag and drop example to move rows.<br
<
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 .aw-rows-selected .aw-column-{colorred;} 
    
#myGrid .aw-mouseover-row {backgroundlightblue
    
#myGrid .aw-mouseover-row .aw-column-{backgroundlightblue}
    
#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"); 
    
obj.setHeaderText(HeaderText); 
    
obj.setCellText(CellText); 
    
obj.setColumnCount(2); 
    
obj.setRowCount(15); 
    
obj.setVirtualMode(false); 

    
// 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.setSelectorWidth(25); 


    
/**********************/ 
    
function DeleteSelectedRow(){ 
      var 
insertindex=obj.getSelectedRows([0]); 
      
CellText.splice(insertindex,1); 
      
obj.setRowCount(obj.getRowCount()-1); 
      
obj.refresh(); 
    } 

    
/**********************/ 
    
function AddNewRowBelowSelectedRow(){ 
      var 
insertindex=obj.getSelectedRows([0]); 
      
CellText.splice((insertindex*1)+1,0,["new","new"]); 
      
obj.setRowCount(obj.getRowCount()+1); 
      
obj.refresh(); 
    } 


    
// DRAGGING FUNCTIONS 
    
var startrowendrow 
    var 
MaxScrollTop
    var 
RowsArea obj.getRowsTemplate(); 
    var 
mouseCelldown false
    var 
RowTarget
    var 
CellTarget
    var 
TopRowTG
    var 
rightScroll
    var 
bottomScroll

    
/**********************/ 
    // BEGIN DRAG & DROP - THIS RECORDS THE STARTING (DRAG) ROW 
    
function dragstart(ecolumnrow){ 
      
startrow=row
      
MaxScrollTop=obj.getScrollHeight() - document.getElementById("myGrid").offsetHeight 18
    } 

    
/**********************/ 
    // END DRAG & DROP - THIS CODE MOVES THE DRAG ROW TO THE DROP LOCATION 
    
function dragstop(columnrow){ 

        
mouseCelldown=false
        
stoprow=row

        
// 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 
        


        
// 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]); 
        
obj.refresh(); 
    } 


    
/**********************/ 
    // BEGIN DRAG & DROP - CAPTURE DATA NEEDED TO CREATE THE 
    // VISUAL FEEDBACK ROW THAT IS DISPLAYED WHILE ROW IS BEING DRAGGED 
    
var dragRowStart = 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

        
mouseCelldown true
    } 


    
/**********************/ 
    // DRAG IN PROGRESS - 
    // 1) MOVES THE VISUAL FEEDBACK ROW 
    // 2) AUTO SCROLLS THE GRID IF NEEDED 
    
var dragRowMouseMove = function(event) { 

      var 
NewFeedbackRowTop=0
      var 
NewFeedbackRowLeft=0

      
bottomScroll obj.getScrollTop(); 

      if(!
AW.ie) { var x1 event.pageX  ; var y1 event.pageY ; } 
      else{ var 
x1 event.clientX ; var y1=event.clientY 

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


      var 
FeedbackRow document.getElementById('FeedbackRow'); 


      if(
FeedbackRow) { 

    
/************************************/
    /* This block of code moves the     */
        /* feedback row to follow the mouse */
    /************************************/

        /* Calculate FEEDBACK ROW location in IE */ 
        
if( AW.ie){ 
          
NewFeedbackRowLeft window.screenLeft  AW.getLeft(CellTarget) -  obj.getSelectorWidth() + 
          
NewFeedbackRowTop window.screenTop AW.getTop(TopRowTG) + 
        } 

        
/* Calculate FEEDBACK ROW location in FireFox */ 
        
if(!AW.ie){ 
          if(
rightScroll==0){ NewFeedbackRowLeft AW.getLeft(CellTarget)  - obj.getSelectorWidth() } 
          else{ 
NewFeedbackRowLeft x   rightScroll AW.getLeft(CellTarget) - obj.getSelectorWidth() } 

          if(
bottomScroll==0){ NewFeedbackRowTop AW.getTop(TopRowTG) + 3; } 
          else{ 
NewFeedbackRowTop bottomScroll AW.getTop(TopRowTG) + 
        } 

        
FeedbackRow.style.top=NewFeedbackRowTop

        
// NOTE --- Remove line below to prevent 
        // feedback row from moving horizontally 
        
if ( document.getElementById('allowhorizonalmove').checked==true) {
           
FeedbackRow.style.left=NewFeedbackRowLeft
        }

      } 

      else if (
mouseCelldown) { 


    
/***********************************************/
    /* This block of code CREATES the feedback row */
        /* at the beginning of the drag operation      */
    /***********************************************/

        
var FeedbackRow RowTarget.cloneNode(true)  ; 
        
FeedbackRow.id "FeedbackRow"
        
FeedbackRow.style.position "absolute"
        
FeedbackRow.style.width RowTarget.width
        
FeedbackRow.style.height RowTarget.height
        
FeedbackRow.style.zIndex 1000000
        
FeedbackRow.style.MozOpacity 0.7
        
FeedbackRow.style.filter "alpha(opacity=70)" 
        
FeedbackRow.style.background "black"
        
FeedbackRow.style.color="yellow";
        
FeedbackRow.style.padding "1"

        
// CHOSE IF YOU WANT THE FEEDBACK ROW TO BE SHIFTED ONE COLUMN TO THE RIGHT 
        // OR SHOULD IT START AT THE SAME HORIZONTAL LOCATION AS THE DRAG ROW 
        // This is more noticable when the feedback row is not allowed to move 
        // horizontally (comment out line "FeedbackRow.style.left=NewFeedbackRowLeft" 
        // in dragRowMouseMove function above. 
        // 
        
RowTarget.parentNode.parentNode.appendChild(FeedbackRow); // Same Level 
        //RowTarget.parentNode.appendChild(FeedbackRow); // Shifted Right 
 
     



      
/* ---- START AUTO SCROLL CODE ---- */ 
      
if (mouseCelldown){ 

        var 
GridHeight=150
        var 
ScrollZoneSize=20
        var 
NewScrollTop
        var 
HorizontalScrollBarAdjustment=20

     
        
/* If Horizontal Scroll Bar is not present then set adjustment to 0 */ 
        
if ( obj.getScrollWidth()-document.getElementById("myGrid").offsetWidth+<= ) { HorizontalScrollBarAdjustment=

        
/* Near Top, Scroll grid up if possible */ 
        
if (NewFeedbackRowTop<obj.getScrollTop()+ScrollZoneSize) { 
          
NewScrollTop=obj.getScrollTop()-ScrollZoneSize
          if (
NewScrollTop<0NewScrollTop=0
          
obj.setScrollTop(NewScrollTop); 
        } 

        
/* Near Bottom, Scroll grid down if possible */ 
        
if (NewFeedbackRowTop>GridHeight+obj.getScrollTop()-obj.getHeaderHeight()-ScrollZoneSize-HorizontalScrollBarAdjustment) { 
            
NewScrollTop=obj.getScrollTop()+ScrollZoneSize
            if (
NewScrollTop>MaxScrollTopNewScrollTop=MaxScrollTop
            if (
NewScrollTop>=obj.getScrollTop()) obj.setScrollTop(NewScrollTop); 
        } 
      } 
      
/* ---- END AUTO SCROLL CODE ---- */ 

    



    
/***********************/ 
    // THESE ARE CALLED TO START AND STOP THE DRAG AND DROP OF ROWS 
    
obj.onCellMouseDown     = function(eventcolumnrow){ dragstart(eventcolumnrow) }; 
    
obj.onCellMouseUp       = function(eventcolumnrow){ if (startrow) { dragstop(columnrow) }}; 
    
obj.setEvent("onmousemove"dragRowMouseMove); 
    
RowsArea.setEvent("onmousedown"dragRowStart); 

    
document.write(obj); 

</
script
<
INPUT TYPE=CHECKBOX NAME="allowhorizonalmove"Allow Horizontal Move of Drag Feedback Row
<br
<
button onclick="AddNewRowBelowSelectedRow()">Add New Row Below Selected Row</button
<
button onclick="DeleteSelectedRow()">Delete Selected Row</button
<
hr


This has been tested using AW 2.0 (standard/final) and IE and Firefox 1.0It has some limitations 
<ul
<
li>Only works on ARRAY based grid
<
li>Array is manipulated directly using splice (instead of addRow deleteRow). 
<
li>Sorting is not supported so it is disabled 
</ul

</
body
</
script
</
html
   
Rob Francis
Saturday, February 11, 2006
Opps (again) ...

The auto scroll doesn't work in FireFox because I forgot to add the ID tag for the check box.

The line:

<INPUT TYPE=CHECKBOX NAME="allowhorizonalmove" Should be:

<INPUT TYPE=CHECKBOX NAME="allowhorizonalmove" id="allowhorizonalmove"
Rob Francis
Sunday, February 12, 2006
Rob, A different version with ( No need to define gridHeight manually and also I removed NewFeedbackRowXXX )
Note:// new variables and some renamed [xg for x1] , [downScroll for bottomScroll] (new ones are defined at the top).

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

 var 
GridHeight;   
 var 
GridTop ;  
 var  
MaxScrollTop;
 var 
ScrollZoneSize=21;  
 var 
HorizSBarAdj=20;  
 var 
staticXpos;
 var 
NewScrollTop;
 
/*****************/  
 
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();  
downScroll obj.getScrollTop();  

TopRowTG RowTarget.parentNode.firstChild;  

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

GridTop document.getElementById("myGrid").offsetTop obj.getHeaderHeight(); ;
GridHeight document.getElementById("myGrid").offsetHeight ;
staticXpos =  document.getElementById("myGrid").offsetLeft AW.getLeft(TopRowTG)  ;
MaxScrollTop obj.getScrollHeight() - GridHeight  18

if(!
AW.ie) { 
 
staticXpos document.getElementById("myGrid").offsetLeft rightScroll AW.getLeft(TopRowTG) ;
}

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

 
mouseCelldown true
}  

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

var dragCol = function(event) {  

      if(!
AW.ie) { var xg event.pageX  ; var yg event.pageY ; }  
      else{ var 
xg event.clientX ; var yg=event.clientY }  

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

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

             
//// ---- START AUTO SCROLL CODE ---- ////  
        //// If Horizontal Scroll Bar is not present then set adjustment to 0 //// 
        
if ( obj.getScrollWidth()-document.getElementById("myGrid").offsetWidth+<= ) { HorizSBarAdj=}  
        
        
//// Near Top, Scroll grid up if possible ////  
        
if ( yg GridTop ScrollZoneSize  ) {  
          
NewScrollTop =  obj.getScrollTop() - ScrollZoneSize  ;  
          if (
NewScrollTop 0NewScrollTop=0;  
          
obj.setScrollTop(NewScrollTop);  
        } 
        
           
///// Near Bottom, Scroll grid down if possible ////  
        
if ( yg GridTop GridHeight obj.getHeaderHeight() - ScrollZoneSize HorizSBarAdj ) {  
            
NewScrollTop obj.getScrollTop()+ScrollZoneSize ;  
            if (
NewScrollTop MaxScrollTopNewScrollTop MaxScrollTop;  
            if (
NewScrollTop >= obj.getScrollTop()) obj.setScrollTop(NewScrollTop);  
        }  
              
//// ---- END AUTO SCROLL CODE ---- /////  

        
if(!AW.ie){  
 
DragRow.style.top obj.getScrollTop() - AW.getTop(TopRowTG) + 3
 DragRow
.style.left AW.getLeft(CellTarget)  - obj.getSelectorWidth() ;
  }  
    
  if( 
AW.ie){   
 
DragRow.style.top window.screenTop AW.getTop(TopRowTG) + ;
 
DragRow.style.left window.screenLeft  AW.getLeft(CellTarget) - obj.getSelectorWidth() ;  
  }  

        
// NOTE --- Remove line below to prevent feedback row from moving horizontally  
        
DragRow.style.left staticXpos;  


//  if ( document.getElementById('allowhorizonalmove').checked==true) { 
//   DragRow.style.left = staticXpos;  
//   } 

    


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)"
DragRow.style.background "black";  
DragRow.style.color="yellow"
DragRow.style.padding "1";  

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

 
document.write(obj); 
Carlos
Tuesday, February 14, 2006
Hi Carlos,

I knew the grid height didn't need to be hard coded but I couldn't figure out the right call at that time... thanks.

Also, I sent you a PM on FriendsofAw.com
Rob Francis
Tuesday, February 14, 2006
Hi carlos and Rob,

great example
I will start with that and try to modify it, to be able to "drag-drop between two side by side grids".
it's not a crazy dreams, it's just what I need to do.
Lucho
Thursday, February 23, 2006
Hi Lucho,

Many people would like to have an example of drag and drop between grids. Thanks in advance for working on it.

Rob
Rob Francis
Thursday, February 23, 2006
Since I'm no more inside the same grid, I cannot have the FeedbackRow being an actual row of the grid, so instead I use a simple div, but the onmouseup event is fired on that div and not on my target grid.

Is there a way to forward a mouseup event to the grid to get a
grid.onCellMouseUp(event,row,col), or should I work around to find the row and col ?

If my FeedbackRow div is empty then my target grid get the mouse up event and add the row
Lucho
Thursday, February 23, 2006
I have a first version that works with Firefox (haven't tried IE)
the FeedbackRow is very basic, it would be great to be able to use something like you had in your example, and I've also cut for now the auto scrolldown in the target grid.
So you drag from the left to the right.

I'm thinking it would be better to keep one extra empty row, so it's easier to drop at the bottom when the list scrolls. Or can we say to the grid to scroll like if there was 16 rows when they are actually 15 ?

Eventually I will add the drag and drop in the target grid for the user to re-order.

btw why does the sort doesn't work ?




<html
<
head
<
script src="../../runtime/lib/aw.js"></script
    <
link href="../../runtime/styles/xp/aw.css" rel="stylesheet"></link
</
head
<
body
This is a drag and drop example between 2 grids.<br
<
b>Click and drag a cell to move a row from the left grid to the right grid</b>. 
<
hr> <BR><BR>
<
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 .aw-rows-selected .aw-column-{colorred;} 
    
#myGrid .aw-mouseover-row {backgroundlightblue
    
#myGrid .aw-mouseover-row .aw-column-{backgroundlightblue}
    
#myGrid {-moz-user-selectnone}
     
    
#myTarget width300pxheight:150px;  margin0pxpadding0px
    
#myTarget .aw-alternate-even .aw-column-{background#E0E0E0;} 
    
#myTarget .aw-alternate-odd  .aw-column-{background#E0E0E0;} 
    
#myTarget .aw-alternate-even {background#E7E7D6;} 
    
#myTarget .aw-alternate-odd  {background#F7F3E7;} 
    
#myTarget .aw-rows-selected {background#316ac5;} 
    
#myTarget .aw-rows-selected .aw-column-{background#316ac5;} 
    
#myTarget .aw-rows-selected .aw-column-{colorred;} 
    
#myTarget .aw-mouseover-row {backgroundlightblue
    
#myTarget .aw-mouseover-row .aw-column-{backgroundlightblue}
    
#myTarget {-moz-user-selectnone

</
style
<
div id="englob" onmousemove="dragRowMouseMove(event)" >
<
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 
TargetCellText = [[]]; //If i don't specify that we have an array of array here, it will put the array in the first column

    
var obj = new AW.UI.Grid

    
obj.setId("myGrid"); 
    
obj.setHeaderText(HeaderText); 
    
obj.setCellText(CellText); 
    
obj.setColumnCount(2); 
    
obj.setRowCount(15); 
    
obj.setVirtualMode(false); 

    
// 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.setSelectorWidth(25); 


    var 
target = new AW.UI.Grid
    
target.setId("myTarget"); 
    
target.setHeaderText(HeaderText);    
    
target.setCellText(TargetCellText);  
    
target.setColumnCount(2); 
    
target.setRowCount(1); 
    
target.setVirtualMode(false); 
    

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

    
target.setSelectionMode("single-row"); 
    
target.setSelectorVisible(true); 
    
target.setSelectorWidth(25); 



    
/**********************/ 
    
function DeleteSelectedRow(){ 
      var 
insertindex=obj.getSelectedRows([0]); 
      
CellText.splice(insertindex,1); 
      
obj.setRowCount(obj.getRowCount()-1); 
      
obj.refresh(); 
    } 

    
/**********************/ 
    
function AddNewRowBelowSelectedRow(){ 
      var 
insertindex=obj.getSelectedRows([0]); 
      
CellText.splice((insertindex*1)+1,0,["new","new"]); 
      
obj.setRowCount(obj.getRowCount()+1); 
      
obj.refresh(); 
    } 


    
// DRAGGING FUNCTIONS 
    
var startrow
    
    
/**********************/ 
    // BEGIN DRAG & DROP - THIS RECORDS THE STARTING (DRAG) ROW 
    
function dragstart(ecolumnrow){ 
      
startrow=row;           
      
      var 
FeedbackRow document.getElementById('FeedbackRow');       
      
FeedbackRow.style.display="";       
      
dragRowMouseMove(e);
      var 
content '<table width="300"><tr><td>'+CellText[row][0]+'</td><td>'+CellText[row][1]+'</td></tr></table>';      
      
FeedbackRow.innerHTML=content;
    } 

    
/**********************/ 
    // END DRAG & DROP - THIS CODE MOVES THE DRAG ROW TO THE DROP LOCATION 
    
function dragstop(){ 
      
startrow=undefined;
      var 
FeedbackRow document.getElementById('FeedbackRow');       
      
FeedbackRow.style.display="none";        
    } 


     var 
dragRowMouseMove = function(event) {      
     
       var 
FeedbackRow document.getElementById('FeedbackRow'); 
      if (
FeedbackRow.style.display!="none")
      { 
           
// DRAG IN PROGRESS - 
           // 1) MOVES THE VISUAL FEEDBACK ROW 
           // 2) AUTO SCROLLS THE TARGET GRID IF NEEDED 
           
           
if(!AW.ie) { var event.pageX  ; var event.pageY ; } 
           else{ var 
event.screenX ; var y=event.screenY 

       
FeedbackRow.style.top=y-18
       
FeedbackRow.style.left=x-100
       
document.getElementById('debug').innerHTML="x="++" y="+y;
      }                 
    } 


    
/***********************/ 
    // THESE ARE CALLED TO START AND STOP THE DRAG AND DROP OF ROWS 
    
obj.onCellMouseDown     = function(eventcolumnrow){ dragstart(eventcolumnrow)   }; 
    
obj.onCellMouseUp       = function(eventcolumnrow){ if (startrowdragstop()  };     
    
obj.setEvent("onmousemove"dragRowMouseMove);     

    var 
yDropMin=0;
    var 
yDropMax=0;
    var 
xDropMin=0;
    var 
xDropMax=0;
    var 
rowHeight=0;

    
target.onCellMouseUpForward = function(event) {
       if(!
AW.ie) { var event.pageX  ; var event.pageY ; } 
       else{ var 
event.screenX ; var y=event.screenY 
       
       
// check if the mouse up is in the target grid       
       
var gridHeight=150;
       var 
gridWidth=300;
       var 
selectorWidth=0;
       if (
target.getSelectorVisible())
       {
            
selectorWidth=target.getSelectorWidth();
       }

       if (
yDropMin==0)
       {
          var 
el target.getCellTemplate(00).element();    
          
rowHeight =el.offsetHeight;                
          
yDropMin AW.getTop(el); // y of first row 
          
yDropMax yDropMin target.getHeaderHeight()+gridHeight;
          
xDropMin AW.getLeft(el); // x of first row 
          
xDropMax xDropMin gridWidth-selectorWidth// x of first row           
       
}

       if (
x>xDropMin && x<xDropMax && y>yDropMin && y<yDropMax)
       {
          
// mouse up is in the grid, compute row and forward event             
          // we need to tinker that with the position of the scrollbar
          
target.onCellMouseUp(event,0,Math.round((y-yDropMin+target.getScrollTop())/rowHeight));                     
       }           
    
    }

    
target.onCellMouseUp = function(eventcolumnrow) {    
    if (
startrow) {                               
           if (
TargetCellText[0][0]==undefined)
           {        
            
TargetCellText[0][0]=CellText[startrow][0];
                
TargetCellText[0][1]=CellText[startrow][1];
           }
           else
           {
                  var 
insertindex=row;               
                  if (
insertindex>target.getRowCount()-1)
                  {
                      
insertindex=target.getRowCount();
                  }
                  
//alert("add val from row " + startrow + " at row " + row  +" insert index= " + insertindex );
                         
                  
TargetCellText.splice((insertindex*1),0,CellText[startrow]); 
                  
target.setRowCount(target.getRowCount()+1);                   
              }
           
           
target.refresh(); 
           
dragstop();
           } 
    
    }; 
    
    
document.write(obj); 
    
document.write(target); 
    
document.onmouseup = function () { // stop draging the row when onmouseup happens out of the grids
        
if (startrow) { dragstop() ;  }
    }
    

</
script
<
br
<
button onclick="AddNewRowBelowSelectedRow()">Add New Row Below Selected Row</button
<
button onclick="DeleteSelectedRow()">Delete Selected Row</button
<
hr


This has been tested using AW 2.0 (standard/final) and IE and Firefox 1.0It has some limitations 
<ul
<
li>Only works on ARRAY based grid
<
li>Array is manipulated directly using splice (instead of addRow deleteRow). 
<
li>Sorting is not supported so it is disabled 
</ul
</
div>

<
div id="FeedbackRow" style="position:absolute;display:none" onmouseup="target.onCellMouseUpForward(event)">
</
div>

<
div id="debug">
</
div>

<
div id="debug2">
</
div>
</
body
</
script
</
html
    
Lucho
Thursday, February 23, 2006
Hi Lucho,

Great job! I ran it under IE and the only glitch compared to FF is the feedback row is not in the same spot. Other than that it works fine in IE.

Sorting is disabled in the original because I didn't think it would work with the way I was splicing the data source array. You can enable sorting and give it a try. The line is:

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

Rob Francis
Thursday, February 23, 2006
Hi Lucho,

I forgot to suggest that when you make the next revision to your sample please post it as a brand new thread. It is a great example and I'm worried that it will get lost in this thread. As the title you could use something like "Example of Drag and Drop between 2 grids" so it is easy to find.

Thanks again.
Rob Francis
Friday, February 24, 2006
Rob, to keep your sample compatible with sorting you need to do something like:
(just replace the whole dragstop function whith all this)
var SortedIndices=[]; 
     
///// clone indices array & fill (when empty)/////////
  
for (i=0;i<CellText.length;i++){ SortedIndices.push(i) } 
   
    
///////// WHEN HEADER CLICKED ////////////
  
obj.onHeaderClicked = function(eventindex){
  
window.setTimeout(function(){
  
SortedIndices obj.getRowIndices();
  },
30);
   }

    
// END DRAG & DROP - THIS CODE MOVES THE DRAG ROW TO THE DROP LOCATION  
    
function dragstop(columnrow){  

        
mouseCelldown=false;  
        
stoprow=row;  

        var 
startrowcontents CellText[startrow];  

var 
indexfrom ;
var  
indexto ;

   for (
i=0;i<SortedIndices.length;i++){ 
if(
SortedIndices[i] == startrow){ indexfrom }
if(
SortedIndices[i] == stoprow){ indexto }
}

var 
rowmoved SortedIndices[indexfrom];

var 
x=indexfrom;
if(
indexfrom<indexto){
 while( 
x<indexto ){ SortedIndices[x]=SortedIndices[x+1] ; x++ ; }
 }

if(
indexfrom>indexto){
 while( 
x>indexto ){ SortedIndices[x]=SortedIndices[x-1] ; x-- ; }
 }
 
 
SortedIndices[indexto]=rowmoved ;
 
  
obj.setRowIndices(SortedIndices);
    
obj.setSelectedRows([stoprow]);  
    }  
 
Carlos
Sunday, February 26, 2006
Also Add & Delete functions need some new code:

function DeleteSelectedRow(){  
 var 
insertindex=obj.getSelectedRows();
    for (
i=0;i<SortedIndices.length;i++){ 
if(
SortedIndices[i] == insertindex){ SortedIndices.splice(i1); }
}
 
obj.setRowCount(obj.getRowCount()-1);
  
obj.setRowIndices(SortedIndices);
    }  

    
/**********************/  
       
   
function AddNewRowBelowSelectedRow(){  
      var 
insertindex=obj.getSelectedRows();  
      
CellText.push(["new","new"])
    for (
i=0;i<SortedIndices.length;i++){ 
if(
SortedIndices[i] == insertindex){ SortedIndices.splicei+10CellText.length-); }
}
      
obj.setRowCount(obj.getRowCount()+1);  
        
obj.setRowIndices(SortedIndices);
    }  
 
Carlos
Sunday, February 26, 2006
Thanks Carlos.

For my use (drag and drop rows in 1 grid), it doesn't make sense for me to allow sorting since I want the user to set the row order. I also create the array in the proper initial order. However, maybe for other people they can think of a reason to enable the sorting.

Also, in Lucho's example (drag and drop rows between 2 grids) it could be very useful. Hopefully your changes will help him too.
Rob Francis
Sunday, February 26, 2006
sounds great, hope I will have time to look at that today or tomorrow.
Lucho
Tuesday, February 28, 2006
Hey Rob,

A question please. In your drag-and-drop example as hosted on friendsofaw.com, you have two functions that start things off: dragstart(e, column, row) and dragRowStart(event).

As far as I can tell, the "e" argument passes to dragstart() has the same srcElement as the "event" passed to dragRowStart(). In which case, I don't understand why the two methods can't be combined into one.

Perhaps is a browser-dependency thing?

Thanks in advance.
LostInSpace
Thursday, April 6, 2006
Hi

I want to implement the same type of functionalities in a grid for my web application.My webapplication is a J2EE presentation component and we use using JSP/Struts based architechture.Is the grid be fully functional with JSP/Struts

I want both drag and drop as well as I want to add the nested Grid to my web application.I saw the drag and drop in Rows.Can this be implemented in columns?

Thanks
Vikramaditya Garg
vikramaditya.garg@fidelity.co.in


Vikramaditya Garg
Thursday, April 13, 2006
Hi Vikramaditya!

I got the same request as you.
Have you found anything yet?

Has anybody got a code snippet for changing the column order?
If so, please let me know

Thanks
Nice regards
Werner
register@sosgmbh.at
Werner
Friday, April 14, 2006
Hi LostInSpace,

Sorry for the slow reply. I haven't been on this forum for awhile because I've got the AW code pretty stable in my project and am working on other parts now :)

The sample above was hacked together using multiple other sample from the forum. If you think those can be combined then give it a try. I didn't spend too much time trying to optimize it.

Good luck,
Rob
Rob Francis
Thursday, April 20, 2006
Very cool stuff - 1 thing that would make this thing really great for sorting purposes would be if you could drag and drop multiple rows at a time. For example, if you could click on the selectors in "multi-row" mode to select which ones you wanted to drag. Then, when you actually clicked on one of the cells it started dragging. That way, if you wanted to move the top two rows to the bottom you could do it with one move, not two. What do you think?
Chris
Friday, May 19, 2006
Hi,

I found what it seems a bug in this wonderful drag-and-drop script:

When there are a few lines in the grid and there is a blank space below them, if you click over the blank space, the script tries to drag all the lines of the script.

You can reproduce this behaviuor in the demo of this script in http://friendsofaw.com/nuke/modules.php?name=Demos when you delete all rows except two or three and click on the blank space of the grid. When you move the mouse all the rows of the grid move also.

I will try to find how to control this, but write this post in case someone knows better this piece of code and can do it faster than me.

Regards.
joakinen
Thursday, June 22, 2006
joakinen, thanks to point this "bug", there should be several ways to avoid it, my first approach is:
( add this new line at bottom of dragRowStart to break the process if no row is clicked)

var dragRowStart = function(event) { 
.....
.....
         
mouseCelldown true

    
// this line is new    
       
if (sECId.indexOf("-rows") > ){ mouseCelldown false }
    } ] 
Carlos
Friday, June 23, 2006
Thanks Carlos, the patch works like a charm!

A question: Is compatible the editing of cells with this drag & drop script? I don't know why the field edit facilities don't work if I add the drag & drop code to my grid...

joakinen
Wednesday, June 28, 2006

Hi,

When you make this grid editable, some strange things happen.
Another bug? I think that the onCellMouseDown/onCellMouseUp events triggered to control the drag&drop process seems to interfere with the editing process.

Steps to reproduce this behaviour using the script published in FriendsOfAW:

STEP 1:change the line
var obj = new AW.UI.Grid to this
var obj = new AW.Grid.Extended STEP 2: change this line
obj.setSelectionMode("single-row");   to this
obj.setSelectionMode("single-cell");  STEP 3: add this line
obj.setCellEditable(true);  At this point you have editing enabled in the grid, but it works in a weird way: to enter the editing mode in a cell you have to follow this 3-step process: [1] click on the cell, [2] doubleclick on the same cell, and [3] press F2. If you click on the cell and then press F2 (the usual way) nothing happens.

Now if you comment the lines following the comment "THESE ARE CALLED TO START AND STOP THE DRAG AND DROP OF ROWS", like this

//obj.onCellMouseDown     = function(event, column, row){ dragstart(event, column, row) };
//obj.onCellMouseUp       = function(event, column, row){ if (startrow) { dragstop(column, row) }};
//obj.setEvent("onmousemove", dragRowMouseMove);
//RowsArea.setEvent("onmousedown", dragRowStart);
 
then editing works perfectly (click & F2) but, of course, you have no drag&drop.

It seems that when I click on a cell to edit it, such click doesn't reach the edit events and is processed only by the drag&drop events. This behaviour is somehow broken by doubleclicking in the cell.

What is the solution to this to make compatible the click&drag action with click&edit?

Regards.
joakinen
Monday, July 10, 2006
Hmmmm, any budget to afront it ?? ;-)
Not easy, but after a fast evaluation I think doable, but may require some tests and time (currently not in my priority list) :-(

I would start removing obj.onCellMouseDown/Up and placing its lines inside current events.
HTH
Carlos
Tuesday, July 11, 2006
Perhaps checking inside tj.onCellMouseDown/Up hat SHIFT or ALT is pressed to fireup the drag&drop events and that the basic clicks keep linked to the edit events?
joakinen
Wednesday, July 12, 2006
Not sure, but I see a risk going that direction, Think that the doubleclick event trapped by edition is a combination of two single clicks
(therefore the onCellMouseDown/Up events are "locking" it and fired first)
I maintain my last point, and would remove it ( Although I know that it means rebuild half of this sample and construct a new Drop )
Thanks
Carlos
Wednesday, July 12, 2006



This topic is archived.

Back to support forum

Forum search