The library supports drag-and-drop within a grid or several grids on the page.
To enable the possibility to drag-and-drop rows in the grid, you should call method enableDragAndDrop() with the true parameter:
Enabling drag-and-drop in the grid
mygrid = new dhtmlXGridObject('gridbox');
...
mygrid.enableDragAndDrop(true);
mygrid.init();
The dragContext object is available during the onDrag event and contains the following properties:
mygrid.enableDragAndDrop(true);
mygrid.enableDragOrder(true);
mygrid.enableMercyDrag(true);
mygrid.setDragBehavior(sibling);
//the item is dropped as a sibling of the target item
mygrid.enableColumnMove(true);
mygrid.attachEvent("onBeforeCMove",function(sInd,tInd){
return confirm("Allows you to move column "+sInd+" to position "+tInd);
}); //return 'true' to allow moving, 'false' - to prohibit it
Related sample: Drag and Drop between Grids
Information stated in the 'Common' part is enough in most cases. The current part should be used just if you want to customize existing drag-and-drop behaviour.
The part covers the following topics:
To redefine the text displaying for the dragging item(s), use the rowToDragElement property. Inside the dragged text you can use any HTML.
mygrid.rowToDragElement=function(id){
//any custom logic here
return text;
}
Let's consider use-cases of specifying the following content:
mygrid.rowToDragElement=function(id){
var text = "<img src='some.gif'> - " + mygrid.cellById(id,0).getValue();
return text;
}
mygrid.rowToDragElement=function(id){
//_dragged.length - the number of dragging items
var text = mygrid._dragged.length + "item(s)";
return text;
}
mygrid.rowToDragElement=function(id){
var text="";
for (var i=0; i<this._dragged.length; i++)
text += mygrid.cellById(mygrid._dragged[i].idd,0).getValue() + "<br/>";
return text;
}
To deny dragging of specific items you can use the onBeforeDrag event.
Let's assume, you load data from an XML file and want to deny dragging of some rows. For this purpose, mark the unnecessary rows in any possible way, e.g. by user data:
<rows>
<row id="1"><cell> data 1 </cell></row>
<row id="2"><cell> data 2 </cell>
<userdata name="drag">deny</userdata>
</row>
</rows>
And then define the event handler as follows:
mygrid.attachEvent("onBeforeDrag",function(id){
// denies dragging if user data exists
if (grid.getUserData(id,"drag")=="deny") return false;
// allows dragging in any other case
return true;
}
From now on, each time d-n-d starts, user data of the dragged item will be checked, and the row can be dragged only if it isn't marked as 'denied'.
To deny dropping to some positions (e.g. to allow dragging A to B, but deny dragging A to C), you can use the onDragIn or onDrag events and return false each time you want to block the operation.
Let's assume you load data from an XML file and want to deny dropping items A to positions of items B. For this purpose mark rows based on the mentioned rule in any possible way, e.g. by userdata:
<rows>
<row id="1"> <cell> data 1 </cell> <userdata name="drag">A</userdata> </row>
<row id="2"> <cell> data 2 </cell> <userdata name="drag">B</userdata> </row>
</rows>
And then define event handler as follows:
mygrid.attachEvent("onDragIn",function(sid,tid){
// nothing can be dropped in a row marked as 'B'
if (mygrid.getUserData(tid,"drag")=="B") return false;
// allows dropping in any other cases
return true;
});
//or
mygrid.attachEvent("onDrag",function(sid,tid){
if (mygrid.getUserData(tid,"drag")=="B") return false;
return true;
});
The described scenario make more sense for TreeGrid, but it can also be used with some customization in case of a plain Grid.
By default, rows are moved (not copied) during the d-n-d operation.
To add some custom rules to this behavior use the moveRowTo() method.
mygrid.attachEvent("onDrag",function(sid,tid){
// moves an item as a sibling of some other element
mygrid.moveRowTo(sid,someID,"copy","sibling");
// blocks default d-n-d
return false;
});
To enable the 'copy' behavior, set the enableMercyDrag command to true.
mygrid.enableMercyDrag(true);
You have one more way to set the 'copy' behavior - the dragContext object, available only for the onDrag event.
mygrid.attachEvent("onDrag",function(sid,tid){
// copies an item instead of moving it
if (!some_check(sid,tid)) mygrid.dragContext.mode="copy";
return true;
});
In case of dhtmlxTreeGrid, you have the method setDragBehavior() to set the desired type of behavior:
mygrid.setDragBehavior("child"); // the item is dropped as a child of the target item
In order not to move or copy an item and apply just some custom logic to it, just return true within the onDrag event handler.
mygrid.attachEvent("onDrag",function(sid,tid){
some_custom_code(sid,tid);
return false;
});
The 'drag' action can be customized with the help of the onDragIn, onDragOut events.
Let's consider the following scenario: each time the dragged item enters the borders of any possible dropping its background is coloured in red. When the item is moved outside the dropping's borders - the background is cleared.
// sid - id of dragged item , tid - id of dropping item
mygrid.attachEvent("onDragIn",function(sid,tid,sgrid,tgrid){
if (tid) // tid may be null if dropping is in the grid body
mygrid.setRowTextStyle(tid,"background-color:red;");// marks current dropping
return true;
})
mygrid.attachEvent("onDragOut",function(tid){
if (tid)
mygrid.setRowTextStyle(tid,""); // clears styles set on the previous step
})
To customize the 'drag' action between several grids, use the gridToGrid property.
//snippet just copies the data, without applying any modifications to it
mygrid.gridToGrid = function(rowId,sgrid,tgrid){
var z=[];
for (var i=0; i<sgrid.getColumnCount(); i++) //applies to each cell in source grid
z[i]=sgrid.cellById(rowId,i).getValue(); // prepares data for the target grid
return z;
}
In case when d-n-d occurs between dhtmlxTree and dhtmlxGrid, the same can be done by using the treeToGridElement and gridToTreeElement elements:
//from dhtmlxGrid to dhtmlxTree
mygrid.gridToTreeElement = function(tree,treeID,gridID){
// takes data from 1st column as value for tree
return this.cellById(gridId,0).getValue();
}
//from dhtmlxTree to dhtmlxGrid
mygrid.treeToGridElement = function(tree,treeID,gridID){
// sets the tree text as a value of 1st column in the grid
var z=[treeObj.getItemText(treeID)];
return z;
}
The following events are generated during the d-n-d process:
In the default scenario there is no need to use any of the mentioned events, because the grid will process all the operations on its own. But sometimes the default behavior needs to be customized. In this case the mentioned events can be used.
Related sample: Drag-and-drop events
Back to top