Extjs Combo Tree

网上找了半天,找到一个好用的,改了一行代码 使用xtype来创建tree

原文地址

http://penggle.iteye.com/blog/803338

效果图

{
            xtype:'xcomboboxtree',
            fieldLabel: '选择部门',
            width:120,
            tree:{
                width:210,
                height:220,
                autoScroll:true,
                xtype:'unittree',
                url:'/logic/UnitHandler.ashx?f=ExpanUnitUserTree',
                margins:'0 5',
                border:true,
                rootVisible:false,
                roottext: '选择授权用户'
            }
        },

tree源代码

Ext.ns("XG.Control.ComboBoxTree");
XG.Control.ComboBoxTree = Ext.extend(Ext.form.TwinTriggerField,{
    animate : {easing:'easeIn',duration:0.75},
    defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"},
    editable : false,
    enableClearValue : false,
    hiddenValue : '',
    displayValue : '',
    listWidth : undefined,
    listHeight : undefined,
    maxListHeight : 225,
    minListWidth : 70,
    handleHeight : 8,
    listClass : '',
    selectedClass : 'x-combo-selected',
    shadow : 'sides',
    listAlign : 'tl-bl?',
    listEmptyText : '',
    resizable : false,
    trigger1Class : 'x-form-clear-trigger',
    hideTrigger1 : true,
    trigger2Class : 'x-form-arrow-trigger',
    initComponent : function(){
        this.addEvents(
            'expand',
            'collapse',
            'treenodeselect',
            'beforecollapse',
            'beforeexpand',
            'clearvalue'
        );
        XG.Control.ComboBoxTree.superclass.initComponent.call(this);
        this.tree=Ext.create(this.tree);
        this.tree.height = Ext.isDefined(this.tree.height) ? this.tree.height : this.listHeight;
        this.tree.autoHeight = false;
        this.tree.autoScroll = true;
        this.tree.containerScroll = true;
        this.tree.border = false;
        this.tree.root.expanded = !Ext.isDefined(this.tree.height) ? true : this.tree.root.expanded;
        this.tplId = Ext.id();
        this.tpl = '<div id="'+this.tplId+'"></div>';
        this.onTrigger2Click = this.onTriggerClick;
        this.onTrigger1Click = this.clearValue;
    },
    onRender : function(ct, position){
        if(this.hiddenName && !Ext.isDefined(this.submitValue)){
            this.submitValue = false;
        }
        XG.Control.ComboBoxTree.superclass.onRender.call(this,ct,position);
        if(this.hiddenName){
            var formItem = this.el.findParent('.x-form-item',4,true);
            if(formItem){
                this.hiddenField = formItem.insertSibling({tag:'input', type:'hidden', name: this.hiddenName,
                        id: (this.hiddenId||this.hiddenName)}, 'after', true);  
                var hf = new Ext.form.Hidden({applyTo:this.hiddenField});
                var basicForm = this.getOwnerForm(this);
                if(basicForm){
                    basicForm.add(hf);
                }
            }else{
                this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName,
                    id: (this.hiddenId||this.hiddenName)}, 'before', true);
            }
        }
        if(Ext.isGecko){
            this.el.dom.setAttribute('autocomplete', 'off');
        }
        this.initList();
    },
    initList : function(){
        if(!this.list){
            var cls = 'x-combo-list',
                listParent = Ext.getDom(this.getListParent() || Ext.getBody()),
                zindex = parseInt(Ext.fly(listParent).getStyle('z-index'), 10);
            if (!zindex) {
                zindex = this.getParentZIndex();
            }
            this.list = new Ext.Layer({
                parentEl: listParent,
                shadow: this.shadow,
                cls: [cls, this.listClass].join(' '),
                constrain:false,
                zindex: (zindex || 12000) + 5
            });
            var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
            this.list.setSize(lw, 0);
            this.tree.width = lw - 1;
            this.list.swallowEvent('mousewheel');
            this.assetHeight = 0;
            if(this.syncFont !== false){
                this.list.setStyle('font-size', this.el.getStyle('font-size'));
            }
            if(this.title){
                this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
                this.assetHeight += this.header.getHeight();
            }
            this.innerList = this.list.createChild({cls:cls+'-inner'});
            this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
            this.view = new Ext.DataView({
                applyTo: this.innerList,
                tpl: this.tpl,
                singleSelect: true,
                selectedClass: this.selectedClass,
                itemSelector: this.itemSelector || '.' + cls + '-item',
                emptyText: this.listEmptyText,
                deferEmptyText: false,
                listeners: {
                    'afterrender' : function(){
                        this.tpl.overwrite(this.el,[]);
                    }
                }
            });
            this.mon(this.view, {
                containerclick : this.onViewClick,
                click : this.onViewClick,
                scope :this
            });
            if(this.resizable){
                this.resizer = new Ext.Resizable(this.list,  {
                   pinned:true, handles:'se'
                });
                this.mon(this.resizer, 'resize', function(r, w, h){
                    this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
                    this.listWidth = w;
                    this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
                    this.restrictHeight();
                }, this);
            }
        }
    },
    initEvents : function(){
        XG.Control.ComboBoxTree.superclass.initEvents.call(this);
        this.tree.on({
            scope:this,
            'render' : function(){
                this.tree.getTreeEl().on('click',function(e,t,o){
                    if(e.getTarget('.x-tree-ec-icon', 1)){//is click tree's collapse/expand trigger icon area?
                        this.isTreeNodeClicked = false;
                    }else{
                        this.isTreeNodeClicked = true;
                    }
                },this);
            },
            'click' : function(n,e){
                if(this.enableClearValue){
                    this.triggers[0].show();
                }
                this.setValue(n.text);
                if(this.hiddenField){
                    this.setHiddenValue(Ext.value(n.id,''));
                }
                this.fireEvent('treenodeselect',this,n,e);
            }
        });
        this.tree.root.on({
            scope:this,
            'expand' : {
                fn : function(){
                    if(!Ext.isDefined(this.tree.height)){//dropdown list auto height
                        this.restrictHeight();
                    }
                },
                single: true
            }
        });
        this.on({
            'beforecollapse' : {
                fn : function() {
                    if(!this.isExpanded()){
                        return;
                    }
                    return this.isTreeNodeClicked;
                }
            },
            'beforedestroy' : {
                fn : function() {
                    this.purgeListeners();
                    this.tree.purgeListeners();   
                }   
            },
            'beforeexpand' : {
                fn : function() {
                    if(this.tree.rendered && !this.tree.getRootNode().isExpanded()){
                        this.tree.getRootNode().expand(false,true);
                    } 
                },   
                single : true
            },
            'focus' : {
                fn : function(){
                    if (!this.tree.rendered && this.tplId) {
                        this.tree.render(this.tplId);
                    }
                },
                single : true
            }
        });
    },
    initValue : function(){
        XG.Control.ComboBoxTree.superclass.initValue.call(this);
        if(this.hiddenField){
            this.setHiddenValue(Ext.value(Ext.isDefined(this.hiddenValue) ? this.hiddenValue : this.value, ''));
        }
    },
    getOwnerForm : function(c){
        var formPanel = this.findDirectFormOwnerCt(c);
        if(formPanel && formPanel.getForm()){
            return formPanel.getForm();
        }else{
            return null;
        }
    },
    findDirectFormOwnerCt : function(c){
        if(c.ownerCt){
            if(c.ownerCt.getXType() == 'form'){
                return c.ownerCt;
            }else{
                return this.findDirectFormOwnerCt(c.ownerCt);
            }
        }else{
            return null;
        }
    },
    getListParent : function(){
        return document.body;
    },
    getParentZIndex : function(){
        var zindex;
        if (this.ownerCt){
            this.findParentBy(function(ct){
                zindex = parseInt(ct.getPositionEl().getStyle('z-index'), 10);
                return !!zindex;
            });
        }
        return zindex;
    },
    restrictHeight : function(){
        this.innerList.dom.style.height = '';
        var inner = this.innerList.dom,
            pad = this.list.getFrameWidth('tb') + (this.resizable ? this.handleHeight : 0) + this.assetHeight,
            h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight),
            ha = this.getPosition()[1]-Ext.getBody().getScroll().top,
            hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height,
            space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadowOffset-pad;

        h = Math.min(h, space, this.maxListHeight);
    
        this.innerList.setHeight(h);
        this.list.beginUpdate();
        this.list.setHeight(h+pad);
        this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
        this.list.endUpdate();
    },
    isExpanded : function(){
        return this.list && this.list.isVisible();
    },
    onViewClick : function(doFocus){
        var index = this.view.getSelectedIndexes()[0];
        if(!index){
            this.collapse();
        }
        if(doFocus == true){
            this.el.focus();
        }
    },
    onDestroy : function(){
        Ext.destroy(
            this.resizer,
            this.view,
            this.list
        );
        Ext.destroyMembers(this, 'hiddenField');
        XG.Control.ComboBoxTree.superclass.onDestroy.call(this);
    },
    setValue : function(val){
        val = Ext.value(val,'');
        if(val != ''){
            if(this.enableClearValue){
                this.triggers[0].show();
            }
        }else{
            if(this.enableClearValue){
                this.triggers[0].hide();
            }
        }
        XG.Control.ComboBoxTree.superclass.setValue.call(this,val);
    },
    setHiddenValue : function(val){
        val = Ext.value(val,'');
        if(val != ''){
            if(this.enableClearValue){
                this.triggers[0].show();
            }
        }else{
            if(this.enableClearValue){
                this.triggers[0].hide();
            }
        }
        if(this.hiddenField){
            this.hiddenField.value = val;
            this.value = val;
        }
        return this;
    },
    reset : function(){
        XG.Control.ComboBoxTree.superclass.reset.call(this);
        if(this.hiddenField){
            this.setHiddenValue('');
        }
    },
    clearValue : function(){
        if(this.enableClearValue){
            var v = this.value;
            if(this.hiddenField){
                v = this.hiddenField.value;
                this.hiddenField.value = '';
            }
            this.setValue('');
            this.validate();
            this.fireEvent('clearvalue', this, v);
        }
    },
    getTree : function(){
        return this.tree;
    },
    getValue : function(){
        if(this.hiddenField){
            return Ext.isDefined(this.value) ? this.value : '';
        }else{
            return Ext.form.ComboBox.superclass.getValue.call(this);
        }
    },
    collapse : function(){
        if(!this.isExpanded()){
            return;
        }
        
        if(this.enableClearValue && Ext.value(this.value,'') != ''){
            this.triggers[0].show();
        }
        
        if(this.fireEvent('beforecollapse',this) !== false){
            this.list.hide();
            Ext.getDoc().un('mousewheel', this.collapseIf, this);
            Ext.getDoc().un('mousedown', this.collapseIf, this);
            this.fireEvent('collapse', this);
        }
        
    },
    expand : function(){
        if(this.isExpanded() || !this.hasFocus){
            return;
        }
        if(this.fireEvent('beforeexpand', this) !== false){

            this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
    
            // zindex can change, re-check it and set it if necessary
            var listParent = Ext.getDom(this.getListParent() || Ext.getBody()),
                zindex = parseInt(Ext.fly(listParent).getStyle('z-index') ,10);
            if (!zindex){
                zindex = this.getParentZIndex();
            }
            if (zindex) {
                this.list.setZIndex(zindex + 5);
            }
            
            this.triggers[0].hide();

            this.list.show(this.animate);
            
            if(Ext.isGecko2){
                this.innerList.setOverflow('auto'); // necessary for FF 2.0/Mac
            }
            this.mon(Ext.getDoc(), {
                scope: this,
                mousewheel: this.collapseIf,
                mousedown: this.collapseIf
            });
            
            this.fireEvent('expand', this);
        }
    },
    collapseIf : function(e){
        if(this.isExpanded() && !this.isDestroyed && !e.within(this.wrap) && !e.within(this.list)){
            this.isTreeNodeClicked = true;
            this.collapse();
        }
    },
    onTriggerClick : function(e){
        if(e.getTarget('#' + this.el.id, 1)){
            return;
        }
        if(this.readOnly || this.disabled){
            return;
        }
        if(this.isExpanded()){
            this.collapse();
            this.el.focus();
        }else {
            this.onFocus({});
            this.expand();
            this.restrictHeight();
            this.el.focus();
        }
    },
    updateEditState: function(){
        if(this.rendered){
            if (this.readOnly) {
                this.el.dom.readOnly = true;
                this.el.addClass('x-trigger-noedit');
                this.mun(this.el, 'click', this.onTriggerClick, this);
            } else {
                if (!this.editable) {
                    this.el.dom.readOnly = true;
                    this.el.addClass('x-trigger-noedit');
                    this.mon(this.el, 'click', this.onTriggerClick, this);
                } else {
                    this.el.dom.readOnly = false;
                    this.el.removeClass('x-trigger-noedit');
                    this.mun(this.el, 'click', this.onTriggerClick, this);
                }
                this.trigger.setDisplayed(!this.hideTrigger);
            }
            this.onResize(this.width || this.wrap.getWidth());
        }
    }
});
Ext.reg('xcomboboxtree',XG.Control.ComboBoxTree);

 

发表评论

邮箱地址不会被公开。 必填项已用*标注