The first thing we need to do is tell our GridPanel that it's
going to be used for drag and drop, this is because the default
behavior for a grid is to have no drag and drop functionality (which
cuts down on resources, ie: memory). We can enable the drag and drop
functionality by setting the enableDragDrop config value to true
Getting Started With Grid Drag & Drop
Getting Started
The first thing we need to do is tell our GridPanel that it's
going to be used for drag and drop, this is because the default
behavior for a grid is to have no drag and drop functionality (which
cuts down on resources, ie: memory). We can enable the drag and drop
functionality by setting the enableDragDrop config value to true
enableDragDrop : true
Now that the first step is out of the way, lets move on to defining some of our drag and drop specifics.
D&D Groups
We will need to set the drag and drop group - ddGroup - this
is a unique identifier that ExtJS components will use to share their
dragged and dropped items. For our example, we are using 'mygrid-dd'.
In your case this might be something more along the lines of 'contacts'
or 'products' which could be set on multiple components to allow drag
and drop between them.
- ddGroup : 'mygrid-dd',
- ddText : 'Place this row.',
ddGroup : 'mygrid-dd',
ddText : 'Place this row.',
Setting
those two config options will give us a grid that allows rows to be
dragged but not dropped, and has a very generic looking dragproxy. So lets first tackle getting rid of that ugly dragproxy by overwriting it at the start of the selection process. We can do this by adding a beforerowselect listener that will modify the dragproxy message.
Listening For The Drag
Using the grids selection model, we can listen for a beforerowselect event and change the dragproxy.
- sm: new Ext.grid.RowSelectionModel({
- singleSelect:true,
- listeners: {
- beforerowselect: function(sm,i,ke,row){
- grid.ddText = title_img(row.data.title, null, row);
- }
- }
- })
sm: new Ext.grid.RowSelectionModel({
singleSelect:true,
listeners: {
beforerowselect: function(sm,i,ke,row){
grid.ddText = title_img(row.data.title, null, row);
}
}
})
This gives us a much nicer looking dragproxy, but we still have nowhere to drop the row.
Dropping The Row
In order to drop a row we need to setup the grids body area as a DropTarget, which will allow it to accept a dropped row.
- var ddrow = new Ext.dd.DropTarget(grid.getView().mainBody, {
- ddGroup : 'mygrid-dd',
- notifyDrop : function(dd, e, data){
- var sm = grid.getSelectionModel();
- var rows = sm.getSelections();
- var cindex = dd.getDragData(e).rowIndex;
- if (sm.hasSelection()) {
- for (i = 0; i < rows.length; i++) {
- store.remove(store.getById(rows[i].id));
- store.insert(cindex,rows[i]);
- }
- sm.selectRecords(rows);
- }
- }
- });
var ddrow = new Ext.dd.DropTarget(grid.getView().mainBody, {
ddGroup : 'mygrid-dd',
notifyDrop : function(dd, e, data){
var sm = grid.getSelectionModel();
var rows = sm.getSelections();
var cindex = dd.getDragData(e).rowIndex;
if (sm.hasSelection()) {
for (i = 0; i < rows.length; i++) {
store.remove(store.getById(rows[i].id));
store.insert(cindex,rows[i]);
}
sm.selectRecords(rows);
}
}
});
Just like the GridPanel, one of the first config options we need to set on the DropTarget is the ddGroup, which is set to mygrid-dd. This allows the GridPanel to accept any drops that come from a component having this same ddGroup
(of course we are only using one as both source and target). Next we
setup the code to be executed when a successful drop happens - the notifyDrop.
Lets break down the code were executing when a successful drop occurs:
- Grab a reference to the GridPanel's SelectionModel.
- Find out what row(s) are selected.
- Get the index of where the row was dropped in relation to the other rows.
- Loop through the selected rows.
- Remove the row of data from its current location.
- Add the row of data at its new location.
- Select the new row (just for a touch of class)
From this bit of code we have a grid that allows you to re-order the
rows. If you wanted to update the database with the new order, then an
ajax call could be added within the notifyDrop event. We could even use this same basic concept to drag rows between separate grids or other ExtJS components.
|