1. #1
    Sencha Premium Member
    Join Date
    Apr 2009
    Posts
    104
    Vote Rating
    0
    jej2003 is on a distinguished road

      0  

    Default Combobox with a Tree

    Combobox with a Tree


    I've found several examples of how to place a tree into a combobox and I've successfully set this up in my webapp. The question I now have is how to make it automatically size up to some maxHeight, show scroll bars if necessary like the BoundList does for the combobox. Can anyone provide an example of how that can be accomplished?

  2. #2
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,490
    Vote Rating
    283
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      0  

    Default


    Here's my first attempt at it. It relies on CSS auto-sizing so you have very little control. To do max-height you'd need to use CSS and IE6 won't like that. I've also turned off the shadow as it's tricky to resize it (you could monitor expand/collapse events).

    The nice thing about this approach is is handles the tree's animations automatically. Trying to do the sizing manually gives you much more control but makes the animations difficult to handle.

    Code:
    Ext.create('Ext.form.field.Picker', {    
        createPicker: function() {
            return Ext.create('Ext.tree.Panel', {
                floating: true,
                hidden: true,
                shadow: false,
                root: {
                    expanded: true,
                    text: 'Root',
                    children: [
                        ...
                    ]
                },
                listeners: {
                    show: {
                        delay: 10,
                        fn: function(tree) {
                            tree.getEl().setStyle('height', 'auto');
                            tree.body.setStyle('height', 'auto');
                            tree.getView().getEl().setStyle('height', 'auto');
                        }
                    }
                }
            });
        }
    });

  3. #3
    Sencha Premium Member
    Join Date
    Apr 2009
    Posts
    104
    Vote Rating
    0
    jej2003 is on a distinguished road

      0  

    Default


    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);
                }
            }
        },

Thread Participants: 1