Supergibbs
19 Dec 2009, 2:32 AM
I have a tree with some draggable nodes. When I move a node, I handle the movenode event to store the move in our database via an ajax call. If for some reason the ajax call fails I want to undo the move. Currently I do it like this:
tree.on('movenode', function (tree, node, oldParent, newParent, index) {
$.ajax({
method: 'GET',
url: '/Tree/Move',
data: {
node: node.id,
oldParentId: oldParent.id,
newParentId: newParent.id
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
newParent.removeChild(node);
oldParent.appendChild(node);
oldParent.expand();
}
});
});
I first call "newParent.removeChild(node);" so the movenode event doesn't fire again but the side effect is that the indentation is messed up. I've fixed that by adding:
node.getUI().renderIndent(); //HACK - private method useThis works but is a hack. So is there a better way to do this or is my original code OK and the indentation problem is a bug? If my original code is OK, I think the problem is in Ext.tree.TreeNode.appendChild(node), the following override fixes it (changes in red):
Ext.override(Ext.tree.TreeNode, {
appendChild: function (node) {
var multi = false;
if (Ext.isArray(node)) {
multi = node;
} else if (arguments.length > 1) {
multi = arguments;
}
if (multi) {
for (var i = 0, len = multi.length; i < len; i++) {
this.appendChild(multi[i]);
}
} else {
if (this.fireEvent("beforeappend", this.ownerTree, this, node) === false) {
return false;
}
var index = this.childNodes.length;
var oldParent = node.parentNode;
if (oldParent) {
if (node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false) {
return false;
}
oldParent.removeChild(node);
}
index = this.childNodes.length;
if (index === 0) {
this.setFirstChild(node);
}
this.childNodes.push(node);
node.parentNode = this;
var ps = this.childNodes[index - 1];
if (ps) {
node.previousSibling = ps;
ps.nextSibling = node;
} else {
node.previousSibling = null;
}
node.nextSibling = null;
this.setLastChild(node);
node.setOwnerTree(this.getOwnerTree());
this.fireEvent("append", this.ownerTree, this, node, index);
if (oldParent) {
node.fireEvent("move", this.ownerTree, node, oldParent, this, index);
}
else {
node.ui.renderIndent();
}
return node;
}
}
});
Thanks!
tree.on('movenode', function (tree, node, oldParent, newParent, index) {
$.ajax({
method: 'GET',
url: '/Tree/Move',
data: {
node: node.id,
oldParentId: oldParent.id,
newParentId: newParent.id
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
newParent.removeChild(node);
oldParent.appendChild(node);
oldParent.expand();
}
});
});
I first call "newParent.removeChild(node);" so the movenode event doesn't fire again but the side effect is that the indentation is messed up. I've fixed that by adding:
node.getUI().renderIndent(); //HACK - private method useThis works but is a hack. So is there a better way to do this or is my original code OK and the indentation problem is a bug? If my original code is OK, I think the problem is in Ext.tree.TreeNode.appendChild(node), the following override fixes it (changes in red):
Ext.override(Ext.tree.TreeNode, {
appendChild: function (node) {
var multi = false;
if (Ext.isArray(node)) {
multi = node;
} else if (arguments.length > 1) {
multi = arguments;
}
if (multi) {
for (var i = 0, len = multi.length; i < len; i++) {
this.appendChild(multi[i]);
}
} else {
if (this.fireEvent("beforeappend", this.ownerTree, this, node) === false) {
return false;
}
var index = this.childNodes.length;
var oldParent = node.parentNode;
if (oldParent) {
if (node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false) {
return false;
}
oldParent.removeChild(node);
}
index = this.childNodes.length;
if (index === 0) {
this.setFirstChild(node);
}
this.childNodes.push(node);
node.parentNode = this;
var ps = this.childNodes[index - 1];
if (ps) {
node.previousSibling = ps;
ps.nextSibling = node;
} else {
node.previousSibling = null;
}
node.nextSibling = null;
this.setLastChild(node);
node.setOwnerTree(this.getOwnerTree());
this.fireEvent("append", this.ownerTree, this, node, index);
if (oldParent) {
node.fireEvent("move", this.ownerTree, node, oldParent, this, index);
}
else {
node.ui.renderIndent();
}
return node;
}
}
});
Thanks!