PDA

View Full Version : How do I get the Ext js gridPanel that DropTarget is added to?



leprechaun
26 Jan 2011, 2:27 AM
I'm doing a drag and drop but with multiple grids in arrays.

In the code below I have a var firstGrid defined, which is accessible in notifyDrop, but I have to move to using an array of grids, which can each have fields dragged and dropped from them. So I can't use 'firstGrid'.

What I need is a way inside notifyDrop to say something like this.getParent() which will return the grid it has been added to. Sort of like how ddSource tells you where its come from, I need a quick method to say which grid its landing on.


var firstGridDropTargetEl = firstGrid.getView().scroller.dom;
var firstGridDropTarget = new Ext.dd.DropTarget(firstGridDropTargetEl, {
ddGroup : 'firstGridDDGroup',
notifyDrop : function(ddSource, e, data){
var records = ddSource.dragData.selections;
Ext.each(records, ddSource.grid.store.remove, ddSource.grid.store);
firstGrid.store.add(records);
return true
}
});I've left out code that is not needed in the example above but I have included the full code below. What I'm aiming for is to have an array of grids, so I can get hold of the target grid.

:-?



Ext.onReady(function(){


var highlightSelections = function(key, value) {
//key is Ext.data.Record object
//console.log(" value" + value + "Record Name:" + key.get("name") + "column1:" + key.get("column1"));
}


var myData = {
records : [
{name : "Rec 0", column1 : "0", column2 : "0"},
{name : "Rec 1", column1 : "1", column2 : "1"},
{name : "Rec 2", column1 : "2", column2 : "2"},
{name : "Rec 3", column1 : "3", column2 : "3"},
{name : "Rec 4", column1 : "4", column2 : "4"},
{name : "Rec 5", column1 : "5", column2 : "5"},
{name : "Rec 6", column1 : "6", column2 : "6"},
{name : "Rec 7", column1 : "7", column2 : "7"},
{name : "Rec 8", column1 : "8", column2 : "8"},
{name : "Rec 9", column1 : "9", column2 : "9"}
]
};


// Generic fields array to use in both store defs.
var fields = [
{name: 'name', mapping : 'name'},
{name: 'column1', mapping : 'column1'},
{name: 'column2', mapping : 'column2'}
];

// create the data store
var firstGridStore = new Ext.data.JsonStore({
fields : fields,
data : myData,
root : 'records'
});


// Column Model shortcut array
var cols = [
{id : 'name', header: "Record Name", width: 160, sortable: true, dataIndex: 'name'},
{header: "column1", width: 50, sortable: true, dataIndex: 'column1'},
{header: "column2", width: 50, sortable: true, dataIndex: 'column2'}
];

// declare the source Grid
var firstGrid = new Ext.grid.GridPanel({
id : 'myFirstGrid',
ddGroup : 'secondGridDDGroup',
store : firstGridStore,
columns : cols,
enableDragDrop : true,
stripeRows : true,
autoExpandColumn : 'name',
title : 'First Grid',
width:200,
height:200,
//draggable internal class from API
draggable: {
// Config option of Ext.Panel.DD class.
// It's a floating Panel, so do not show a placeholder proxy in the original position.
insertProxy: false,

// Called for each mousemove event while dragging the DD object.
onDrag : function(e){
// Record the x,y position of the drag proxy so that we can
// position the Panel at end of drag.
var pel = this.proxy.getEl();
this.x = pel.getLeft(true) - 15;
this.y = pel.getTop(true) - 188; //additional adjustment for some reason need to include box height


},

// Called on the mouseup event.
endDrag : function(e){
this.panel.setPosition(this.x, this.y);
//console.log("end drag:" + this.x, this.y);
}
},
selModel: new Ext.grid.RowSelectionModel({
singleSelect: true
})


});


var secondGridStore = new Ext.data.JsonStore({
fields : fields,
root : 'records'

});

// create the destination Grid
var secondGrid = new Ext.grid.GridPanel({
id : 'mySecondGrid',
ddGroup : 'firstGridDDGroup',
store : secondGridStore,
columns : cols,
enableDragDrop : true,
stripeRows : true,
autoExpandColumn : 'name',
title : 'Second Grid',
width:200,
height:200,
draggable: {
// Config option of Ext.Panel.DD class.
// It's a floating Panel, so do not show a placeholder proxy in the original position.
insertProxy: false,

// Called for each mousemove event while dragging the DD object.
onDrag : function(e){
// Record the x,y position of the drag proxy so that we can
// position the Panel at end of drag.

var pel = this.proxy.getEl();
this.x = pel.getLeft(true)- 15;
this.y = pel.getTop(true) - 188; //additional adjustment for some reason need to include box height


},

// Called on the mouseup event.
endDrag : function(e){

this.panel.setPosition(this.x, this.y);
//console.log("end drag:" + this.x, this.y);
}
},
selModel: new Ext.grid.RowSelectionModel({
singleSelect: true
})

});



//Simple 'border layout' panel to house both grids
var displayPanel = new Ext.Panel({
width : 900,
height : 600,
layout : 'hbox',
renderTo : 'panel',
layout:'absolute',
items : [
firstGrid,
secondGrid
],
bbar : [
'->', // Fill
{
text : 'Reset both grids',
handler : function() {
//refresh source grid
firstGridStore.loadData(myData);

//purge destination grid
secondGridStore.removeAll();
}
},
{
text : 'Reset grids position',
handler : function() {
firstGrid.setPosition(0,0);
secondGrid.setPosition(200,0);


}
}
]
});

// used to add records to the destination stores
var blankRecord = Ext.data.Record.create(fields);

/****
* Setup Drop Targets
***/
// This will make sure we only drop to the view scroller element
var firstGridDropTargetEl = firstGrid.getView().scroller.dom;
var firstGridDropTarget = new Ext.dd.DropTarget(firstGridDropTargetEl, {
ddGroup : 'firstGridDDGroup',
notifyDrop : function(ddSource, e, data){
var records = ddSource.dragData.selections;
Ext.each(records, ddSource.grid.store.remove, ddSource.grid.store);
firstGrid.store.add(records);
firstGrid.store.sort('name', 'ASC');
return true
}
});


// This will make sure we only drop to the view scroller element
var secondGridDropTargetEl = secondGrid.getView().scroller.dom;
var secondGridDropTarget = new Ext.dd.DropTarget(secondGridDropTargetEl, {
ddGroup : 'secondGridDDGroup',
notifyDrop : function(ddSource, e, data){
var records = ddSource.dragData.selections;
Ext.each(records, ddSource.grid.store.remove, ddSource.grid.store);
secondGrid.store.add(records);
secondGrid.store.sort('name', 'ASC');
Ext.each(records, highlightSelections);
return true
}
});

});

