PDA

View Full Version : Drag and Drop via 2 Grids and sort Rows via D&D



rakete
12 May 2009, 2:55 AM
hi there!

im an extJs Newbie and sorry if my english is not perfect.

I need to d&d between two grids. In the left grid i need to sort rows via d&d.

heres is my example
http://server1a203.eventit.ag/Unbenannt-1.gif

with the following code:



Ext.ns('Example');

// {{{
Example.GridDropZone = function(grid, config) {
this.grid = grid;
Example.GridDropZone.superclass.constructor.call(this, grid.view.scroller.dom, config);
};
Ext.extend(Example.GridDropZone, Ext.dd.DropZone, {

onContainerOver:function(dd, e, data) {
return dd.grid !== this.grid ? this.dropAllowed : this.dropNotAllowed;
} // eo function onContainerOver

,onContainerDrop:function(dd, e, data) {
if(dd.grid !== this.grid) {
this.grid.store.add(data.selections);
Ext.each(data.selections, function(r) {
dd.grid.store.remove(r);
});
this.grid.onRecordsDrop(dd.grid, data.selections);
this.grid.sort('feildname', 'ASC');
return true;
}
else {
return false;
}
} // eo function onContainerDrop

});
// }}}
// {{{

Ext.namespace('Ext.ux.dd');

Ext.ux.dd.GridReorderDropTarget = function(grid, config) {
this.target = new Ext.dd.DropTarget(grid.getEl(), {
ddGroup: grid.ddGroup || 'GridDD'
,grid: grid
,gridDropTarget: this
,notifyDrop: function(dd, e, data){
// determine the row
var t = Ext.lib.Event.getTarget(e);
var rindex = this.grid.getView().findRowIndex(t);
if (rindex === false) return false;
if (rindex == data.rowIndex) return false;

// fire the before move/copy event
if (this.gridDropTarget.fireEvent(this.copy?'beforerowcopy':'beforerowmove', this.gridDropTarget, data.rowIndex, rindex, data.selections) === false) return false;

// update the store
var ds = this.grid.getStore();
if (!this.copy) {
for(i = 0; i < data.selections.length; i++) {
ds.remove(ds.getById(data.selections[i].id));
}
}
ds.insert(rindex,data.selections);

// re-select the row(s)
var sm = this.grid.getSelectionModel();
if (sm) sm.selectRecords(data.selections);

// fire the after move/copy event
this.gridDropTarget.fireEvent(this.copy?'afterrowcopy':'afterrowmove', this.gridDropTarget, data.rowIndex, rindex, data.selections);

return true;
}
,notifyOver: function(dd, e, data) {
var t = Ext.lib.Event.getTarget(e);
var rindex = this.grid.getView().findRowIndex(t);
if (rindex == data.rowIndex) rindex = false;

return (rindex === false)? this.dropNotAllowed : this.dropAllowed;
}
});
if (config) {
Ext.apply(this.target, config);
if (config.listeners) Ext.apply(this,{listeners: config.listeners});
}

this.addEvents({
"beforerowmove": true
,"afterrowmove": true
,"beforerowcopy": true
,"afterrowcopy": true
});

Ext.ux.dd.GridReorderDropTarget.superclass.constructor.call(this);
};

Ext.extend(Ext.ux.dd.GridReorderDropTarget, Ext.util.Observable, {
getTarget: function() {
return this.target;
}
,getGrid: function() {
return this.target.grid;
}
,getCopy: function() {
return this.target.copy?true:false;
}
,setCopy: function(b) {
this.target.copy = b?true:false;
}
});

var reader = new Ext.data.ArrayReader({}, [
{name: 'caption'},
{name: 'groupingField'}
]);

