PDA

View Full Version : Customized Drag and Drop from 2 Trees To Grid



mat33
24 May 2013, 6:47 AM
Can someone tell me if what I'm trying to do is possible or not in ExtJS 4?


Let's say as left panel I have a tab panel "TabPanel" with two tabs.
each tab is a tree: "UserTree" and "UserRightTree".
Then, we have a "Grid" as right panel.


Following ExtJS 4 documentation and examples, I understood how to drag and drop
a User from UserTree to the Grid. So that it creates a new row (with the fields: id, name and access) each time I drop a user on the grid.


Now I want from the second tab of "TabPanel" (so the tree "UserRightTree") to be able to drag and drop "One or More Items" to a precise Column of the Grid (e.g.: the column access).
So that it allows for each row of the Grid One or More Items (access right).


When drag n drop from "UserRightTree", I don't want to create a new row in the Grid.
Instead, I want to be able to DND (one or more "UserRightTree" tree items) to a precise Column of any existing row of the Grid



Is this possible as explained?
If yes, can you put me in the good direction to achieve this customized DnD from Tree1 to Grid Row and Tree2 to Column of the same Grid? a simple example would be very welcome :)


If it is not possible, what you advise me?
Should I replace the Grid by something else?
Would it change something if I was using a Tree instead of the Grid (e.g.: a multi column tree with same behaviour than explained above)


Thanks for your answer

slemmon
28 May 2013, 12:50 PM
I'm not sure I follow when you say dropping the record to a specific column of the destination grid. Do you mean if the user attempts to drop the record on the grid and they'r hovering over the approved column allow the drop and if they're not hovering over the approved column don't allow the record to be added?

mat33
3 Jun 2013, 2:07 PM
First case: from "User Tree" to "User Policy Grid"
when I drag a User from the Tab "User" to the Grid "User Policy Grid", I can drop it as a new row in the Grid (which is correct behaviour)
see
44159

and
44160


Second case: from "User Right Tree" to "User Policy Grid"
Here is what I want to do:
- When I drag an Access from the Tab "User Right" to the Grid, I want it to be dropable only on the column "Access Right" of the Grid:
44162

- I do Not want to create a new row like in first case, but instead add the item on the column access right of a specific user:
44161

- Furthermore, I want to be able to drag and drop one or more Access Right from the Tab "User Right" to a user of the grid:
44163


Do you think the second case as explained is something possible to do in ExtJS 4?
If yes, how should I code the Grid part to act differently regarding what "items" (user or access right) we drop on it?
How can I make the Grid and the column "access right" dropable when I drag an access right over it?

Thank for you help

mat33
4 Jun 2013, 2:21 AM
Hi slemmon,

yes, that's correct.
but I need the grid to work two ways:
- adding new row if user drop item from Tree 1 on the grid
- same as you said if user drop item from Tree 2 on the grid

as explained in the previous post (with screenshots)

slemmon
4 Jun 2013, 11:49 AM
Definitely possible, though may take just a little time studying how do just what you're looking to do. You might check out the example here:
http://docs.sencha.com/extjs/4.2.1/extjs-build/examples/build/KitchenSink/ext-theme-neptune/#dd-field-to-grid

If you pull that up in Chrome and check out all-classes.js in the sources tab in the Dev Tools and click on the pretty print (button that looks like: {}) then you can search for "Ext.ux.dd.CellFieldDropZone". Check out its onNodeEnter and onNodeDrop methods to see how it' handling allowing the drop only on certain cells.

mat33
11 Jun 2013, 1:28 AM
I looked at the Field to Grid Cell DnD (Drag n Drop) as you advised.
I tried couple of things linked with this DnD example and others available.
But at the end I wasn't able to adapt the code for my case :(


To be honest, I don't know what code I should add and where in order to DnD from Tree to Cell of the Grid.
(To allow a leaf of "User Right" tree to be dropped in a cell of an existing row of User Policy Grid; no row creation here)


Keeping in mind that I already have a Tree to Grid DnD defined from another Tree to the same destination Grid, as explained in previous posts (this DnD create rows in the Grid).
I want both DnD to work simultaneously.


Would be great to have a simple code example and explanation of what kind of code to add and where?
Does the new code has to be a plugin of User Policy Grid or may I use handlers or listeners (or combining both)?



Here is code I have at the moment for each part (data model, store and tree/grid):

code of "User" Tree (left panel 1)

//user data model
Ext.define('UserDataModel', {
extend: 'Ext.data.Model',
fields: ['id', 'login', 'name', 'leaf'],
//example: {"id": "af449205-3499-41de-ba53-d8a07deecdf5", "login": "user1", "name": "User Name 1", "leaf": true}
});


//store
var UserStore = Ext.create('Ext.data.TreeStore', {
id: 'user-store', model: 'UserDataModel', autoLoad: true, autoSync: true,
proxy: {
type: 'ajax',
url: 'lib/json/user_policy.json',
reader: {
type: 'json',
root: 'users'
}
}
});


