PDA

View Full Version : override Ext.dd.Registry



sntial
20 Nov 2010, 3:57 PM
I'm trying to override a few methods related to tree nodes and dragging. I don't have regular tree labels. They are HTML with images, etc.

I have the following overrides working properly:



Ext.override(Ext.tree.TreeNodeUI, {
onSelectedChange : function(state) {
if (state){
this.focus();
this.addClass("x-tree-selected");
// 20101120 MB - added this call to remove stale row selection colors
this.onOut(null);
} else {
//this.blur();
this.removeClass("x-tree-selected");
}
}
});

Ext.override(Ext.tree.TreeDragZone, {
onInitDrag : function(e) {
var data = this.dragData;
// 20101120 MB - removed next two calls - selection handled by controller
//this.tree.getSelectionModel().select(data.node);
//this.tree.eventModel.disable();
this.proxy.update("");
data.node.ui.appendDDGhost(this.proxy.ghost.dom);
this.tree.fireEvent("startdrag", this.tree, data.node, e);
}
});


I'd like to override Ext.dd.Registry.getHandleFromEvent as follows:



Ext.override(Ext.dd.Registry, {
getHandleFromEvent : function(e) {
var t = Ext.lib.Event.getTarget(e);
// 20101120 MB - added this while loop to handle tree labels with html children instead of raw text
while (!t.id && t.parentNode) {
t = t.parentNode;
}
return t ? handles[t.id] : null;
}
});


However, this does not take effect (working code below). I'm stuck with replacing the entire Ext.dd.Registry object. It seems like this object does not follow the standard Ext prototyping scheme. Am I missing something?



Ext.dd.Registry = function(){
var elements = {};
var handles = {};
var autoIdSeed = 0;

var getId = function(el, autogen){
if(typeof el == "string"){
return el;
}
var id = el.id;
if(!id && autogen !== false){
id = "extdd-" + (++autoIdSeed);
el.id = id;
}
return id;
};

return {

register : function(el, data){
data = data || {};
if(typeof el == "string"){
el = document.getElementById(el);
}
data.ddel = el;
elements[getId(el)] = data;
if(data.isHandle !== false){
handles[data.ddel.id] = data;
}
if(data.handles){
var hs = data.handles;
for(var i = 0, len = hs.length; i < len; i++){
handles[getId(hs[i])] = data;
}
}
},


unregister : function(el){
var id = getId(el, false);
var data = elements[id];
if(data){
delete elements[id];
if(data.handles){
var hs = data.handles;
for(var i = 0, len = hs.length; i < len; i++){
delete handles[getId(hs[i], false)];
}
}
}
},


getHandle : function(id){
if(typeof id != "string"){
id = id.id;
}
return handles[id];
},


getHandleFromEvent : function(e){
var t = Ext.lib.Event.getTarget(e);
// 20101120 MB - added this while loop to handle tree labels with html children instead of raw text
while (!t.id && t.parentNode) {
t = t.parentNode;
}
return t ? handles[t.id] : null;
},


getTarget : function(id){
if(typeof id != "string"){
id = id.id;
}
return elements[id];
},


getTargetFromEvent : function(e){
var t = Ext.lib.Event.getTarget(e);
return t ? elements[t.id] || handles[t.id] : null;
}
};
}();

brian.moeskau
21 Nov 2010, 12:43 PM
Yeah, you can't override a singleton using Ext.override, since there is no prototype to modify in this case. However, since Ext.dd.Registry is an instantiated object, you can simply override the method directly:


Ext.dd.Registry.getHandleFromEvent = function(e){
var t = Ext.lib.Event.getTarget(e);
// 20101120 MB - added this while loop to handle tree labels with html children instead of raw text
while (!t.id && t.parentNode) {
t = t.parentNode;
}
return t ? handles[t.id] : null;
};

sntial
21 Nov 2010, 12:58 PM
I have tried that already. The handles variable is undefined at runtime.

this.handles and Ext.dd.Registry.handles does not work either.

I'm thinking it's because the getHandleFromEvent method is in the return block instead of explicitly defined.

brian.moeskau
21 Nov 2010, 5:18 PM
Ah sorry, didn't notice that. If you need access to anything declared privately in the singleton's scope you're going to have to redeclare the entire thing just as you did. Not much way around that.

sntial
21 Nov 2010, 5:29 PM
Oh, right. It all makes sense now.

I guess it's just a little odd how this class was implemented (compared to the other ExtJs stuff I've overridden).

Thanks for the explanation. That was driving me crazy.

brian.moeskau
21 Nov 2010, 5:47 PM
It's implemented just like any other singleton. You'd run into the same type of issue overriding Ext.MessageBox, Ext.ComponentMgr, etc. if you needed access to their private scopes. If you just want to change the behavior and don't need to rely on anything in the private scope you can directly override methods on the singleton instance as I showed.

sntial
21 Nov 2010, 6:11 PM
Got it. Thanks.