Example.Grid = Ext.extend(Ext.grid.GridPanel, {

// defaults - configurable from outside
border:false
,autoScroll:true
,viewConfig:{forceFit:true}
,layout:'fit'
,enableDragDrop:true
,initComponent:function() {

// hard coded config - cannot be changed from outside
var config = {
columns:[
{dataIndex:'caption', header:'Feld', sortable: true},
{dataIndex:'groupingField', header:'Gruppe'}

]
};

// apply config
Ext.apply(this, Ext.apply(this.initialConfig, config));

// call parent
Example.Grid.superclass.initComponent.apply(this, arguments);

} // eo function initComponent


,listeners: {
render: function(g) {
// Best to create the drop target after render, so we don't need to worry about whether grid.el is null

// constructor parameters:
// grid (required): GridPanel or EditorGridPanel (with enableDragDrop set to true and optionally a value specified for ddGroup, which defaults to 'GridDD')
// config (optional): config object
// valid config params:
// anything accepted by DropTarget
// listeners: listeners object. There are 4 valid listeners, all listed in the example below
// copy: boolean. Determines whether to move (false) or copy (true) the row(s) (defaults to false for move)
var ddrow = new Ext.ux.dd.GridReorderDropTarget(g, {
copy: false
,listeners: {
beforerowmove: function(objThis, oldIndex, newIndex, records) {
// code goes here
// return false to cancel the move
}
,afterrowmove: function(objThis, oldIndex, newIndex, records) {
// code goes here
}
,beforerowcopy: function(objThis, oldIndex, newIndex, records) {
// code goes here
// return false to cancel the copy
}
,afterrowcopy: function(objThis, oldIndex, newIndex, records) {
// code goes here
}
}
});

// if you need scrolling, register the grid view's scroller with the scroll manager
Ext.dd.ScrollManager.register(g.getView().getEditorParent());
}
,beforedestroy: function(g) {
// if you previously registered with the scroll manager, unregister it (if you don't it will lead to problems in IE)
Ext.dd.ScrollManager.unregister(g.getView().getEditorParent());

}
}


,onRender:function() {
Example.Grid.superclass.onRender.apply(this, arguments);

this.dz = new Example.GridDropZone(this, {ddGroup:this.ddGroup || 'GridDD'});
} // eo function onRender
/**
* Called when records are dropped on this grid
* @param {Ext.grid.GridPanel} srcGrid The source grid
* @param {Array} records Array of dropped records
*/
,onRecordsDrop:Ext.emptyFn

}); // eo extend

// }}}
// {{{
Example.Grid1 = Ext.extend(Example.Grid, {

initComponent:function() {

// var gridcolumns =new Array();


// hard coded config - cannot be changed from outside
var config = {
store: new Ext.data.Store({
reader: reader,
data: Ext.grid.ExportData
})

};

// apply config
Ext.apply(this, Ext.apply(this.initialConfig, config));

// call parent
Example.Grid1.superclass.initComponent.apply(this, arguments);

} // eo function initComponent
}); // eo extend

// register xtype
Ext.reg('examplegrid1', Example.Grid1);
// }}}
// {{{
Example.Grid2 = Ext.extend(Example.Grid, {

initComponent:function() {

// hard coded config - cannot be changed from outside
var config = {
store: new Ext.data.GroupingStore({
reader: reader
,data: Ext.grid.NoExportData
,sortInfo:{field: 'caption', direction: "ASC"}
,groupField:'groupingField'
}),
view: new Ext.grid.GroupingView({
forceFit:true,
groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})'
})
};

// apply config
Ext.apply(this, Ext.apply(this.initialConfig, config));

// call parent
Example.Grid2.superclass.initComponent.apply(this, arguments);

} // eo function initComponent
}); // eo extend

// register xtype
Ext.reg('examplegrid2', Example.Grid2);
// }}}

Ext.BLANK_IMAGE_URL = './ext/resources/images/default/s.gif';

// application main entry point
Ext.onReady(function() {

Ext.QuickTips.init();

// create and show window
var win = new Ext.Window({
layout:'border'
,width:680
,height:240
,title:Ext.getDom('page-title').innerHTML
,items:[{
xtype:'examplegrid1'
,region:'west'
,width:340
,split:true
},{
xtype:'examplegrid2'
,region:'center'
}]
});
win.show();

}); // eo function onReady



it is working but i could only sort via d&d in the left grid OR (when i delete the render: function) d&d via the grids
i think the render function overwrite the onrender function but i have no idea how to join these both snippets.:-/

thanks for help!

rakete
12 May 2009, 4:23 AM
got a solution, thx

jsundquist
2 Jun 2009, 10:05 AM
Mind actually posting your solution.

brentdooley999
3 Jun 2009, 11:03 AM
I would also like to see it. Thanks.

rakete
4 Jun 2009, 3:58 AM
hi there!

here is my solution. thats not the complete code because its getting really big but this is all you need to drag & drop fields via 2 grids and also to sort the left grid items via drag and drop.
The right grid is a GroupingStore and it sorts automatically after each drag/drop.



