So I’ve been doing some work with the ExtJS tree for the past few days.
Day one – Getting the basic tree to work reading data from my api.. magic.
Day two – updating that data using drag’n'drop from two grids of data -Separate post coming soon on this bee tee dub- a bit hellish, documentation isn’t very clear, a lot of googling and finding various answers, none of which are fully correct.
Day three – Start fixing all the drag states and structure quirks when you are not doing a simple like for like model copy. Nightmare. This also brought up something that looked like it should have been straightforward.
TreeViewDragDrop plugin has a config according to the latest documentation (4.0.7) that says ‘allowContainerDrop’ Basically if you have gone outside of a node on the tree, but still inside the container which holds the tree, you should accept the drop request and append it to the tree. At least thats what I assume it’s meant to do from reading the documentation. Doesn’t work. Long story short, it’s not been implemented and the docs are wrong. The real property has a ‘s’ at the end. ‘allowContainerDrops’ not that it matters as it does nowt.
Anyway thats my rant over as fixing it was thankfully not too difficult thanks to the trusty Ext.override function.
Ext.override(Ext.tree.ViewDropZone, {
onContainerOver : function(dd, e, data) {
var defaultCls = this.dropNotAllowed;
if (this.allowContainerDrops)
defaultCls = this.dropAllowed;
return e.getTarget('.' + this.indicatorCls) ? this.currentCls : defaultCls;
},
getPosition: function(e, node) {
var view = this.view,
record = view.getRecord(node),
y = e.getPageY(),
noAppend = record.isLeaf(),
noBelow = false,
region = Ext.fly(node).getRegion(),
fragment;
// If we are dragging on top of the root node of the tree, we always want to append.
if (record.isRoot()) {
return 'append';
}
// Return 'append' if the node we are dragging on top of is not a leaf else return false.
if (this.appendOnly) {
return noAppend ? false : 'append';
}
if (!this.allowParentInsert) {
noBelow = record.hasChildNodes() && record.isExpanded();
}
fragment = (region.bottom - region.top) / (noAppend ? 2 : 3);
if (y >= region.top && y < (region.top + fragment)) {
return 'before';
}
else if (!noBelow && (noAppend || (y >= (region.bottom - fragment) && y <= region.bottom))) {
return 'after';
}
else if (this.allowContainerDrops && (y >= region.bottom)) {
return 'after';
}
else {
return 'append';
}
}
});
Ext.override(Ext.view.DropZone, {
// The mouse is past the end of all nodes (or there are no nodes)
onContainerOver : function(dd, e, data) {
var me = this,
view = me.view,
count = view.store.getCount();
// There are records, so position after the last one
if (count) {
me.positionIndicator(view.getNode(count - 1), data, e);
}
// No records, position the indicator at the top
else {
delete me.overRecord;
delete me.currentPosition;
me.getIndicator().setWidth(Ext.fly(view.el).getWidth()).showAt(0, 0);
me.valid = true;
}
return me.dropAllowed;
},
getTargetFromEvent : function(e) {
var node = e.getTarget(this.view.getItemSelector()),
mouseY, nodeList, testNode, i, len, box;
// Not over a row node: The content may be narrower than the View's encapsulating element, so return the closest.
// If we fall through because the mouse is below the nodes (or there are no nodes), we'll get an onContainerOver call.
if (!node) {
mouseY = e.getPageY();
for (i = 0, nodeList = this.view.getNodes(), len = nodeList.length; i < len; i++) {
testNode = nodeList[i];
box = Ext.fly(testNode).getBox();
if (mouseY <= box.bottom) {
return testNode;
}
}
if (this.allowContainerDrops) {
return nodeList[nodeList.length - 1];
}
}
return node;
}
});Looks an impressive fix, doesn’t it.. It’s not, a most of it is the original code with the statements added in to actually do something when allowContainerDrops = true.
Being very new to the toolkit I’m sure I’ve got something wrong here, but hey it’s working for me on version 4.0.7 and assumes that the container space is always on the bottom of the tree.
Even with it’s flaws, I’m still loving working with ExtJS and the pleasure is outweighing the pain at the moment. Maybe that will change as we start to do more complex work with it. Who knows. I hope not though.
Over and out
