Thanks skirtle, this was close but a key missing is the maxHeight constraint and showing scroll bars. I put together something that works pretty well, but it just feels wrong. So basically I listen for item expand and collapse events, when those happen I check to see if there are any animations occurring if so I call this function again with a delay. If there aren't any I call do layout on my panel. This works but I need to use a private method on view (isAnimating) to see if the animation is done or not. It would be nicer if I could figure out a way to hook into some after expand method which completes when the node is finished animating. Either way here is what I did, any comments/improvements would be appreciated
Code:
createPicker : function() {
var self = this;
self.picker = new Ext.container.Container({
maxHeight : 150,
layout : 'fit',
autoScroll : true,
floating : true,
resizable: false,
focusOnToFront : false,
shadow : true,
ownerCt : this.ownerCt,
useArrows : true,
items : new Ext.tree.Panel({
displayField : this.displayField,
autoScroll : true,
resizable: false,
useArrows : true,
store : self.store,
rootVisible : false,
listeners:{
scope:this,
select:this.valueSelected,
itemexpand: Ext.Function.createDelayed(this.onItemExpand, 100),
itemcollapse: Ext.Function.createDelayed(this.onItemExpand, 100)
}
})
});
return self.picker;
},
onItemExpand : function(node){
var view = this.picker.down('treeview');
if(view.isAnimating(node)){
Ext.Function.createDelayed(this.onItemExpand, 100).call(this, node);
return true;
}
this.picker.doLayout();
return true;
},
alignPicker : function() {
// override the original method because otherwise the height of the treepanel would be always 0
var me = this, picker, isAbove, aboveSfx = '-above';
var scrollOffset = 0;
if (this.isExpanded) {
picker = me.getPicker();
if (me.matchFieldWidth) {
// Auto the height (it will be constrained by min and max width) unless there are no records to display.
if (me.bodyEl.getWidth() > this.treeWidth){
if(picker.el.getHeight() < picker.maxHeight)
scrollOffset = 15;
picker.setWidth(me.bodyEl.getWidth() + scrollOffset);
} else picker.setWidth(this.treeWidth);
}
if (picker.isFloating()) {
picker.alignTo(me.inputEl, "", me.pickerOffset);// ""->tl
// // add the {openCls}-above class if the picker was aligned above the field due to hitting the bottom of the viewport
isAbove = picker.el.getY() < me.inputEl.getY();
me.bodyEl[isAbove ? 'addCls' : 'removeCls'](me.openCls
+ aboveSfx);
picker.el[isAbove ? 'addCls' : 'removeCls'](picker.baseCls
+ aboveSfx);
picker.el.shadow.el.setWidth(picker.el.shadow.el.getWidth() - scrollOffset);
}
}
},