Ext.ux.dd.GridReorderDropTarget = function(grid, config) {
this.target = new Ext.dd.DropTarget(grid.getEl(), {
ddGroup: grid.ddGroup || 'GridDD'
,grid: grid
,gridDropTarget: this
,notifyDrop: function(dd, e, data){
// determine the row
var t = Ext.lib.Event.getTarget(e);
var rindex = this.grid.getView().findRowIndex(t);
if (rindex === false) return false;
if (rindex == data.rowIndex) return false;

// fire the before move/copy event
if (this.gridDropTarget.fireEvent(this.copy?'beforerowcopy':'beforerowmove', this.gridDropTarget, data.rowIndex, rindex, data.selections) === false) return false;

// update the store
var ds = this.grid.getStore();
if (!this.copy) {
for(i = 0; i < data.selections.length; i++) {
ds.remove(ds.getById(data.selections[i].id));
}
}
ds.insert(rindex,data.selections);

// re-select the row(s)
var sm = this.grid.getSelectionModel();
if (sm) sm.selectRecords(data.selections);

// fire the after move/copy event
this.gridDropTarget.fireEvent(this.copy?'afterrowcopy':'afterrowmove', this.gridDropTarget, data.rowIndex, rindex, data.selections);

return true;
}
,notifyOver: function(dd, e, data) {
var t = Ext.lib.Event.getTarget(e);
var rindex = this.grid.getView().findRowIndex(t);
if (rindex == data.rowIndex) rindex = false;

return (rindex === false)? this.dropNotAllowed : this.dropAllowed;
}
});
if (config) {
Ext.apply(this.target, config);
if (config.listeners) Ext.apply(this,{listeners: config.listeners});
}

this.addEvents({
"beforerowmove": true
,"afterrowmove": true
,"beforerowcopy": true
,"afterrowcopy": true
});

Ext.ux.dd.GridReorderDropTarget.superclass.constructor.call(this);
};


Ext.extend(Ext.ux.dd.GridReorderDropTarget, Ext.util.Observable, {
getTarget: function() {
return this.target;
}
,getGrid: function() {
return this.target.grid;
}
,getCopy: function() {
return this.target.copy?true:false;
}
,setCopy: function(b) {
this.target.copy = b?true:false;
}
});


Ext.onReady(function(){

// Array Reader - der das in smarty erstellte Array liest
var reader = new Ext.data.ArrayReader({}, [
{name: 'caption'},
{name: 'group'},
{name: 'dataorigin'},
{name: 'fieldidentifier'},
{name: 'show'}
]);

// create the data store
var firstGridStore = new Ext.data.Store({
reader: reader,
data: ExportData
});

// Column Model shortcut array
var cols = [
{id : 'caption', header: "Feldbezeichnung", width: 260, sortable: true, dataIndex: 'caption'},
{header: "Gruppe", width: 100, sortable: true, dataIndex: 'group'}
];

//Expander Template
var expander = new Ext.grid.RowExpander({
tpl : new Ext.Template(
'<div style="padding-left:28px"><p style="font-size:9px"><b>Herkunft:</b> {dataorigin}</p></div>'
)
});

// declare the source Grid
var firstGrid = new Ext.grid.GridPanel({
ddGroup : 'secondGridDDGroup'
,store : firstGridStore
,cm: new Ext.grid.ColumnModel([
expander,
new Ext.grid.RowNumberer(),
{id : 'caption', header: "Feldbezeichnung", width: 260, sortable: true, dataIndex: 'caption'},
{header: "Gruppe", width: 120, sortable: true, dataIndex: 'group'}
])
,autoExpandColumn : 'caption'
,autoExpandMin : 200
,autoExpandMax : 350
,enableDragDrop : true
,stripeRows : true
,width : 500
,plugins : [expander,rowActions]
,region : 'west'
,title : 'Export'
,buttons:[{
text:'Speichern'
,iconCls:'icon-save'
,id: 'savebtn'
,disabled: true
,scope: firstGrid
,handler:function() {

}
},{
text:'Zurücksetzen'
,iconCls:'icon-reset'
,id: 'resetbtn'
,disabled: true
// ,style: 'text-align: center; margin: 0 0 0 170;'
,handler:function() {

}
}]
,buttonAlign:'left'
,listeners: {
render: function(g) {
// Best to create the drop target after render, so we don't need to worry about whether grid.el is null
// constructor parameters:
// grid (required): GridPanel or EditorGridPanel (with enableDragDrop set to true and optionally a value specified for ddGroup, which defaults to 'GridDD')
// config (optional): config object
// valid config params:
// anything accepted by DropTarget
// listeners: listeners object. There are 4 valid listeners, all listed in the example below
// copy: boolean. Determines whether to move (false) or copy (true) the row(s) (defaults to false for move)
var ddrow = new Ext.ux.dd.GridReorderDropTarget(g, {
copy: false
,listeners: {
beforerowmove: function(objThis, oldIndex, newIndex, records) {
// code goes here
// return false to cancel the move
}
,afterrowmove: function(objThis, oldIndex, newIndex, records) {
// refresh grid 1
firstGrid.getView().refresh();
}
,beforerowcopy: function(objThis, oldIndex, newIndex, records) {
// code goes here
// return false to cancel the copy
}
,afterrowcopy: function(objThis, oldIndex, newIndex, records) {
// code goes here
// return false to cancel the copy
}
}
});

// if you need scrolling, register the grid view's scroller with the scroll manager
Ext.dd.ScrollManager.register(g.getView().getEditorParent());
}
,beforedestroy: function(g) {
// if you previously registered with the scroll manager, unregister it (if you don't it will lead to problems in IE)
Ext.dd.ScrollManager.unregister(g.getView().getEditorParent());
}
}
});

var secondGridStore = new Ext.data.GroupingStore({
reader: reader
,data: NoExportData
,sortInfo:{field: 'caption', direction: "ASC"}
,groupField:'group'
});

// create the destination Grid
var secondGrid = new Ext.grid.GridPanel({
ddGroup : 'firstGridDDGroup',
store : secondGridStore,
columns : cols,
enableDragDrop : true,
stripeRows : true,
autoExpandColumn : 'caption',
autoExpandMax : 350,
width : 300,
region : 'center',
title : 'Ablage',
view: new Ext.grid.GroupingView({
forceFit:true,
groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})',
startCollapsed : true
})
,buttonAlign:'right'

});


