'Extjs 4.x Grid drag and drop records with parent-child relation
I have created a Extjs (4.X) grid which has records of parents and childrens. The records are in sorted order where in the childrens always appear just below their parents as shown here, where 'P' designates a record as parent while 'C' designates a record as children.
'May' is the parent of Peter, Odin is the parent of Thor and Loki, Bruce has no children yet marked as Parent (standalone entity)
I wish to change sort order of only the parents while also bringing their childrens along when I drag and drop records within the grid. I have progressed upto a point where I am able to allow only a parent to be able to drag while disallowing a children to be moved moved around. For example if I hold the record 'May Parker', it should be allowed to drop after record Loki, the last child of a parent OR a row before another parent OR after the last row in the grid. I have created a fiddle which works for below cases:
1> Allow movement of only a parent record.
2> Disallow a parent to move if the record that was traversed was a Child. (nodeOver record is a child).
3> Allow a parent to drop if the node over is a child but it is the last row.
The <3> doesnt work right because the nodeOver index gives me last index of the grid regardless of whether I place the Parent either after last row or before the last row.
I have used an override as below:
Ext.override(Ext.view.DropZone, {
onNodeOver: function(nodeData, source, e, data) {
if (data && data.records && data.records[0]) {
// The check should be better specified, e.g. a
// female with the name 'Malena' would be recognized as male!
//debugger;
console.log(this.view.getStore().data.items[nodeData.rowIndex].data);
console.log(data.records[0].data.type);
// debugger;
console.log(nodeData.rowIndex +" Hello "+this.view.getStore().data.length);
if (data.records[0].data.type.localeCompare('P') != 0 || (
this.view.getStore().data.items[nodeData.rowIndex].data.type.localeCompare(' C') == 0 &&
nodeData.rowIndex != (this.view.getStore().data.length -1 ) ) ) {
return this.dropNotAllowed;
}
}
return this.callOverridden([nodeData, source, e, data]);
},
onContainerOver: function(source, e, data) {
return this.dropNotAllowed;
}
});
Here is the fiddle of my progress so far: https://fiddle.sencha.com/#view/editor&fiddle/3ji3
Much appreciated if someone can point me in the right direction for below items
1> How do I club parent and its childrens so that drag and drop clubs and moves all of them?
3> How do I ensure that parents cannot be dropped between another parent and its childrens ?
Please ignore the Ranking provided for the child records, in real world scenario I intend to provide ranking only for the parent records and for childrens it will be empty.
Solution 1:[1]
This is better achieved with a treepanel, like: https://examples.sencha.com/extjs/6.2.0/examples/kitchensink/#tree-reorder Works since Ext 2.0. You can D&D any branch (parent) and all the leaves (children) will travel with it.
Solution 2:[2]
Here is a working example of your grid-group-header.
The main work is to add a listener to groupmousedown
and update the eventlistener:
grid.mon(grid, {
scope: me,
groupmousedown: me.onGroupMouseDown
});
onGroupMouseDown: function(view, item, groupName, e) {
if (e.pointerType === 'mouse') {
var groupFeature = view.findFeature('grouping'),
group = groupFeature.getGroup(groupName),
selectionModel = view.getSelectionModel();
selectionModel.select(group.items);
this.onTriggerGesture(view, group.items, item, null, e);
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Arthur |
Solution 2 | Dinkheller |