leprechaun
26 Jan 2011, 8:57 AM
Tried intead to iterate through the array and to get this work with after render in the main panel, (as all my grids are items for the main display panel) but it tells me Error: 'getView().scroller.dom' is null or not an object



afterRender : function(){
Ext.each(gridPanelArray, function(myGrid, index) {
var myView = myGrid.getView();
var myGridDropTargetEl = myGrid.getView().scroller.dom;
//var myGridDropTargetEl = myGrid.el;
});
}

I tried putting the after render into the gridPanel but it just failed

anyone have any ideas here?

:s

leprechaun
26 Jan 2011, 9:01 AM
oh and here is the entire code I'm working on so far....


/*!
* Ext JS Library 3.3.1
* Copyright(c) 2006-2010 Sencha Inc.
* [email protected]
* http://www.sencha.com/license
*/
Ext.onReady(function(){

var paper = Raphael(0, 0, 900, 900);

//we need an array to store lines drawn as sets
var raphaelSetArray = [];

//need a storage area for our GridPanels so we can iterate them
var gridPanelArray = [];

//need a storage area for our grid stores so we can iterate them
var gridStoreArray = [];

//need a storage area for myData objects // may not need later on
var allDataArray = [];

//tablePanel array for storage of tables/relations we can drag and drop onto the grid
//var tablePanelArray = [];

var disabledRecords = []; //e.g. disabledRecords = [2] will disable the third row in the table selection panel;

var disabledRefs = []; // e.g. disabledRefs = ['employee_number']; // means that it won't get drawn/redrawn


//make two json representing two tables with relationships


// we need to put all the table data in here for parsing and building the grid
var gridJson = {
"employees" : [
{"name" : "employee_number"},
{"name" : "first_name"},
{"name" : "last_name"}
],
"documents" : [
{"name" : "employee_number"},
{"name" : "document_number"},
{"name" : "customer_number"},
{"name" : "document_name"}
],
"customers" : [
{"name" : "customer_number"},
{"name" : "first_name"},
{"name" : "last_name"}
]
}

// Generic fields array to use in both store defs.
var fields = [
{
name: 'name',
mapping : 'name'
}
];

var cols = [
{
id : 'name',
width: 160,
sortable: false,
dataIndex: 'name'
}
];

var tablePanelData = {
tables : []
};

// Column Model shortcut array


DraggableGrid = Ext.extend(Ext.grid.GridPanel,{
// constructor function
constructor: function(config) {
Ext.apply(this, {

//id : 'fg',
ddGroup : 'gridPanelDDGroup',
//store : firstGridStore,
columns : cols,
enableDragDrop : true,
stripeRows : true,
autoExpandColumn : 'name',
hidden : true,
header : true,
//title : 'employees',
enableColumnMove : false,
enableHdMenu : false,
width:200,
height:200,
autoHeight : true,
viewConfig: {
scrollOffset: 0
},
//draggable internal class from API

draggable: {
// Config option of Ext.Panel.DD class.
// It's a floating Panel, so do not show a placeholder proxy in the original position.
insertProxy: false,
// Called for each mousemove event while dragging the DD object.
onDrag : function(e){
// Record the x,y position of the drag proxy so that we can
// position the Panel at end of drag.
var pel = this.proxy.getEl();
this.x = pel.getLeft(true) - 15;
this.y = pel.getTop(true) - 188; //additional adjustment for some reason need to include box height
paper.clear();
},

// Called on the mouseup event.
endDrag : function(e){
this.panel.setPosition(this.x, this.y);
//console.log("end drag:" + this.x, this.y);
reDraw(displayPanel);
}
},
selModel: new Ext.grid.RowSelectionModel({
singleSelect: true
})
/*
afterRender : function(){

Ext.each(gridPanelArray, function(myGrid, index) {
var myView = myGrid.getView();
var myGridDropTargetEl = myGrid.getView().scroller.dom;
//var myGridDropTargetEl = myGrid.el;
});

}*/
});
DraggableGrid.superclass.constructor.apply(this, arguments);
}
});

//we need to create an extended class for drop panels that can be dynamicaly created
GridDropTarget = Ext.extend(Ext.dd.DropTarget,{
// constructor function
constructor: function(config) {
Ext.apply(this, {
ddGroup : 'gridPanelDDGroup',

notifyDrop : function(ddSource, e, data){
var records = ddSource.dragData.selections;
var aRecordName = records[0].get('name');

//when adding check to see if record exist or not //TODO
var recordGridIndex ;
var aGrid;
//instead of using first grid here we could iterate gridPanelArray
Ext.each(gridPanelArray, function(itGrid, idxGrid) {
recordGridIndex = itGrid.store.find('name',aRecordName);
aGrid = itGrid;
});
if(recordGridIndex == -1)
{
aGrid.store.add(records);
recordGridIndex = aGrid.store.find('name',aRecordName);
var fgRow = aGrid.getView().getRow(recordGridIndex);
reDraw(displayPanel);
}
//What we need now is a method to check that the records are a valid link
return true
}

});
GridDropTarget.superclass.constructor.apply(this, arguments);
}
});



allDataArray = [];

//iterate through the original JSON for the grid, store data and build components
Ext.iterate(gridJson, function(key, value) {

var myArray = [];
var kName = key;

tablePanelData.tables.push({
name:key
});

Ext.each(value, function(item, index) {
myArray.push( {
"name" : item.name
} );
});

var myDataObject = new Object();
myDataObject[key] = myArray;
//alert("grid key" + key.toString());
allDataArray.push(myDataObject);

// create the data store
var myGridStore = new Ext.data.JsonStore({
fields : fields,
data : myDataObject,
root : kName
});

gridStoreArray.push(myGridStore);

var myGrid = new DraggableGrid({
id : kName + "Grid",
store : myGridStore,
title : kName,
columns : cols
});

//add the grid to our array so we can retrieve later set Visible and set Position
gridPanelArray.push(myGrid);

});

var tablePanelStore = new Ext.data.JsonStore({
fields : fields,
data : tablePanelData,
root : 'tables'
});

var tablePanelGrid = new Ext.grid.GridPanel({
id : 'tg',
ddGroup : 'tablePanelGridDDGroup',
store : tablePanelStore,
columns : cols,
enableDragDrop : true,
stripeRows : true,
autoExpandColumn : 'name',
header : true,
title : 'tables',
enableColumnMove : false,
enableHdMenu : false,
width:150,
height:600,
autoHeight : true,
viewConfig: {
scrollOffset: 0
},
view: new Ext.grid.GridView({
getRowClass: function (rec, idx, rowParams, store){
var id = parseInt(rec.id);
//alert(id);
if (disabledRecords.indexOf(idx) != -1)
{
//alert(idx + "Record disabled" );
return "disabled-record";
}
}
}),

selModel: new Ext.grid.RowSelectionModel({
singleSelect: true,
listeners: {
beforerowselect : function (sm, rowIndex, keep, rec) {
//var id = parseInt(rec.id);
//if (disabledRecords.contains(id))
//alert(disabledRecords.indexOf(rowIndex));
if (disabledRecords.indexOf(rowIndex) != -1){
alert("This record cannot currently be added" );
return false;
}
}
}
})
});


var tablePanel = new Ext.Panel({
width : 150,
height : 600,
x: 750,
layout : 'absolute',
items : [
tablePanelGrid
]
});

var displayPanelItems = gridPanelArray;

displayPanelItems.push(tablePanel);

//Simple 'border layout' panel to house both grids
var displayPanel = new Ext.Panel({
width : 900,
height : 600,
renderTo : 'panel',
layout:'absolute',
layoutConfig: {
align : 'stretch',
pack : 'start'
},

/*defaults : { flex : 1 }, //auto stretch
layoutConfig : { align : 'stretch' },*/
items : displayPanelItems ,
bbar : [
'->', // Fill
{
text : 'Draw Lines',
handler : function() {
reDraw(displayPanel);
}
},
{
text : 'Clear Lines',
handler : function() {
paper.clear();
//var tempArray = raphaelSetArray[0];
raphaelSetArray[0].rset.hide();
}
},
{
text : 'Reset grids position',
handler : function() {
//firstGrid.setPosition(0,0);
//secondGrid.setPosition(200,0);
}
}
],
keys: [
{
key: [Ext.EventObject.DELETE],
handler: function() {
//Ext.Msg.alert("Alert","Delete Key Event !");
//when we hit the delete key we need to delete the seperate relationship
//get selection Model
var firstSelectionModel = gridPanelArray[0].getSelectionModel();
var secondSelectionModel = gridPanelArray[1].getSelectionModel();
//get the selected record
//check selection has been made
if(firstSelectionModel.hasSelection()&
secondSelectionModel.hasSelection())
{

var firstRecord = firstSelectionModel.getSelected();
var secondRecord = secondSelectionModel.getSelected();
//get the index of selected record
//var idx = firstGrid.store.indexOf(record);

var firstName = firstRecord.data.name;
var secondName = secondRecord.data.name;
//we need to che
if(!firstName.localeCompare(secondName))
{
disabledRefs.push(firstName);
//alert( isInStringArray(firstName, disabledRefs) + secondName);
Ext.each(raphaelSetArray, function(raphaelSet, index) {
//iterate through array that stores raphael sets(paths & rect)
Ext.iterate(raphaelSet, function(key, value) {
//alert(key + " of raphaelSet is " + value);
//alert(typeof(value));
if(!firstName.localeCompare(value))
{
//alert(firstName + " matches " + value);
raphaelSet.rset.remove(); //removes the set from rapheal
var idx = raphaelSetArray.indexOf(raphaelSet);
if(idx!=-1)
{
raphaelSetArray.splice(idx,1);
}
//we also need to remove the raphealSet from the array
//raphaelSetArray.pop(raphaelSet);
}
});
});
}
}
}
}
]
/*,
afterRender : function(){
Ext.each(gridPanelArray, function(myGrid, index) {
var myView = myGrid.getView();
var myGridDropTargetEl = myGrid.getView().scroller.dom;
//var myGridDropTargetEl = myGrid.el;
});
}*/
});

// used to add records to the destination stores
//var blankRecord = Ext.data.Record.create(fields);

//
var displayPanelDropTargetEl = displayPanel.el;

var displayPanelDropTarget = new Ext.dd.DropTarget(displayPanelDropTargetEl, {
ddGroup : 'tablePanelGridDDGroup',
notifyDrop : function(ddSource, e, data){

//var records = ddSource.dragData.selections;
//var aRecordName = records[0].get('name');
//var aRecordNum = parseInt(records[0].get('column1')); //need to change header/field title to something more meaningful
var aRecordNum = data.rowIndex;

var dragEl = ddSource.getDragEl();
var dropRect = dragEl.getBoundingClientRect();

//var elAbPos = getElementAbsolutePos(this.getEl());

//alert("table dropped " + dropRect.left + " " + dropRect.top);
//alert("table dropped " + aRecordNum + " " + aRecordName);
var tempGridPanel = gridPanelArray[aRecordNum];
tempGridPanel.setVisible(true);
tempGridPanel.setPosition(dropRect.left - 15, dropRect.top - 188);
//now we need to take the bounding box xy from here as a position for placing the grid/table
reDraw(displayPanel);
//
//when adding check to see if record for table exist in panel or not //TODO
//What we need now is a method to check that the records are a valid link
return true
}

});

/*
Ext.each(gridPanelArray, function(myGrid, index) {
var myView = myGrid.getView();
var myGridDropTargetEl = myGrid.getView().scroller.dom;
//var myGridDropTargetEl = myGrid.el;
var myGridDropTarget = new Ext.dd.DropTarget(myGridDropTargetEl,{
id : (myGrid + 'DropTarget'),
//ddGroup : (myGrid + 'DDGroup') ,
ddGroup : 'gridPanelDDGroup',
notifyDrop : function(ddSource, e, data){
var records = ddSource.dragData.selections;
Ext.each(records, ddSource.grid.store.remove, ddSource.grid.store);

return true
}
});
});
*/



function isInStringArray(myString,myArray) {
var myArrayString = myArray.toString();
return (myArrayString.indexOf(myString) != -1);
}

function reDraw(displayPanel)
{
//var items = displayPanel.items.items;

//we must get the matches in records in order to find out their new locations and map them
//!what needs to happen now with the methods is that we need to compare all grids not just the first two!
var itemOneName;
var itemTwoName;

//we must loop through the gridPanelArray and then loop through the same grid panel array to loo???

gridPanelArray[0].store.data.each( function(itemOne, indexOne) {

itemOneName = itemOne.data.name;
//alert(itemOneName + "itemOneName");
gridPanelArray[1].store.data.each( function(itemTwo, indexTwo) {
itemTwoName = itemTwo.data.name;
//alert(itemTwoName + "itemTwoName");
//we check for a match name and we check the parent table is on the grid/visible
if((!gridPanelArray[0].hidden & !gridPanelArray[1].hidden) && (itemOneName.match(itemTwoName)) && !isInStringArray(itemOneName, disabledRefs)){
//alert("itemOneName:"+itemOneName + "\nindexOne:" + indexOne + "\nitemTwoName:"+itemTwoName + "\nindexTwo:" + indexTwo);
var dp = displayPanel;

var firstRow = gridPanelArray[0].view.getRow(indexOne);
var secondRow = gridPanelArray[1].view.getRow(indexTwo);
var fbcr = firstRow.getBoundingClientRect();
var sbcr = secondRow.getBoundingClientRect();

var lineDrawn;
var rectFirst;
var rectSecond;

//need to put in a if statement to check if its left or right
if(((fbcr.right - fbcr.left)/2) + fbcr.left < ((sbcr.right - sbcr.left)/2) + sbcr.left)
{
lineDrawn = paper.path("M"+(fbcr.right+10)+" "+(fbcr.bottom - 10)+"L"+ (sbcr.left-10) + " " + (sbcr.bottom - 10) );
// regular rectangle
rectFirst = paper.rect(fbcr.right, (fbcr.bottom - 11), 10, 2);
rectSecond = paper.rect((sbcr.left - 10) , (sbcr.bottom - 11), 10, 2);
}
else{
lineDrawn = paper.path("M"+(fbcr.left-10)+" "+(fbcr.bottom - 10)+"L"+ (sbcr.right+10) + " " + (sbcr.bottom - 10) );
rectFirst = paper.rect((fbcr.left - 10) , (fbcr.bottom - 11), 10, 2);
rectSecond = paper.rect(sbcr.right, (sbcr.bottom - 11), 10, 2);
}

//select bothe records in each grid and hit delete

var st = paper.set();
st.push(
lineDrawn,
rectFirst,
rectSecond
);

raphaelSetArray.push({
name:itemOneName,
rset:st
});
}
});
});
}

//this method needs to redraw each line for each relationships
function reDrawDynamic(displayPanel) //doesn't work yet'
{
//var items = displayPanel.items.items;

//we must get the matches in records in order to find out their new locations and map them
//!what needs to happen now with the methods is that we need to compare all grids not just the first two!
var itemOneName;
var itemTwoName;

var iterationGridOne;
var iterationGridTwo;

var indexGridOne;
var indexGridTwo;

//we must loop through the gridPanelArray and then loop through the same grid panel array to loo???
//when check one grid we must not compare it to itself, that is whats causing a problem
Ext.each(gridPanelArray, function(iGridOne, idxGridOne) {
iterationGridOne = iGridOne;
indexGridOne = idxGridOne;
Ext.each(gridPanelArray, function(iGridTwo, idxGridTwo) {
iterationGridTwo = iGridTwo;
indexGridTwo = idxGridTwo;
if(!(indexGridOne == indexGridTwo)){
//alert(typeof(iterationGridTwo) + " gridPanelArray.length "+ gridPanelArray.length);
iterationGridOne.store.data.each( function(itemOne, indexOne) {

itemOneName = itemOne.data.name;
//alert(itemOneName + "itemOneName");
iterationGridTwo.store.data.each( function(itemTwo, indexTwo) {
itemTwoName = itemTwo.data.name;
//alert(itemTwoName + "itemTwoName");
//we check for a match name and we check the parent table is on the grid/visible
if((!iterationGridOne.hidden & !iterationGridTwo.hidden) && (itemOneName.match(itemTwoName)) && !isInStringArray(itemOneName, disabledRefs)){
alert("itemOneName:"+itemOneName + "\nindexOne:" + indexOne + "\nitemTwoName:"+itemTwoName + "\nindexTwo:" + indexTwo);
var dp = displayPanel;

var firstRow = iterationGridOne.view.getRow(indexOne);
var secondRow = iterationGridTwo.view.getRow(indexTwo);
var fbcr = firstRow.getBoundingClientRect();
var sbcr = secondRow.getBoundingClientRect();

var lineDrawn;
var rectFirst;
var rectSecond;

//need to put in a if statement to check if its left or right
if(((fbcr.right - fbcr.left)/2) + fbcr.left < ((sbcr.right - sbcr.left)/2) + sbcr.left)
{
lineDrawn = paper.path("M"+(fbcr.right+10)+" "+(fbcr.bottom - 10)+"L"+ (sbcr.left-10) + " " + (sbcr.bottom - 10) );
// regular rectangle
rectFirst = paper.rect(fbcr.right, (fbcr.bottom - 11), 10, 2);
rectSecond = paper.rect((sbcr.left - 10) , (sbcr.bottom - 11), 10, 2);
}
else{
lineDrawn = paper.path("M"+(fbcr.left-10)+" "+(fbcr.bottom - 10)+"L"+ (sbcr.right+10) + " " + (sbcr.bottom - 10) );
rectFirst = paper.rect((fbcr.left - 10) , (fbcr.bottom - 11), 10, 2);
rectSecond = paper.rect(sbcr.right, (sbcr.bottom - 11), 10, 2);
}

//select bothe records in each grid and hit delete

var st = paper.set();
st.push(
lineDrawn,
rectFirst,
rectSecond
);

raphaelSetArray.push({
name:itemOneName,
rset:st
});
}
});
});
}
});
});
}

});