drag and drop rows from grid to grid
Posted on November 23rd, 2008 by jack
http://tdg-i.com/js/extexamples/dnd_grid_to_grid/dnd_grid_to_grid.html
from this post...
http://extjs.com/forum/showthread.php?t=39277
His example works great but he creates grid objects instead of using xtypes. The problem is I'm using xtypes and theres no real way that I can think of to tie his droptargets to my xtypes.
For a little background on what I'm trying to do, I have a bunch of grids in my app and all of them show different types of data (a contact grid, an address grid, a phone number grid, etc etc) I would like to be able to drag and drop between each grid to represent associations between the rows in those grids. For example, if I want to associate 2 addresses to a contact, I would multi select 2 addresses from the addresses grid and drag/drop them to the contact in the contact grid. No new rows would be created in the target grid and no current rows would be deleted from the source grid. To make things easier on myself, all my grids extend a myGridCls class that extends the Ext.grid.EditorGridPanel class so I can make changes to my grids in one place. Is there any way I could include a droptarget config in myGridCls so that way I wouldn't have to make a separate droptarget config for every single one of my grids.
Heres some sample code...
var myGridCls = Ext.extend(Ext.grid.EditorGridPanel, {
initComponent:function() {
Ext.apply(this, {
enableDragDrop: true,
loadMask: true,
sm: new Ext.grid.RowSelectionModel(),
autoScroll: true,
viewConfig: {
forceFit: true
}
});
this.on('afteredit',function(e){
Ext.Ajax.request({
url: 'editfield.php',
method: 'GET',
timeout: 90000,
params: {
EntryType: this.EntryType,
Entry_ID: e.record.data.Entry_ID,
Field: e.field,
Value: e.value
}
});
},this);
myGridCls.superclass.initComponent.apply(this, arguments);
}, onRender:function() {
this.on({
rowcontextmenu: function(g,ri,e){
e.stopEvent(); // Prevent the browser to show its default contextmenu
gridCtxMenu.rowIndex = ri; // It's important! you'll need the rowIndex (the row that right clicked on it) on future.
gridCtxMenu.srcId = 'protoid';
gridCtxMenu.showAt(e.getXY()); // Get the current X and Y coordinates and show the gridCtxMenu (my custom created menu) on that location.
},
scope: this
});
if( this.DeleteEntries==true ){
this.on('keydown',function(e){
debug(e);
debug(e.getCharCode());
if( e.getCharCode()==46){
this.getSelectionModel().selections.each(function( item){
Ext.Ajax.request({
url: 'deleterow.php',
method: 'POST',
params: {
EntryType: this.EntryType,
ParentEntry_ID: this.Entry_ID,
Entry_ID: item.data.Entry_ID
}
});
},this );
Ext.each(this.getSelectionModel().getSelections(), this.getStore().remove, this.getStore());
}
},this);
}
myGridCls.superclass.onRender.apply(this, arguments);
}
});
var addressEditGridCls = Ext.extend(myGridCls, {
initComponent:function() {
Ext.apply(this, {
height: 100,
DeleteEntries: true,
columns: addyGridFields,
EntryType: 'ADDRESS',
store: new Ext.data.SimpleStore({
proxy: new Ext.data.HttpProxy({
timeout: 60000,
url: 'loadlist.php',
method: 'GET'
}),
baseParams: {
Type: 'CONTACT_ADDRESSES'
},
fields: addyGridFields
}),
tbar: [{
text: 'Add Address',
iconCls: 'add',
handler: function(){
Ext.getCmp('triggerform').layout.setActiveItem('ne wAddressForm');
Ext.getCmp('newAddressForm').Entry_ID=this.Entry_I D;
Ext.getCmp('newAddressForm').getForm().reset();
debug(this);
}, scope: this
}]
});
addressEditGridCls.superclass.initComponent.apply( this, arguments);
},onRender:function() {
addressEditGridCls.superclass.onRender.apply(this, arguments);
}
});
Ext.reg('addressEditGrid', addressEditGridCls);
var phoneEditGridCls = Ext.extend(myGridCls, {
initComponent:function() {
Ext.apply(this, {
height: 100,
DeleteEntries: true,
columns: phoneGridFields,
EntryType: 'PHONE',
store: new Ext.data.SimpleStore({
proxy: new Ext.data.HttpProxy({
timeout: 60000,
url: 'loadlist.php',
method: 'GET'
}),
baseParams: {
Type: 'CONTACT_PHONES'
},
fields: phoneGridFields
})
});
phoneEditGridCls.superclass.initComponent.apply(th is, arguments);
},onRender:function() {
phoneEditGridCls.superclass.onRender.apply(this, arguments);
}
});
Ext.reg('phoneEditGrid', phoneEditGridCls);
var contactCatGridCls = Ext.extend(myGridCls, {
initComponent:function() {
Ext.apply(this, {
store: contactCatGridAllSt,
hideHeaders: true,
EntryType: 'CONTACTCATEGORY',
cm: new Ext.grid.ColumnModel([
// checkColumn,
{id: 'ContactCategory', header: "Contact Category", width: 350, sortable: false, dataIndex: 'ContactCategoryLabel'}
])
// sm: checkColumn
});
contactCatGridCls.superclass.initComponent.apply(t his, arguments);
},onRender:function() {
contactCatGridCls.superclass.onRender.apply(this, arguments);
}
});
Ext.reg('contactCatGrid', contactCatGridCls);
Ext.override(Ext.grid.GridView, {
onRowOver : function(e, t){
var row;
if((row = this.findRowIndex(t)) !== false){
this.grid.droprow=this.grid.getStore().getAt(row);
this.addRowClass(row, 'x-grid3-row-over');
}
}
});
this is exactly what I was looking for. So just to understand what I'm doing...
By putting
this.dz = new GridDropZone(this, {ddGroup:this.ddGroup 'GridDD'});
inside the onRender method in my class and after the...
myGridCls.superclass.onRender.apply(this, arguments);
I'm saying that after a grid has been created/rendered and all the render type args have been applied, THEN ad the dropzone to it? Anywhere else and the dom div tags of my grid wouldn't be setup at that point in time so there would be nothing for the dropzone to glue it's self on to. Did I get it?
var dz1 = new Ext.dd.DropZone(myGridCls.getView().el.dom.childNo des[0].childNodes[1], {ddGroup:'group'});
this obviously doesn't work but its an example of what I'm talking about.
Ext.override(Ext.grid.GridView, {
onRowOver : function(e, t){
var row;
if((row = this.findRowIndex(t)) !== false){
this.grid.droprow=this.grid.getStore().getAt(row);
}
}
});
I just have it store the hovered grid row to this.grid.droprow so I can access it when I drop whatever it is I'm dragging.
Now my next dilemma is how to get hover over highlighting to work while your dragging over a grid row. When you mouse over a grid row it turns on fine, but when you are dragging something it doesn't show.
As I'm dragging my rows, I can easily sniff the selection module of the source grid to see what rows I'm dragging and I can easily dive into what ever grid I'm dropping the rows into but I can't seem to see the target row in the target grid I'm dragging the source rows into. Like if I'm dragging rows 1-7 from grid A into row 10 on grid B, I can get to the 1-7 rows just fine and I can see grid B just fine but I can't get to row 10 in grid B. I checked grid Bs selection model and obviously, the target row doesn't show up since it's not technically selected.
I honestly have no clue what you mean. Do you mean something like this?
var myGridCls = Ext.extend(Ext.grid.EditorGridPanel, {
initComponent:function() {
Ext.apply(this, {
enableDragDrop: true,
loadMask: true,
droptarget: new Ext.dd.DropTarget({stuff goes here}),
sm: new Ext.grid.RowSelectionModel(),
autoScroll: true,
viewConfig: {
forceFit: true
}
});
myGridCls.superclass.initComponent.apply(this, arguments);
}, onRender:function() {
myGridCls.superclass.onRender.apply(this, arguments);
}
});