//user tree
var UserTree = Ext.create('Ext.tree.Panel', {
id: 'user-tree',
store: UserStore,
displayField: 'login',
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop',
dragGroup: 'PolicyGridDDGroup',
//dropGroup: 'PolicyGridDDGroup',
allowContainerDrops: false,
},copy: true
}
});

code of "User Right" Tree (left panel 2)

//data model
Ext.define('UserRightDataModel', {
extend: 'Ext.data.Model',
fields: ['id', 'right', 'value', 'leaf']
//example: {"id": "8edced3d-a65c-4978-b796-5394ec1859c0", "name": "Access 1", "value": "All", "leaf": true}
});


//store
var UserRightStore = Ext.create('Ext.data.TreeStore', {
id: 'user-right-store', model: 'UserRightDataModel', autoLoad: true, autoSync: true,
proxy: {
type: 'ajax',
url: 'lib/json/user_policy.json',
reader: {
type: 'json',
root: 'rights'
}
}
});


//user access right tree
var UserRightTree = Ext.create('Ext.tree.Panel', {
id: 'user-right-tree',
store: UserRightStore,
displayField: 'right',
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop',
dragGroup: 'PolicyGridDDGroup',
//dropGroup: 'PolicyGridDDGroup',
allowContainerDrops: false,
},copy: true,
}
});

code of "User Policy Grid" (right panel)

//data model
Ext.define('PolicyDataModel', {
extend: 'Ext.data.Model',
fields: ['id', 'login', 'name', 'right', 'active', 'comment', 'leaf'],
//example: {"id": "029499f3-38bb-4d9d-bc96-46ba120c4fb2", "login": "user1", "name": "User Name 1", "right": "", "active": true, "leaf": true}
});


//store
var PolicyStore = Ext.create('Ext.data.Store', {
id: 'policy-store',
model: 'PolicyDataModel',
data: myData
});


//columns
var columns = [
{xtype: 'actioncolumn', width: 25, sortable: false, dataIndex: 'delete', menuDisabled: true, hideable: true,
items: [{
iconCls: 'icon-delete', tooltip: 'Delete this row',
handler: function(grid, rowIndex){ PolicyStore.removeAt(rowIndex); }
}]
},
//{header: "id", width: 250, sortable: true, dataIndex: 'id'},
{header: "Login", width: 100, sortable: true, dataIndex: 'login'},
{header: "User Name", width: 150, sortable: true, dataIndex: 'name'},
{header: "Access Right", width: 150, sortable: true, dataIndex: 'right'},
{header: "Active", width: 65, sortable: true, dataIndex: 'active', xtype: 'checkcolumn', default: true},
{header: "Comment", width: 400, sortable: true, dataIndex: 'comment', editor: {allowBlank: true}}
];


//user policy grid
var PolicyGrid = Ext.create('Ext.grid.Panel', {
id: 'policy-grid', multiSelect: true, stripeRows: true,
store: PolicyStore,
columns: columns,
viewConfig: {
plugins: {
ptype: 'gridviewdragdrop',
dragGroup: 'PolicyGridDDGroup',
dropGroup: 'PolicyGridDDGroup'
},
listeners: {
beforedrop: function(node, data, overModel, dropPosition, dropFunction) {


//catch the source store
var ItemFromStoreId = data.records[0].store.storeId;


switch (ItemFromStoreId) {
case PolicyStore.storeId: console.log('item drag from Policy Grid'); break;
case UserStore.storeId: console.log('item drag from User Tree'); break;
case UserRightStore.storeId: console.log('item drag from User Right Tree'); break;
}


if (data.records[0].get('leaf')) { dropFunction.cancelDrop(); } //Cancel drop when item is a folder not a leaf
else { dropFunction.processDrop(); } //drop the item (node) in the grid
},


drop: function(node, data, dropRec, dropPosition) {
var dropOn = dropRec ? ' ' + dropPosition + ' ' + dropRec.get('login') : ' on empty view';
},
},
plugins: Ext.create('Ext.grid.plugin.CellEditing', {xtype: 'cell-editing', clicksToEdit: 1})
});

Any help is very welcome :)

mat33
17 Jun 2013, 12:10 AM
Hi,

I tried couple of more things, but I can't say I made any real progress :(


I think the main problem I am facing is that the grid has to work two ways at the same time or simultaneously, which are:


- create a new row in the Grid when an item is dragged from Tree 1 (User Tree) and dropped over the Grid
- add info in a specific Cell of the Grid (no row created) when an item is dragged from Tree 2 (User Right Tree) and dropped over the corresponding Cell of the Grid


latest things I tried were:
- have the 2 Drag and Drop behaviours working at the same time using different dragGroup for the Trees
and playing with ddGroup or dropGroup with the Grid (which seems quite impossible?)
- to change dynamically the behaviour of the Grid regarding which Tree is active (User or UserRight Tree)
for this test, I tried to change the Grid "selType" dynamically from "rowmodel" to "cellmodel".
which basically works if I track this value using console.log(). But the result is not good and the Grid kind of bogus after that.


I read ExtJs 4 documentation about Grid and Drag and Drop.
But to achieve what I want, I didn't help me so far :(


Any chance to get little help on this?