// ####################### Panel Anzeige ######################
// Panel mit Export Button
var displayPanel2 = new Ext.Panel({
width : '98%',
header : true,
title : 'Export',
height : 50,
collapsible:true,
layout : 'column',
renderTo : 'contentPanel1'
});
// Panel mit den beiden Grids
var displayPanel = new Ext.Panel({
width : '98%',
header : true,
collapsed: false,
title : 'Export Einstellungen',
height : 500,
autoHeight : false,
tools:[{
id:'maximize',
handler: function(event, toolEl, panel){
}
},{
id:'minimize',
hidden: true,
handler: function(event, toolEl, panel){
}
}],
cls : 'center',
collapsible:true,
layout : 'border',
renderTo : 'contentPanel2',
items : [
firstGrid,
secondGrid
]
});

// ####################### /eof Panel Anzeige ######################


var firstGridDropTargetEl = firstGrid.getView().el.dom.childNodes[0].childNodes[1];
var firstGridDropTarget = new Ext.dd.DropTarget(firstGridDropTargetEl, {
ddGroup : 'firstGridDDGroup',
copy : true,
notifyDrop : function(ddSource, e, data){

// Generic function to add records.
function addRow(record, index, allItems) {

//getting Drop Element Index
var t = Ext.lib.Event.getTarget(e);
var rindex = firstGrid.getView().findRowIndex(t);

if(rindex === false){
firstGridStore.add(record);
rindex = firstGridStore.getCount()-1;
}else{
firstGridStore.insert(rindex,record);
}

var newRecord = firstGridStore.getAt(rindex);
//alert(newRecord.get("caption") + " " +newRecord.get("show"));
newRecord.set("show",1);
//Remove Record from the source
ddSource.grid.store.remove(record);
// Call a sort dynamically
ddSource.grid.store.sort('caption', 'ASC');
firstGrid.getView().refresh();
}
// Loop through the selections
Ext.each(ddSource.dragData.selections ,addRow);
return(true);
}
});

var secondGridDropTargetEl = secondGrid.getView().el.dom.childNodes[0].childNodes[1];
var destGridDropTarget = new Ext.dd.DropTarget(secondGridDropTargetEl, {
ddGroup : 'secondGridDDGroup',
copy : false,
notifyDrop : function(ddSource, e, data){

// Generic function to add records.
function addRow(record, index, allItems) {

secondGridStore.add(record);
// Call a sort dynamically
secondGridStore.sort('caption', 'ASC');
var newRecord = secondGridStore.getAt(index);
newRecord.set("show",0);
//Remove Record from the source
ddSource.grid.store.remove(record);
}
// Loop through the selections
Ext.each(ddSource.dragData.selections ,addRow);
return(true);
}
});



});


hope that helps!

puyngke
26 Aug 2009, 8:45 AM
hei i really nid that plugin for my project and I can't seem to make it work...I hope you can post a working sample thank you very much