zoukankan      html  css  js  c++  java
  • ExtJS Form扩展组件[ColorFiled, DateTimeFiled, IconCombo, MultiComboBox, DynamicTreeCombox]

    支持Form颜色选择组件、日期时间选择组件、带图标的下拉列表、多选下来列表、动态下拉列表树等组件

    开发环境:

    System:Windows

    WebBrowser:IE6+、Firefox3+

    JavaEE Server:tomcat5.0.2.8、tomcat6

    IDE:eclipse、MyEclipse 8

    开发依赖库:

    JavaEE5、ext 2.2.2

    Email:hoojo_@126.com

    Blog:http://blog.csdn.net/IBM_hoojo

    http://hoojo.cnblogs.com/

     

    一、ColoFieldr组件

    可以选择一些常用的颜色

    clip_image001

    需要用到的文件

    ColorField组件文件:Ext.form.ColorField.js

    ColorField运行示例文件:Ext.hoo.for.ColorField.js

    代码如下

    Color.html

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
        <head>
            <title>form Component -- DateTimeField</title>
            <meta http-equiv="pragma" content="no-cache"/>
            <meta http-equiv="cache-control" content="no-cache"/>
            <meta http-equiv="expires" content="0"/>
            <meta http-equiv="content-Type" content="text/html; charset=utf-8"/>
            <meta http-equiv="author" content="hoojo"/>
            <meta http-equiv="email" content="hoojo_@126.com"/>
            <meta http-equiv="ext-lib" content="version 2.2"/>
            <meta http-equiv="blog" content="http://blog.csdn.net/IBM_hoojo"/>        
            <link rel="stylesheet" type="text/css" href="../ext2/resources/css/ext-all.css"/>
            <script type="text/javascript" src="../ext2/adapter/ext/ext-base.js"></script>
            <script type="text/javascript" src="../ext2/ext-all.js"></script>
            <script type="text/javascript" src="../ext2/build/locale/ext-lang-zh_CN-min.js"></script>
            <script type="text/javascript" src="Ext.form.ColorField.js"></script>
            <script type="text/javascript" src="Ext.hoo.for.ColorField.js"></script>
      </head>
      
      <body>
          <div id="show" style="float: left; margin: 100px 0 0 100px;"></div>
      </body>
    </html>

    Ext.form.ColorField.js

    /**
     * @class Ext.form.ColorField
     * @extends Ext.form.TriggerField
     * Provides a very simple color form field with a ColorMenu dropdown.
     * Values are stored as a six-character hex value without the '#'.
     * I.e. 'ffffff'
     * @constructor
     * Create a new ColorField
     * <br />Example:
     * <pre><code>
    var cf = new Ext.form.ColorField({
        fieldLabel: 'Color',
        hiddenName:'pref_sales',
        showHexValue:true
    });
    </code></pre>
     * @param {Object} config
     */
    Ext.form.ColorField = function(config){
        Ext.form.ColorField.superclass.constructor.call(this, config);
        //this.on('render', this.handleRender);
    };
     
    Ext.extend(Ext.form.ColorField, Ext.form.TriggerField,  {
        /**
         * @cfg {Boolean} showHexValue
         * True to display the HTML Hexidecimal Color Value in the field
         * so it is manually editable.
         */
        showHexValue : false,
        
        /**
         * @cfg {String} triggerClass
         * An additional CSS class used to style the trigger button.  The trigger will always get the
         * class 'x-form-trigger' and triggerClass will be <b>appended</b> if specified (defaults to 'x-form-color-trigger'
         * which displays a calendar icon).
         */
        triggerClass : 'x-form-color-trigger',
        
        /**
         * @cfg {String/Object} autoCreate
         * A DomHelper element spec, or true for a default element spec (defaults to
         * {tag: "input", type: "text", size: "10", autocomplete: "off"})
         */
        // private
        defaultAutoCreate : {tag: "input", type: "text", size: "10",
                             autocomplete: "off", maxlength:"6"},
        
        /**
         * @cfg {String} lengthText
         * A string to be displayed when the length of the input field is
         * not 3 or 6, i.e. 'fff' or 'ffccff'.
         */
        lengthText: "Color hex values must be either 3 or 6 characters.",
        
        //text to use if blank and allowBlank is false
        blankText: "Must have a hexidecimal value in the format ABCDEF.",
        
        /**
         * @cfg {String} color
         * A string hex value to be used as the default color.  Defaults
         * to 'FFFFFF' (white).
         */
        defaultColor: 'FFFFFF',
        
        maskRe: /[a-f0-9]/i,
        // These regexes limit input and validation to hex values
        regex: /[a-f0-9]/i,
     
        //private
        curColor: 'ffffff',
        initComponent:function(){   
            Ext.form.ColorField.superclass.initComponent.call(this);   
            this.addEvents('click','change', 'select');  
        },        
        onChange: function (field, newVal, oldVal) {
            alert(newVal);
        },
        onRender : function(ct, position){
            Ext.form.ColorField.superclass.onRender.call(this, ct, position);
            this.handleRender();
        },
        // private
        validateValue : function(value){
            if(!this.showHexValue) {
                return true;
            }
            if(value.length<1) {
                this.el.setStyle({
                    'background-color':'#' + this.defaultColor
                });
                if(!this.allowBlank) {
                    this.markInvalid(String.format(this.blankText, value));
                    return false
                }
                return true;
            }
            if(value.length!=3 && value.length!=6 ) {
                this.markInvalid(String.format(this.lengthText, value));
                return false;
            }
            this.setColor(value);
            return true;
        },
     
        // private
        validateBlur : function(){
            return !this.menu || !this.menu.isVisible();
        },
        
        // Manually apply the invalid line image since the background
        // was previously cleared so the color would show through.
        markInvalid : function( msg ) {
            Ext.form.ColorField.superclass.markInvalid.call(this, msg);
            this.el.setStyle({
                'background-image': 'url(../lib/resources/images/default/grid/invalid_line.gif)'
            });
        },
     
        /**
         * Returns the current color value of the color field
         * @return {String} value The hexidecimal color value
         */
        getValue : function(){
            return this.curValue || this.defaultValue || "FFFFFF";
        },
     
        /**
         * Sets the value of the color field.  Format as hex value 'FFFFFF'
         * without the '#'.
         * @param {String} hex The color value
         */
        setValue : function(hex){
            Ext.form.ColorField.superclass.setValue.call(this, hex);
            this.setColor(hex);
        },
        
        /**
         * Sets the current color and changes the background.
         * Does *not* change the value of the field.
         * @param {String} hex The color value.
         */
        setColor : function(hex) {
            this.curColor = hex;
            
            this.el.setStyle( {
                'background-color': '#' + hex,
                'background-image': 'none'
            });
            if(!this.showHexValue) {
                this.el.setStyle({
                    'text-indent': '-100px'
                });
                if(Ext.isIE) {
                    this.el.setStyle({
                        'margin-left': '100px'
                    });
                }
            }
        },
        
        handleRender: function() {
            this.setDefaultColor();
        },
        
        setDefaultColor : function() {
            this.setValue(this.defaultColor);
        },
     
        // private
        menuListeners : {
            select: function(m, d){
                this.setValue(d);
            },
            show : function(){ // retain focus styling
                this.onFocus();
            },
            hide : function(){
                this.focus();
                var ml = this.menuListeners;
                this.menu.un("select", ml.select,  this);
                this.menu.un("show", ml.show,  this);
                this.menu.un("hide", ml.hide,  this);
            }
        },
        
        //private
        handleSelect : function(palette, selColor) {
            this.setValue(selColor);
            this.fireEvent("click", this, selColor);        
            this.fireEvent("change", this, selColor);        
            this.fireEvent("select", this, selColor); 
        },
     
        // private
        // Implements the default empty TriggerField.onTriggerClick function to display the ColorPicker
        onTriggerClick : function(){
            if(this.disabled){
                return;
            }
            if(this.menu == null){
                this.menu = new Ext.menu.ColorMenu();
                this.menu.palette.on('select', this.handleSelect, this );
            }
            this.menu.on(Ext.apply({}, this.menuListeners, {
                scope:this
            }));
            this.menu.show(this.el, "tl-bl?");
        }
    });

    Ext.hoo.for.ColorField.js

    /**
     * @function 颜色选择器
     * @auhor: hoojo
     * @createDate: Sep 11, 2010 10:35:15 PM
     * @blog: blog.csdn.net/IBM_hoojo
     * @email: hoojo_@126.com
     * @class Ext.hoo.form.ColorField
     * @extends Ext.form.ColorField
     */
    Ext.ns("Ext.hoo.form");
    Ext.hoo.form.ColorField = Ext.extend(Ext.form.ColorField, {
        constructor: function () {
            Ext.hoo.form.ColorField.superclass.constructor.call(this, {
                //fieldLabel: "plase selected",
                renderTo: "show",
                 160,
                defaultColor: "00FF00",
                curColor: "00FF00",
                showHexValue: true,
                listeners: {
                    "select": function (f, v) {
                        alert(this.getValue() + "##" + v);
                    }
                }
            });        
        }
    });
     
    Ext.onReady(function () {
        Ext.BLANK_IMAGE_URL = "../ext2/resources/images/default/s.gif";
        Ext.QuickTips.init();
        Ext.form.Field.prototype.msgTarget = "qtip";
        
        new Ext.hoo.form.ColorField();
    });

    二、日期时间选择控件

    可以选择日期、时间

    clip_image002

    需要用到的文件

    Spinner.js

    Spinner.css

    SpinnerField.js

    日期时间组件:Ext.ux.form.DateTimeField.js

    示例:Ext.hoo.form.DateTimeField.js

    代码如下

    dateTimeFieldExample.htm

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
        <head>
            <title>form Component -- MultiComboBox</title>
            <meta http-equiv="pragma" content="no-cache"/>
            <meta http-equiv="cache-control" content="no-cache"/>
            <meta http-equiv="expires" content="0"/>
            <meta http-equiv="content-Type" content="text/html; charset=utf-8"/>
            <meta http-equiv="author" content="hoojo"/>
            <meta http-equiv="email" content="hoojo_@126.com"/>
            <meta http-equiv="ext-lib" content="version 3.2"/>
            <meta http-equiv="blog" content="http://blog.csdn.net/IBM_hoojo"/>        
            <link rel="stylesheet" type="text/css" href="../ext/resources/css/ext-all.css"/>
            <link rel="stylesheet" type="text/css" href="../css/Spinner.css"/>
            <script type="text/javascript" src="../ext/adapter/ext/ext-base.js"></script>
            <script type="text/javascript" src="../ext/ext-all.js"></script>
            <script type="text/javascript" src="../ext/build/locale/ext-lang-zh_CN-min.js"></script>
            <script type="text/javascript" src="Spinner.js"></script>
            <script type="text/javascript" src="SpinnerField.js"></script>
            <script type="text/javascript" src="Ext.ux.form.DateTimeField.js"></script>
            <script type="text/javascript" src="Ext.hoo.form.DateTimeField.js"></script>
      </head>
      
      <body>
          <div id="show" style="float: left; margin: 100px 0 0 100px;"></div>
      </body>
    </html>

    Spinner.css

    /*!
     * Ext JS Library 3.1.1
     * Copyright(c) 2006-2010 Ext JS, LLC
     * licensing@extjs.com
     * http://www.extjs.com/license
     */
    .x-form-spinner-proxy{
        /*background-color:#ff00cc;*/
    }
    .x-form-field-wrap .x-form-spinner-trigger {
        background:transparent url('../images/spinner.gif') no-repeat 0 0;
    }
     
    .x-form-field-wrap .x-form-spinner-overup{
        background-position:-17px 0;
    }
    .x-form-field-wrap .x-form-spinner-clickup{
        background-position:-34px 0;
    }
    .x-form-field-wrap .x-form-spinner-overdown{
        background-position:-51px 0;
    }
    .x-form-field-wrap .x-form-spinner-clickdown{
        background-position:-68px 0;
    }
     
     
    .x-trigger-wrap-focus .x-form-spinner-trigger{
        background-position:-85px 0;
    }
    .x-trigger-wrap-focus .x-form-spinner-overup{
        background-position:-102px 0;
    }
    .x-trigger-wrap-focus .x-form-spinner-clickup{
        background-position:-119px 0;
    }
    .x-trigger-wrap-focus .x-form-spinner-overdown{
        background-position:-136px 0;
    }
    .x-trigger-wrap-focus .x-form-spinner-clickdown{
        background-position:-153px 0;
    }
    .x-trigger-wrap-focus .x-form-trigger{
        border-bottom: 1px solid #7eadd9;
    }
     
    .x-form-field-wrap .x-form-spinner-splitter {
        line-height:1px;
        font-size:1px;
        background:transparent url('../images/spinner-split.gif') no-repeat 0 0;
        position:absolute;
        cursor: n-resize;
    }
     
    .x-trigger-wrap-focus .x-form-spinner-splitter{
        background-position:-14px 0;
    }
     
    .x-date-bottom {
        font-size: 12px;
    }
     
    .x-date-menu {
        height: 200px;
    }

    图片

    spinner.gif clip_image003

    spinner-split.gif clip_image004

    Spinner.js

    /*!
     * Ext JS Library 3.1.1
     * Copyright(c) 2006-2010 Ext JS, LLC
     * licensing@extjs.com
     * http://www.extjs.com/license
     */
    /**
     * @class Ext.ux.Spinner
     * @extends Ext.util.Observable
     * Creates a Spinner control utilized by Ext.ux.form.SpinnerField
     */
    Ext.ux.Spinner = Ext.extend(Ext.util.Observable, {
        incrementValue: 1,
        alternateIncrementValue: 5,
        triggerClass: 'x-form-spinner-trigger',
        splitterClass: 'x-form-spinner-splitter',
        alternateKey: Ext.EventObject.shiftKey,
        defaultValue: 0,
        accelerate: false,
     
        constructor: function(config){
            Ext.ux.Spinner.superclass.constructor.call(this, config);
            Ext.apply(this, config);
            this.mimicing = false;
        },
     
        init: function(field){
            this.field = field;
     
            field.afterMethod('onRender', this.doRender, this);
            field.afterMethod('onEnable', this.doEnable, this);
            field.afterMethod('onDisable', this.doDisable, this);
            field.afterMethod('afterRender', this.doAfterRender, this);
            field.afterMethod('onResize', this.doResize, this);
            field.afterMethod('onFocus', this.doFocus, this);
            field.beforeMethod('onDestroy', this.doDestroy, this);
        },
     
        doRender: function(ct, position){
            var el = this.el = this.field.getEl();
            var f = this.field;
     
            if (!f.wrap) {
                f.wrap = this.wrap = el.wrap({
                    cls: "x-form-field-wrap"
                });
            }
            else {
                this.wrap = f.wrap.addClass('x-form-field-wrap');
            }
     
            this.trigger = this.wrap.createChild({
                tag: "img",
                src: Ext.BLANK_IMAGE_URL,
                cls: "x-form-trigger " + this.triggerClass
            });
     
            if (!f.width) {
                this.wrap.setWidth(el.getWidth() + this.trigger.getWidth());
            }
     
            this.splitter = this.wrap.createChild({
                tag: 'div',
                cls: this.splitterClass,
                style: '13px; height:2px;'
            });
            this.splitter.setRight((Ext.isIE) ? 1 : 2).setTop(10).show();
     
            this.proxy = this.trigger.createProxy('', this.splitter, true);
            this.proxy.addClass("x-form-spinner-proxy");
            this.proxy.setStyle('left', '0px');
            this.proxy.setSize(14, 1);
            this.proxy.hide();
            this.dd = new Ext.dd.DDProxy(this.splitter.dom.id, "SpinnerDrag", {
                dragElId: this.proxy.id
            });
     
            this.initTrigger();
            this.initSpinner();
        },
     
        doAfterRender: function(){
            var y;
            if (Ext.isIE && this.el.getY() != (y = this.trigger.getY())) {
                this.el.position();
                this.el.setY(y);
            }
        },
     
        doEnable: function(){
            if (this.wrap) {
                this.wrap.removeClass(this.field.disabledClass);
            }
        },
     
        doDisable: function(){
            if (this.wrap) {
                this.wrap.addClass(this.field.disabledClass);
                this.el.removeClass(this.field.disabledClass);
            }
        },
     
        doResize: function(w, h){
            if (typeof w == 'number') {
                this.el.setWidth(w - this.trigger.getWidth());
            }
            this.wrap.setWidth(this.el.getWidth() + this.trigger.getWidth());
        },
     
        doFocus: function(){
            if (!this.mimicing) {
                this.wrap.addClass('x-trigger-wrap-focus');
                this.mimicing = true;
                Ext.get(Ext.isIE ? document.body : document).on("mousedown", this.mimicBlur, this, {
                    delay: 10
                });
                this.el.on('keydown', this.checkTab, this);
            }
        },
     
        // private
        checkTab: function(e){
            if (e.getKey() == e.TAB) {
                this.triggerBlur();
            }
        },
     
        // private
        mimicBlur: function(e){
            if (!this.wrap.contains(e.target) && this.field.validateBlur(e)) {
                this.triggerBlur();
            }
        },
     
        // private
        triggerBlur: function(){
            this.mimicing = false;
            Ext.get(Ext.isIE ? document.body : document).un("mousedown", this.mimicBlur, this);
            this.el.un("keydown", this.checkTab, this);
            this.field.beforeBlur();
            this.wrap.removeClass('x-trigger-wrap-focus');
            this.field.onBlur.call(this.field);
        },
     
        initTrigger: function(){
            this.trigger.addClassOnOver('x-form-trigger-over');
            this.trigger.addClassOnClick('x-form-trigger-click');
        },
     
        initSpinner: function(){
            this.field.addEvents({
                'spin': true,
                'spinup': true,
                'spindown': true
            });
     
            this.keyNav = new Ext.KeyNav(this.el, {
                "up": function(e){
                    e.preventDefault();
                    this.onSpinUp();
                },
     
                "down": function(e){
                    e.preventDefault();
                    this.onSpinDown();
                },
     
                "pageUp": function(e){
                    e.preventDefault();
                    this.onSpinUpAlternate();
                },
     
                "pageDown": function(e){
                    e.preventDefault();
                    this.onSpinDownAlternate();
                },
     
                scope: this
            });
     
            this.repeater = new Ext.util.ClickRepeater(this.trigger, {
                accelerate: this.accelerate
            });
            this.field.mon(this.repeater, "click", this.onTriggerClick, this, {
                preventDefault: true
            });
     
            this.field.mon(this.trigger, {
                mouseover: this.onMouseOver,
                mouseout: this.onMouseOut,
                mousemove: this.onMouseMove,
                mousedown: this.onMouseDown,
                mouseup: this.onMouseUp,
                scope: this,
                preventDefault: true
            });
     
            this.field.mon(this.wrap, "mousewheel", this.handleMouseWheel, this);
     
            this.dd.setXConstraint(0, 0, 10)
            this.dd.setYConstraint(1500, 1500, 10);
            this.dd.endDrag = this.endDrag.createDelegate(this);
            this.dd.startDrag = this.startDrag.createDelegate(this);
            this.dd.onDrag = this.onDrag.createDelegate(this);
        },
     
        onMouseOver: function(){
            if (this.disabled) {
                return;
            }
            var middle = this.getMiddle();
            this.tmpHoverClass = (Ext.EventObject.getPageY() < middle) ? 'x-form-spinner-overup' : 'x-form-spinner-overdown';
            this.trigger.addClass(this.tmpHoverClass);
        },
     
        //private
        onMouseOut: function(){
            this.trigger.removeClass(this.tmpHoverClass);
        },
     
        //private
        onMouseMove: function(){
            if (this.disabled) {
                return;
            }
            var middle = this.getMiddle();
            if (((Ext.EventObject.getPageY() > middle) && this.tmpHoverClass == "x-form-spinner-overup") ||
            ((Ext.EventObject.getPageY() < middle) && this.tmpHoverClass == "x-form-spinner-overdown")) {
            }
        },
     
        //private
        onMouseDown: function(){
            if (this.disabled) {
                return;
            }
            var middle = this.getMiddle();
            this.tmpClickClass = (Ext.EventObject.getPageY() < middle) ? 'x-form-spinner-clickup' : 'x-form-spinner-clickdown';
            this.trigger.addClass(this.tmpClickClass);
        },
     
        //private
        onMouseUp: function(){
            this.trigger.removeClass(this.tmpClickClass);
        },
     
        //private
        onTriggerClick: function(){
            if (this.disabled || this.el.dom.readOnly) {
                return;
            }
            var middle = this.getMiddle();
            var ud = (Ext.EventObject.getPageY() < middle) ? 'Up' : 'Down';
            this['onSpin' + ud]();
        },
     
        //private
        getMiddle: function(){
            var t = this.trigger.getTop();
            var h = this.trigger.getHeight();
            var middle = t + (h / 2);
            return middle;
        },
     
        //private
        //checks if control is allowed to spin
        isSpinnable: function(){
            if (this.disabled || this.el.dom.readOnly) {
                Ext.EventObject.preventDefault(); //prevent scrolling when disabled/readonly
                return false;
            }
            return true;
        },
     
        handleMouseWheel: function(e){
            //disable scrolling when not focused
            if (this.wrap.hasClass('x-trigger-wrap-focus') == false) {
                return;
            }
     
            var delta = e.getWheelDelta();
            if (delta > 0) {
                this.onSpinUp();
                e.stopEvent();
            }
            else
                if (delta < 0) {
                    this.onSpinDown();
                    e.stopEvent();
                }
        },
     
        //private
        startDrag: function(){
            this.proxy.show();
            this._previousY = Ext.fly(this.dd.getDragEl()).getTop();
        },
     
        //private
        endDrag: function(){
            this.proxy.hide();
        },
     
        //private
        onDrag: function(){
            if (this.disabled) {
                return;
            }
            var y = Ext.fly(this.dd.getDragEl()).getTop();
            var ud = '';
     
            if (this._previousY > y) {
                ud = 'Up';
            } //up
            if (this._previousY < y) {
                ud = 'Down';
            } //down
            if (ud != '') {
                this['onSpin' + ud]();
            }
     
            this._previousY = y;
        },
     
        //private
        onSpinUp: function(){
            if (this.isSpinnable() == false) {
                return;
            }
            if (Ext.EventObject.shiftKey == true) {
                this.onSpinUpAlternate();
                return;
            }
            else {
                this.spin(false, false);
            }
            this.field.fireEvent("spin", this);
            this.field.fireEvent("spinup", this);
        },
     
        //private
        onSpinDown: function(){
            if (this.isSpinnable() == false) {
                return;
            }
            if (Ext.EventObject.shiftKey == true) {
                this.onSpinDownAlternate();
                return;
            }
            else {
                this.spin(true, false);
            }
            this.field.fireEvent("spin", this);
            this.field.fireEvent("spindown", this);
        },
     
        //private
        onSpinUpAlternate: function(){
            if (this.isSpinnable() == false) {
                return;
            }
            this.spin(false, true);
            this.field.fireEvent("spin", this);
            this.field.fireEvent("spinup", this);
        },
     
        //private
        onSpinDownAlternate: function(){
            if (this.isSpinnable() == false) {
                return;
            }
            this.spin(true, true);
            this.field.fireEvent("spin", this);
            this.field.fireEvent("spindown", this);
        },
     
        spin: function(down, alternate){
            var v = parseFloat(this.field.getValue());
            var incr = (alternate == true) ? this.alternateIncrementValue : this.incrementValue;
            (down == true) ? v -= incr : v += incr;
     
            v = (isNaN(v)) ? this.defaultValue : v;
            v = this.fixBoundries(v);
            this.field.setRawValue(v);
        },
     
        fixBoundries: function(value){
            var v = value;
     
            if (this.field.minValue != undefined && v < this.field.minValue) {
                v = this.field.minValue;
            }
            if (this.field.maxValue != undefined && v > this.field.maxValue) {
                v = this.field.maxValue;
            }
     
            return this.fixPrecision(v);
        },
     
        // private
        fixPrecision: function(value){
            var nan = isNaN(value);
            if (!this.field.allowDecimals || this.field.decimalPrecision == -1 || nan || !value) {
                return nan ? '' : value;
            }
            return parseFloat(parseFloat(value).toFixed(this.field.decimalPrecision));
        },
     
        doDestroy: function(){
            if (this.trigger) {
                this.trigger.remove();
            }
            if (this.wrap) {
                this.wrap.remove();
                delete this.field.wrap;
            }
     
            if (this.splitter) {
                this.splitter.remove();
            }
     
            if (this.dd) {
                this.dd.unreg();
                this.dd = null;
            }
     
            if (this.proxy) {
                this.proxy.remove();
            }
     
            if (this.repeater) {
                this.repeater.purgeListeners();
            }
        }
    });
     
    //backwards compat
    Ext.form.Spinner = Ext.ux.Spinner;

    SpinnerField.js

    /*!
     * Ext JS Library 3.1.1
     * Copyright(c) 2006-2010 Ext JS, LLC
     * licensing@extjs.com
     * http://www.extjs.com/license
     */
    Ext.ns('Ext.ux.form');
     
    /**
     * @class Ext.ux.form.SpinnerField
     * @extends Ext.form.NumberField
     * Creates a field utilizing Ext.ux.Spinner
     * @xtype spinnerfield
     */
    Ext.ux.form.SpinnerField = Ext.extend(Ext.form.NumberField, {
        actionMode: 'wrap',
        deferHeight: true,
        autoSize: Ext.emptyFn,
        onBlur: Ext.emptyFn,
        adjustSize: Ext.BoxComponent.prototype.adjustSize,
     
        constructor: function(config) {
            var spinnerConfig = Ext.copyTo({}, config, 'incrementValue,alternateIncrementValue,accelerate,defaultValue,triggerClass,splitterClass');
     
            var spl = this.spinner = new Ext.ux.Spinner(spinnerConfig);
     
            var plugins = config.plugins
                ? (Ext.isArray(config.plugins)
                    ? config.plugins.push(spl)
                    : [config.plugins, spl])
                : spl;
     
            Ext.ux.form.SpinnerField.superclass.constructor.call(this, Ext.apply(config, {plugins: plugins}));
        },
     
        // private
        getResizeEl: function(){
            return this.wrap;
        },
     
        // private
        getPositionEl: function(){
            return this.wrap;
        },
     
        // private
        alignErrorIcon: function(){
            if (this.wrap) {
                this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
            }
        },
     
        validateBlur: function(){
            return true;
        }
    });
     
    Ext.reg('spinnerfield', Ext.ux.form.SpinnerField);
     
    //backwards compat
    Ext.form.SpinnerField = Ext.ux.form.SpinnerField;

    Ext.ux.form.DateTimeField.js

    Ext.ns('Ext.ux.form');
    Ext.ux.form.TimePickerField = function(config){
        Ext.ux.form.TimePickerField.superclass.constructor.call(this, config);
    }
    Ext.extend(Ext.ux.form.TimePickerField, Ext.form.Field, {
        defaultAutoCreate: {
            tag: 'div'
        },
        cls: 'x-form-timepickerfield',
        hoursSpinner: null,
        minutesSpinner: null,
        secondsSpinner: null,
        spinnerCfg: {
             40
        },
        spinnerFixBoundries: function(value){
            if (value < this.field.minValue) {
                value = this.field.maxValue;
            }
            if (value > this.field.maxValue) {
                value = this.field.minValue;
            }
            return this.fixPrecision(value);
        },
        onRender: function(ct, position){
            Ext.ux.form.TimePickerField.superclass.onRender.call(this, ct, position);
            this.rendered = false;
            this.date = new Date();
            var values = {};
            if (this.value) {
                values = this._valueSplit(this.value);
                this.date.setHours(values.h);
                this.date.setMinutes(values.m);
                this.date.setSeconds(values.s);
                delete this.value;
            }
            else {
                values = {
                    h: this.date.getHours(),
                    m: this.date.getMinutes(),
                    s: this.date.getSeconds()
                };
            }
            var spinnerWrap = Ext.DomHelper.append(this.el, {
                tag: 'div'
            });
            var cfg = Ext.apply({}, this.spinnerCfg, {
                renderTo: spinnerWrap,
                readOnly: this.readOnly,
                disabled: this.disabled,
                listeners: {
                    spin: {
                        fn: this.onSpinnerChange,
                        scope: this
                    },
                    valid: {
                        fn: this.onSpinnerChange,
                        scope: this
                    },
                    afterrender: {
                        fn: function(spinner){
                            spinner.wrap.applyStyles('float: left');
                        },
                        single: true
                    }
                }
            });
            this.hoursSpinner = new Ext.ux.form.SpinnerField(Ext.apply({}, cfg, {
                minValue: 0,
                maxValue: 23,
                cls: 'first',
                value: values.h
            }));
            this.minutesSpinner = new Ext.ux.form.SpinnerField(Ext.apply({}, cfg, {
                minValue: 0,
                maxValue: 59,
                value: values.m
            }));
            this.secondsSpinner = new Ext.ux.form.SpinnerField(Ext.apply({}, cfg, {
                minValue: 0,
                maxValue: 59,
                value: values.s
            }));
            Ext.DomHelper.append(spinnerWrap, {
                tag: 'div',
                cls: 'x-form-clear-left'
            });
            this.rendered = true;
        },
        _valueSplit: function(v){
            var split = v.split(':');
            return {
                h: split.length > 0 ? split[0] : 0,
                m: split.length > 1 ? split[1] : 0,
                s: split.length > 2 ? split[2] : 0
            };
        },
        onSpinnerChange: function(){
            if (!this.rendered) {
                return;
            }
            this.fireEvent('change', this, this.getRawValue());
        },
        disable: function(){
            Ext.ux.form.TimePickerField.superclass.disable.call(this);
            this.hoursSpinner.disable();
            this.minutesSpinner.disable();
            this.secondsSpinner.disable();
        },
        enable: function(){
            Ext.ux.form.TimePickerField.superclass.enable.call(this);
            this.hoursSpinner.enable();
            this.minutesSpinner.enable();
            this.secondsSpinner.enable();
        },
        setReadOnly: function(r){
            Ext.ux.form.TimePickerField.superclass.setReadOnly.call(this, r);
            this.hoursSpinner.setReadOnly(r);
            this.minutesSpinner.setReadOnly(r);
            this.secondsSpinner.setReadOnly(r);
        },
        clearInvalid: function(){
            Ext.ux.form.TimePickerField.superclass.clearInvalid.call(this);
            this.hoursSpinner.clearInvalid();
            this.minutesSpinner.clearInvalid();
            this.secondsSpinner.clearInvalid();
        },
        getRawValue: function(){
            if (!this.hoursSpinner) {
                this.date = new Date();
                return {
                    h: this.date.getHours(),
                    m: this.date.getMinutes(),
                    s: this.date.getSeconds()
                };
            }
            else {
                return {
                    h: this.hoursSpinner.getValue(),
                    m: this.minutesSpinner.getValue(),
                    s: this.secondsSpinner.getValue()
                };
            }
        },
        setRawValue: function(v){
            this.hoursSpinner.setValue(v.h);
            this.minutesSpinner.setValue(v.m);
            this.secondsSpinner.setValue(v.s);
        },
        isValid: function(preventMark){
            return this.hoursSpinner.isValid(preventMark) &&
            this.minutesSpinner.isValid(preventMark) &&
            this.secondsSpinner.isValid(preventMark);
        },
        validate: function(){
            return this.hoursSpinner.validate() &&
            this.minutesSpinner.validate() &&
            this.secondsSpinner.validate();
        },
        getValue: function(){
            var v = this.getRawValue();
            return String.leftPad(v.h, 2, '0') + ':' +
            String.leftPad(v.m, 2, '0') +
            ':' +
            String.leftPad(v.s, 2, '0');
        },
        setValue: function(value){
            if (!this.rendered) {
                this.value = value;
                return;
            }
            value = this._valueSplit(value);
            this.setRawValue(value);
            this.validate();
        }
    });
     
    Ext.form.TimePickerField = Ext.ux.form.TimePickerField;
    Ext.reg('timepickerfield', Ext.form.TimePickerField);
    Ext.ns('Ext.ux.form');
    Ext.DateTimePicker = Ext.extend(Ext.DatePicker, {
        timeFormat: 'g:i:s A',
        timeLabel: '时间',
        timeWidth: 100,
        initComponent: function(){
            Ext.DateTimePicker.superclass.initComponent.call(this);
            this.id = Ext.id();
        },
        onRender: function(container, position){
            Ext.DateTimePicker.superclass.onRender.apply(this, arguments);
            var table = Ext.get(Ext.DomQuery.selectNode('table tbody', container.dom));
            var tfEl = Ext.DomHelper.insertBefore(table.last(), {
                tag: 'tr',
                children: [{
                    tag: 'td',
                    cls: 'x-date-bottom',
                    html: this.timeLabel,
                    style: '30;'
                }, {
                    tag: 'td',
                    cls: 'x-date-bottom ux-timefield',
                    style: "height: 20px;",
                    colspan: '2'
                }]
            }, true);
            this.tf.render(table.child('td.ux-timefield'));
            var p = this.getEl().parent('div.x-layer');
            if (p) {
                p.setStyle("height", p.getHeight() + 31);
            }
        },
        setValue: function(value){
            var old = this.value;
            if (!this.tf) {
                this.tf = new Ext.ux.form.TimePickerField();
                this.tf.ownerCt = this;
            }
            this.value = this.getDateTime(value);
        },
        getDateTime: function(value){
            if (this.tf) {
                var dt = new Date();
                var timeval = this.tf.getValue();
                value = Date.parseDate(value.format(this.dateFormat) + ' ' + this.tf.getValue(), this.format);
            }
            return value;
        },
        selectToday: function(){
            if (this.todayBtn && !this.todayBtn.disabled) {
                this.value = this.getDateTime(new Date());
                this.fireEvent("select", this, this.value);
            }
        }
    });
    Ext.reg('datetimepickerfield', Ext.DateTimePicker);
    if (parseInt(Ext.version.substr(0, 1), 10) > 2) {
        Ext.menu.DateTimeItem = Ext.DateTimePicker;
        Ext.override(Ext.menu.DateMenu, {
            initComponent: function(){
                this.on('beforeshow', this.onBeforeShow, this);
                if (this.strict = (Ext.isIE7 && Ext.isStrict)) {
                    this.on('show', this.onShow, this, {
                        single: true,
                        delay: 20
                    });
                }
                Ext.apply(this, {
                    plain: true,
                    showSeparator: false,
                    items: this.picker = new Ext.DatePicker(Ext.apply({
                        internalRender: this.strict || !Ext.isIE,
                        ctCls: 'x-menu-date-item'
                    }, this.initialConfig))
                });
                Ext.menu.DateMenu.superclass.initComponent.call(this);
                this.relayEvents(this.picker, ["select"]);
                this.on('select', this.menuHide, this);
                if (this.handler) {
                    this.on('select', this.handler, this.scope || this);
                }
            }
        });
    }
    else {
        Ext.menu.DateTimeItem = function(config){
            Ext.menu.DateTimeItem.superclass.constructor.call(this, new Ext.DateTimePicker(config), config);
            this.picker = this.component;
            alert(this.picker);
            this.addEvents('select');
            
            this.picker.on("render", function(picker){
                picker.getEl().swallowEvent("click");
                picker.container.addClass("x-menu-date-item");
            });
            
            this.picker.on("select", this.onSelect, this);
        };
        
        Ext.extend(Ext.menu.DateTimeItem, Ext.menu.DateMenu, {
            onSelect: function(picker, date){
                this.fireEvent("select", this, date, picker);
                Ext.menu.DateTimeItem.superclass.handleClick.call(this);
            }
        });
    }
     
    Ext.menu.DateTimeMenu = function(config){
        Ext.menu.DateTimeMenu.superclass.constructor.call(this, config);
        this.plain = true;
        var di = new Ext.menu.DateTimeItem(config);
        this.add(di);
        this.picker = di;
        this.relayEvents(di, ["select"]);
        
        this.on('beforeshow', function(){
            if (this.picker) {
                this.picker.hideMonthPicker(true);
            }
        }, this);
    };
    Ext.extend(Ext.menu.DateTimeMenu, Ext.menu.Menu, {
        cls: 'x-date-menu',
        beforeDestroy: function(){
            this.picker.destroy();
        },
        hide: function(deep){
            if (this.picker.tf.innerList) {
                if ((Ext.EventObject.within(this.picker.tf.innerList)) || (Ext.get(Ext.EventObject.getTarget()) == this.picker.tf.innerList)) 
                    return false;
            }
            if (this.el && this.isVisible()) {
                this.fireEvent("beforehide", this);
                if (this.activeItem) {
                    this.activeItem.deactivate();
                    this.activeItem = null;
                }
                this.el.hide();
                this.hidden = true;
                this.fireEvent("hide", this);
            }
            if (deep === true && this.parentMenu) {
                this.parentMenu.hide(true);
            }
        }
    });
     
    Ext.ux.form.DateTimeField = Ext.extend(Ext.form.DateField, {
        dateFormat: 'Y-m-d',
        timeFormat: 'H:i:s',
        defaultAutoCreate: {
            tag: "input",
            type: "text",
            size: "20",
            autocomplete: "off"
        },
        initComponent: function(){
            Ext.ux.form.DateTimeField.superclass.initComponent.call(this);
            this.format = this.dateFormat + ' ' + this.timeFormat;
            this.afterMethod('afterRender', function(){
                this.getEl().applyStyles('top:0');
            });
        },
        getValue: function(){
            return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || '';
        },
        onTriggerClick: function(){
            if (this.disabled) {
                return;
            }
            if (this.menu == null) {
                this.menu = new Ext.menu.DateTimeMenu();
            }
            Ext.apply(this.menu.picker, {
                minDate: this.minValue,
                maxDate: this.maxValue,
                disabledDatesRE: this.ddMatch,
                disabledDatesText: this.disabledDatesText,
                disabledDays: this.disabledDays,
                disabledDaysText: this.disabledDaysText,
                format: this.format,
                timeFormat: this.timeFormat,
                dateFormat: this.dateFormat,
                showToday: this.showToday,
                minText: String.format(this.minText, this.formatDate(this.minValue)),
                maxText: String.format(this.maxText, this.formatDate(this.maxValue))
            });
            if (this.menuEvents) {
                this.menuEvents('on');
            }
            else {
                this.menu.on(Ext.apply({}, this.menuListeners, {
                    scope: this
                }));
            }
            this.menu.picker.setValue(this.getValue() || new Date());
            this.menu.show(this.el, "tl-bl?");
        }
    });
    Ext.reg('datetimefield', Ext.ux.form.DateTimeField);

    Ext.hoo.form.DateTimeField.js

    /**
     * @function 可以选择日期的DateTimeField
     * @auhor: hoojo
     * @createDate: Sep 16, 2010 9:25:12 PM
     * @blog: blog.csdn.net/IBM_hoojo
     * @email: hoojo_@126.com
     * @class Ext.hoo.form.DateTimeField
     * @extends Ext.ux.form.DateTimeField
     */
    Ext.ns("Ext.hoo.form");
    Ext.hoo.form.DateTimeField = Ext.extend(Ext.ux.form.DateTimeField, {
        constructor: function () {
            Ext.hoo.form.DateTimeField.superclass.constructor.call(this, {
                renderTo: "show",
                height: 222,
                dateFormat: 'Y-m-d',
                timeFormat: 'H:i:s',
                listeners: {
                    select: function () {
                        alert(this.getValue() + "##" + this.getRawValue());
                    }
                }
            });
        }
    });
     
    Ext.onReady(function () {
        Ext.BLANK_IMAGE_URL = "../ext2/resources/images/default/s.gif";
        Ext.QuickTips.init();
        Ext.form.Field.prototype.msgTarget = "qtip";
        
        new Ext.hoo.form.DateTimeField();
    });

    三、带图标的下列列表

    效果图如下

    clip_image005

    需要的文件

    combo_icon.gif

    clip_image006

    iconCombobox 插件文件: Ext.ux.IconCombo.js

    示例文件: Ext.hoo.form.WebBroserIconComboBox.js

    代码如下

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
        <head>
            <title>form Component -- iconCombo</title>
            <meta http-equiv="pragma" content="no-cache"/>
            <meta http-equiv="cache-control" content="no-cache"/>
            <meta http-equiv="expires" content="0"/>
            <meta http-equiv="content-Type" content="text/html; charset=utf-8"/>
            <meta http-equiv="author" content="hoojo"/>
            <meta http-equiv="email" content="hoojo_@126.com"/>
            <meta http-equiv="ext-lib" content="version 2.2"/>
            <meta http-equiv="blog" content="http://blog.csdn.net/IBM_hoojo"/>        
            <link rel="stylesheet" type="text/css" href="../ext2/resources/css/ext-all.css"/>
            <link rel="stylesheet" type="text/css" href="../css/iconCombo.css"/>
            <style type="text/css">
                .ffCls {
                    background: url(../images/combo_icon.gif) no-repeat 1px -15px;
                }
                
                .ieCls {
                    background: url(../images/combo_icon.gif) no-repeat 1px 2px;
                }
                
                .operaCls {
                    background: url(../images/combo_icon.gif) no-repeat 1px -68px;
                }
                
                .chromeCls {
                    background: url(../images/combo_icon.gif) no-repeat 1px -85px;
                }
                
                .maxCls {
                    background: url(../images/combo_icon.gif) no-repeat 1px -32px;
                }
                
                .ttCls {
                    background: url(../images/combo_icon.gif) no-repeat 1px -50px;
                }
                
                .sfCls {
                    background: url(../images/combo_icon.gif) no-repeat 1px -103px;
                }
                
                .twCls {
                    background: url(../images/combo_icon.gif) no-repeat 1px -121px;
                }
                
                .flockCls {
                    background: url(../images/combo_icon.gif) no-repeat 1px -139px;
                }
            </style>
            <script type="text/javascript" src="../ext2/adapter/ext/ext-base.js"></script>
            <script type="text/javascript" src="../ext2/ext-all.js"></script>
            <script type="text/javascript" src="../ext2/build/locale/ext-lang-zh_CN-min.js"></script>
            <script type="text/javascript" src="Ext.ux.IconCombo.js"></script>
            <script type="text/javascript" src="Ext.hoo.form.WebBroserIconComboBox.js"></script>
      </head>
      
      <body>
          <div id="show" style="padding: 100px 0 0 300px;"></div>
      </body>
    </html>

    Ext.ux.IconCombo.js 文件代码

    /**
     * @class Ext.ux.IconCombo
     * @extends Ext.form.ComboBox
     * @param {Object} config Configuration options
     */
    Ext.ux.IconCombo = function(config) {
        // call parent constructor
        Ext.ux.IconCombo.superclass.constructor.call(this, config);
        this.tpl = config.tpl || '<tpl for="."><div class="x-combo-list-item">'
                + '<table><tbody><tr>' + '<td>' + '<div class="{'
                + this.iconClsField + '}"></div></td>' + '<td>{'
                + this.displayField + '}</td>' + '</tr></tbody></table>'
                + '</div></tpl>';
    };
     
    Ext.extend(Ext.ux.IconCombo, Ext.form.ComboBox, {
        defaultIconCls: "ux-icon-combo-icon",
        emptyText: "plase selected",
        setIconCls : function() {
            var record = this.store.query(this.valueField, this.getValue()).itemAt(0);
            if (record) {
                this.flag.className = record.get(this.iconClsField) || defaultIconCls || "ux-icon-combo-icon";
                //this.flag.style.backgroundImage = rec.get(this.iconClsField);
            }
        },
        setValue : function(value) {
            Ext.ux.IconCombo.superclass.setValue.call(this, value);
            this.setIconCls();
        },
        onRender: function(ct, position) {
                Ext.ux.IconCombo.superclass.onRender.call(this, ct, position);
                
                var wrap = this.el.up("div.x-form-field-wrap");
                this.wrap.applyStyles({
                    position : "relative"
                });
                this.el.addClass("ux-icon-combo-input");
                //textfield中显示的图片div
                this.flag = Ext.DomHelper.append(wrap, {
                    tag : "div",
                    style : "position:absolute; left: 5px; top: 1px;"
                });
                //默认图片样式
                this.flag.className = this.defaultIconCls;
            }
    });

    Ext.hoo.form.WebBroserIconComboBox.js

    /**
     * @function 带图片的combobox
     * @auhor: hoojo
     * @createDate: Sep 10, 2010 11:16:12 PM
     * @blog: blog.csdn.net/IBM_hoojo
     * @email: hoojo_@126.com
     * @class Ext.hoo.form.WebBroserIconComboBox
     * @extends Ext.ux.IconCombo
     */
    Ext.ns("Ext.hoo.form");
    Ext.hoo.form.WebBroserIconComboBox = Ext.extend(Ext.ux.IconCombo, {
        constructor: function () {
            Ext.hoo.form.WebBroserIconComboBox.superclass.constructor.call(this, {
                /*fieldLabel: "web broser type",
                labelWidth: 73,*/
                renderTo: /*Ext.getBody(),*/"show",
                 200,
                store: new Ext.data.SimpleStore({
                    fields: ["shortName", "name", "iconCls"],
                    data: [
                        ["ff", "Mozilla Firefox" , "ffCls"],
                        ["IE", "Internet Explorer" , "IECls"],
                        ["opera", "Opera" , "operaCls"],
                        ["chrome", "Google Chrome" , "chromeCls"],
                        ["max", "Maxthon" , "maxCls"],
                        ["tt", "TecentTraveler" , "ttCls"],
                        ["sf", "Safari" , "sfCls"],
                        ["tw", "TheWorld" , "twCls"],
                        ["flock", "Flock" , "flockCls"]
                    ]
                }),
                valueField: "shortName",
                displayField: "name",
                iconClsField: "iconCls",
                triggerAction: "all",
                editable: false,
                mode: "local"
            });
            this.on("select", function (field, e) {
                alert(field.getValue() + "###" + field.getRawValue());
            }, this);
        }
    });
     
    Ext.onReady(function () {
        Ext.BLANK_IMAGE_URL = "../ext2/resources/images/default/s.gif";
        Ext.QuickTips.init();
        Ext.form.Field.prototype.msgTarget = "qtip";
        
        new Ext.hoo.form.WebBroserIconComboBox();
    });

    四、多选下列列表组件

    可以同时选择多个选项

    clip_image007

    核心文件

    多选下拉列表组件:Ext.form.MultiComboBox.js

    示例文件:Ext.hoo.form.InterestMultiComboBox.js

    代码如下

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
        <head>
            <title>form Component -- MultiComboBox</title>
            <meta http-equiv="pragma" content="no-cache"/>
            <meta http-equiv="cache-control" content="no-cache"/>
            <meta http-equiv="expires" content="0"/>
            <meta http-equiv="content-Type" content="text/html; charset=utf-8"/>
            <meta http-equiv="author" content="hoojo"/>
            <meta http-equiv="email" content="hoojo_@126.com"/>
            <meta http-equiv="ext-lib" content="version 2.2"/>
            <meta http-equiv="blog" content="http://blog.csdn.net/IBM_hoojo"/>        
            <link rel="stylesheet" type="text/css" href="../ext2/resources/css/ext-all.css"/>
            <style type="text/css">
                .checked{
                    background-image: url("../ext2/resources/images/default/menu/checked.gif");
                }
                .unchecked{
                    background-image: url("../ext2/resources/images/default/menu/unchecked.gif");
                }
                
                .x-combo-list-item {
                    line-height: 18px; 
                }
            </style>
            <script type="text/javascript" src="../ext2/adapter/ext/ext-base.js"></script>
            <script type="text/javascript" src="../ext2/ext-all.js"></script>
            <script type="text/javascript" src="../ext2/build/locale/ext-lang-zh_CN-min.js"></script>
            <script type="text/javascript" src="Ext.form.MultiComboBox.js"></script>
            <script type="text/javascript" src="Ext.hoo.form.InterestMultiComboBox.js"></script>
      </head>
      
      <body>
      <center>
          <div id="show" style="padding-top: 200px;"></div>
      </center>
      </body>
    </html>

    Ext.form.MultiComboBox.js

    Ext.form.MultiComboBox = Ext.extend(Ext.form.TriggerField, {
        defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"},
        listClass: '',
        selectedClass: 'x-combo-selected',
        triggerClass : 'x-form-arrow-trigger',
        shadow:'sides',
        listAlign: 'tl-bl?',
        maxHeight: 300,
        triggerAction: 'query',
        minChars : 4,
        typeAhead: false,
        queryDelay: 500,
        pageSize: 0,
        selectOnFocus: false,
        queryParam: 'query',
        loadingText: 'Loading...',
        resizable: false,
        handleHeight : 8,
        editable: true,
        allQuery: '',
        mode: 'remote',
        minListWidth : 70,
        forceSelection:false,
        typeAheadDelay : 250,
        displaySeparator:';',
        valueSeparator:',',
        lazyInit : true,
     
        initComponent : function(){
            Ext.form.ComboBox.superclass.initComponent.call(this);
            this.addEvents(
                'expand',
                'collapse',
                'beforeselect',
                'select',
                'beforequery'
            );
            if(this.transform){
                this.allowDomMove = false;
                var s = Ext.getDom(this.transform);
                if(!this.hiddenName){
                    this.hiddenName = s.name;
                }
                if(!this.store){
                    this.mode = 'local';
                    var d = [], opts = s.options;
                    for(var i = 0, len = opts.length;i < len; i++){
                        var o = opts[i];
                        var value = (Ext.isIE ? o.getAttributeNode('value').specified : o.hasAttribute('value')) ? o.value : o.text;
                        if(o.selected) {
                            this.value = value;
                        }
                        d.push([value, o.text]);
                    }
                    this.store = new Ext.data.SimpleStore({
                        'id': 0,
                        fields: ['value', 'text'],
                        data : d
                    });
                    this.valueField = 'value';
                    this.displayField = 'text';
                }
                s.name = Ext.id(); // wipe out the name in case somewhere else they have a reference
                if(!this.lazyRender){
                    this.target = true;
                    this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate);
                    Ext.removeNode(s); // remove it
                    this.render(this.el.parentNode);
                }else{
                    Ext.removeNode(s); // remove it
                }
     
            }
            this.selectedIndex = -1;
            if(this.mode == 'local'){
                if(this.initialConfig.queryDelay === undefined){
                    this.queryDelay = 10;
                }
                if(this.initialConfig.minChars === undefined){
                    this.minChars = 0;
                }
            }
        },
     
        // private
        onRender : function(ct, position){
            Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
            var disValue="";
            if(this.hiddenName){
                this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName, id: (this.hiddenId||this.hiddenName)},
                        'before', true);
              var hvalue=this.hiddenValue !== undefined ? this.hiddenValue :
                    this.value !== undefined ? this.value : '';
              var hvalueArray=hvalue.split(this.valueSeparator);
              
              for(var i=0;i<this.store.data.length;i++){
                     var r = this.store.getAt(i);   
                     var newValue = r.data[this.displayField];
                      var v=r.data[this.valueField];
                      for(var j=0;j<hvalueArray.length;j++){
                          if(hvalueArray[j]==v){
                              disValue+=newValue+this.displaySeparator;
                          }
                      }
                     
              }     
                this.hiddenField.value =this.hiddenValue !== undefined ? this.hiddenValue :
                    this.value !== undefined ? this.value : '';
                this.el.dom.removeAttribute('name');
            }
            if(Ext.isGecko){
                this.el.dom.setAttribute('autocomplete', 'off');
            }
     
            if(!this.lazyInit){
                this.initList();
            }else{
                this.on('focus', this.initList, this, {single: true});
            }
     
            if(!this.editable){
                this.editable = true;
                this.setEditable(false);
            }
            this.setValue(disValue);
        },
     
        initList : function(){
            if(!this.list){
                var cls = 'x-combo-list';
     
                this.list = new Ext.Layer({
                    shadow: this.shadow, cls: [cls, this.listClass].join(' '), constrain:false
                });
     
                var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
                this.list.setWidth(lw);
                this.list.swallowEvent('mousewheel');
                this.assetHeight = 0;
     
                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.on('mouseover', this.onViewOver, this);
                this.innerList.on('mousemove', this.onViewMove, this);
                this.innerList.setWidth(lw - this.list.getFrameWidth('lr'))
     
                if(this.pageSize){
                    this.footer = this.list.createChild({cls:cls+'-ft'});
                    this.pageTb = new Ext.PagingToolbar({
                        store:this.store,
                        pageSize: this.pageSize,
                        renderTo:this.footer
                    });
                    this.assetHeight += this.footer.getHeight();
                }
     
                if(!this.tpl){
                    //alert(cls);
                    //x-combo-list-item
                    this.tpl = '<tpl for="."><div class="'+cls+'-item"><span class="unchecked" style="padding-bottom: 1px;" id="checkBox_{' + this.displayField + '}">&nbsp;&nbsp;&nbsp;&nbsp;</span>{' + this.displayField + '}</div></tpl>';
                }
                this.view = new Ext.DataView({
                    applyTo: this.innerList,
                    tpl: this.tpl,
                    singleSelect: true,
                    selectedClass: this.selectedClass,
                    itemSelector: this.itemSelector || '.' + cls + '-item'
                });
     
                this.view.on('click', this.onViewClick, this);
     
                this.bindStore(this.store, true);
     
                if(this.resizable){
                    this.resizer = new Ext.Resizable(this.list,  {
                       pinned:true, handles:'se'
                    });
                    this.resizer.on('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);
                    this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
                }
            }
        },
     
        bindStore : function(store, initial){
            if(this.store && !initial){
                this.store.un('beforeload', this.onBeforeLoad, this);
                this.store.un('load', this.onLoad, this);
                this.store.un('loadexception', this.collapse, this);
                if(!store){
                    this.store = null;
                    if(this.view){
                        this.view.setStore(null);
                    }
                }
            }
            if(store){
                this.store = Ext.StoreMgr.lookup(store);
     
                this.store.on('beforeload', this.onBeforeLoad, this);
                this.store.on('load', this.onLoad, this);
                this.store.on('loadexception', this.collapse, this);
     
                if(this.view){
                    this.view.setStore(store);
                }
            }
        },
     
        // private
        initEvents : function(){
            Ext.form.ComboBox.superclass.initEvents.call(this);
     
            this.keyNav = new Ext.KeyNav(this.el, {
                "up" : function(e){
                    this.inKeyMode = true;
                    this.selectPrev();
                },
     
                "down" : function(e){
                    if(!this.isExpanded()){
                        this.onTriggerClick();
                    }else{
                        this.inKeyMode = true;
                        this.selectNext();
                    }
                },
     
                "enter" : function(e){
                    this.onViewClick();
                    //return true;
                },
     
                "esc" : function(e){
                    this.collapse();
                },
     
                "tab" : function(e){
                    this.onViewClick(false);
                    return true;
                },
     
                scope : this,
     
                doRelay : function(foo, bar, hname){
                    if(hname == 'down' || this.scope.isExpanded()){
                       return Ext.KeyNav.prototype.doRelay.apply(this, arguments);
                    }
                    return true;
                },
     
                forceKeyDown : true
            });
            this.queryDelay = Math.max(this.queryDelay || 10,
                    this.mode == 'local' ? 10 : 250);
            this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
            if(this.typeAhead){
                this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
            }
            if(this.editable !== false){
                this.el.on("keyup", this.onKeyUp, this);
            }
            if(this.forceSelection){
                this.on('blur', this.doForce, this);
            }
        },
     
        onDestroy : function(){
            if(this.view){
                this.view.el.removeAllListeners();
                this.view.el.remove();
                this.view.purgeListeners();
            }
            if(this.list){
                this.list.destroy();
            }
            this.bindStore(null);
            Ext.form.ComboBox.superclass.onDestroy.call(this);
        },
     
        // private
        fireKey : function(e){
            if(e.isNavKeyPress() && !this.list.isVisible()){
                this.fireEvent("specialkey", this, e);
            }
        },
     
        // private
        onResize: function(w, h){
            Ext.form.ComboBox.superclass.onResize.apply(this, arguments);
            if(this.list && this.listWidth === undefined){
                var lw = Math.max(w, this.minListWidth);
                this.list.setWidth(lw);
                this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
            }
        },
     
        // private
        onDisable: function(){
            Ext.form.ComboBox.superclass.onDisable.apply(this, arguments);
            if(this.hiddenField){
                this.hiddenField.disabled = this.disabled;
            }
        },
        setEditable : function(value){
            if(value == this.editable){
                return;
            }
            this.editable = value;
            if(!value){
                this.el.dom.setAttribute('readOnly', true);
                this.el.on('mousedown', this.onTriggerClick,  this);
                this.el.addClass('x-combo-noedit');
            }else{
                this.el.dom.setAttribute('readOnly', false);
                this.el.un('mousedown', this.onTriggerClick,  this);
                this.el.removeClass('x-combo-noedit');
            }
        },
     
        // private
        onBeforeLoad : function(){
            if(!this.hasFocus){
                return;
            }
            this.innerList.update(this.loadingText ?
                   '<div class="loading-indicator">'+this.loadingText+'</div>' : '');
            this.restrictHeight();
            this.selectedIndex = -1;
        },
     
        // private
        onLoad : function(){
            if(!this.hasFocus){
                return;
            }
            if(this.store.getCount() > 0){
                this.expand();
                this.restrictHeight();
                if(this.lastQuery == this.allQuery){
                    if(this.editable){
                        this.el.dom.select();
                    }
                    if(!this.selectByValue(this.value, true)){
                        this.select(0, true);
                    }
                }else{
                    this.selectNext();
                    if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
                        this.taTask.delay(this.typeAheadDelay);
                    }
                }
            }else{
                this.onEmptyResults();
            }
        },
     
        // private
        onTypeAhead : function(){
            if(this.store.getCount() > 0){
                var r = this.store.getAt(0);
                var newValue = r.data[this.displayField];
                var len = newValue.length;
                var selStart = this.getRawValue().length;
                if(selStart != len){
                    this.setRawValue(newValue);
                    this.selectText(selStart, newValue.length);
                }
            }
        },
        // private
        onSelect : function(record, index){
            if(this.fireEvent('beforeselect', this, record, index) !== false){
                var r = this.store.getAt(index);
                var newValue = r.data[this.displayField];
                var check=document.getElementById("checkBox_"+newValue);
                if(check.className=="checked"){
                    check.className="unchecked"
                }else{
                    check.className="checked"
                }
                var value=""; 
                var hiddenValue="";
                for(var i=0;i<this.store.data.length;i++){
                     var r = this.store.getAt(i);   
                     newValue = r.data[this.displayField];
                     check=document.getElementById("checkBox_"+newValue);
                     if(check.className=="checked"){
                         value+= r.data[this.displayField]+this.displaySeparator;
                         hiddenValue+= r.data[this.valueField]+this.valueSeparator;
                     }
                }
                if(value.length>1){
                    value=value.substring(0,value.length-this.displaySeparator.length);
                }
                if(hiddenValue.length>1){
                    hiddenValue=hiddenValue.substring(0,value.length-this.valueSeparator.length);
                }
                this.setValue(value);
                this.hiddenField.value=hiddenValue;
                this.fireEvent('select', this, record, index);
            }
        },
        getValue : function(){
            if(this.valueField){
                return typeof this.value != 'undefined' ? this.value : '';
            }else{
                return Ext.form.ComboBox.superclass.getValue.call(this);
            }
        },
     
        /**
         * Clears any text/value currently set in the field
         */
        clearValue : function(){
            if(this.hiddenField){
                this.hiddenField.value = '';
            }
            this.setRawValue('');
            this.lastSelectionText = '';
            this.applyEmptyText();
        },
        setValue : function(v){
            var text = v;
            if(this.valueField){
                var r = this.findRecord(this.valueField, v);
                if(r){
                    text = r.data[this.displayField];
                }else if(this.valueNotFoundText !== undefined){
                    text = this.valueNotFoundText;
                }
            }
            this.lastSelectionText = text;
            Ext.form.ComboBox.superclass.setValue.call(this, text);
            this.value = v;
        },
     
        // private
        findRecord : function(prop, value){
            var record;
            if(this.store.getCount() > 0){
                this.store.each(function(r){
                    if(r.data[prop] == value){
                        record = r;
                        return false;
                    }
                });
            }
            return record;
        },
     
        // private
        onViewMove : function(e, t){
            this.inKeyMode = false;
        },
     
        // private
        onViewOver : function(e, t){
            if(this.inKeyMode){ // prevent key nav and mouse over conflicts
                return;
            }
            var item = this.view.findItemFromChild(t);
            if(item){
                var index = this.view.indexOf(item);
                this.select(index, false);
            }
        },
     
        // private
        onViewClick : function(doFocus){
            var index = this.view.getSelectedIndexes()[0];
            var r = this.store.getAt(index);
            if(r){
                this.onSelect(r, index);
            }
            if(doFocus !== false){
                this.el.focus();
            }
        },
     
        // private
        restrictHeight : function(){
            this.innerList.dom.style.height = '';
            var inner = this.innerList.dom;
            var fw = this.list.getFrameWidth('tb');
            var h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight);
            this.innerList.setHeight(h < this.maxHeight ? 'auto' : this.maxHeight);
            this.list.beginUpdate();
            this.list.setHeight(this.innerList.getHeight()+fw+(this.resizable?this.handleHeight:0)+this.assetHeight);
            this.list.alignTo(this.el, this.listAlign);
            this.list.endUpdate();
        },
     
        // private
        onEmptyResults : function(){
            this.collapse();
        },
     
        /**
         * Returns true if the dropdown list is expanded, else false.
         */
        isExpanded : function(){
            return this.list && this.list.isVisible();
        },
        selectByValue : function(v, scrollIntoView){
            if(v !== undefined && v !== null){
                var r = this.findRecord(this.valueField || this.displayField, v);
                if(r){
                    this.select(this.store.indexOf(r), scrollIntoView);
                    return true;
                }
            }
            return false;
        },
        select : function(index, scrollIntoView){
            
            this.selectedIndex = index;
            this.view.select(index);
            if(scrollIntoView !== false){
                var el = this.view.getNode(index);
                if(el){
                    this.innerList.scrollChildIntoView(el, false);
                }
            }
        },
     
        // private
        selectNext : function(){
            var ct = this.store.getCount();
            if(ct > 0){
                if(this.selectedIndex == -1){
                    this.select(0);
                }else if(this.selectedIndex < ct-1){
                    this.select(this.selectedIndex+1);
                }
            }
        },
     
        // private
        selectPrev : function(){
            var ct = this.store.getCount();
            if(ct > 0){
                if(this.selectedIndex == -1){
                    this.select(0);
                }else if(this.selectedIndex != 0){
                    this.select(this.selectedIndex-1);
                }
            }
        },
     
        // private
        onKeyUp : function(e){
            if(this.editable !== false && !e.isSpecialKey()){
                this.lastKey = e.getKey();
                this.dqTask.delay(this.queryDelay);
            }
        },
     
        // private
        validateBlur : function(){
            return !this.list || !this.list.isVisible();   
        },
     
        // private
        initQuery : function(){
            this.doQuery(this.getRawValue());
        },
     
        // private
        doForce : function(){
            if(this.el.dom.value.length > 0){
                this.el.dom.value =
                    this.lastSelectionText === undefined ? '' : this.lastSelectionText;
                this.applyEmptyText();
            }
        },
        doQuery : function(q, forceAll){
            if(q === undefined || q === null){
                q = '';
            }
            var qe = {
                query: q,
                forceAll: forceAll,
                combo: this,
                cancel:false
            };
            if(this.fireEvent('beforequery', qe)===false || qe.cancel){
                return false;
            }
            q = qe.query;
            forceAll = qe.forceAll;
            if(forceAll === true || (q.length >= this.minChars)){
                if(this.lastQuery !== q){
                    this.lastQuery = q;
                    if(this.mode == 'local'){
                        this.selectedIndex = -1;
                        if(forceAll){
                            this.store.clearFilter();
                        }else{
                            this.store.filter(this.displayField, q);
                        }
                        this.onLoad();
                    }else{
                        this.store.baseParams[this.queryParam] = q;
                        this.store.load({
                            params: this.getParams(q)
                        });
                        this.expand();
                    }
                }else{
                    this.selectedIndex = -1;
                    this.onLoad();   
                }
            }
        },
     
        // private
        getParams : function(q){
            var p = {};
            //p[this.queryParam] = q;
            if(this.pageSize){
                p.start = 0;
                p.limit = this.pageSize;
            }
            return p;
        },
        /**
         * Hides the dropdown list if it is currently expanded. Fires the 'collapse' event on completion.
         */
        collapse : function(){
            if(!this.isExpanded()){
                return;
            }
            this.list.hide();
            Ext.getDoc().un('mousewheel', this.collapseIf, this);
            Ext.getDoc().un('mousedown', this.collapseIf, this);
            this.fireEvent('collapse', this);
        },
        // private
        collapseIf : function(e){
            if(!e.within(this.wrap) && !e.within(this.list)){
                this.collapse();
            }
        },
        
        /**
         * Expands the dropdown list if it is currently hidden. Fires the 'expand' event on completion.
         */
        expand : function(){
            if(this.isExpanded() || !this.hasFocus){
                return;
            }
            this.list.alignTo(this.wrap, this.listAlign);
            var hvalueArray=this.hiddenField.value.split(this.valueSeparator);
            for(var i=0;i<this.store.data.length;i++){
                 var r = this.store.getAt(i);   
                 var newValue = r.data[this.displayField];
                  var v=r.data[this.valueField];
                  for(var j=0;j<hvalueArray.length;j++){
                      if(hvalueArray[j]==v){
                          document.getElementById("checkBox_"+newValue).className="checked";
                      }
                  }
                 
            } 
            this.list.show();
            Ext.getDoc().on('mousewheel', this.collapseIf, this);
            Ext.getDoc().on('mousedown', this.collapseIf, this);
            this.fireEvent('expand', this);
        },
     
        // private
        // Implements the default empty TriggerField.onTriggerClick function
        onTriggerClick : function(){
            if(this.disabled){
                return;
            }
            if(this.isExpanded()){
                this.collapse();
                this.el.focus();
            }else {
                this.onFocus({});
                if(this.triggerAction == 'all') {
                    this.doQuery(this.allQuery, true);
                } else {
                    this.doQuery(this.getRawValue());
                }
                this.el.focus();
            }
        }
    });
    Ext.reg('multicombo', Ext.form.MultiComboBox);

    Ext.hoo.form.InterestMultiComboBox.js

    /**
     * @function 支持多选的combox 
     * @auhor: hoojo
     * @createDate: Sep 10, 2010 10:32:00 PM
     * @blog: blog.csdn.net/IBM_hoojo
     * @email: hoojo_@126.com
     * @class Ext.hoo.form.InterestMultiComboBox
     * @extends Ext.form.MultiComboBox
     */
    Ext.ns("Ext.hoo.form");
    Ext.hoo.form.InterestMultiComboBox = Ext.extend(Ext.form.MultiComboBox, {
         constructor: function () {
             Ext.hoo.form.InterestMultiComboBox.superclass.constructor.call(this, {
                 renderTo: "show",
                  250,
                mode: "local",
                fieldLabel: "多选下拉框",
                store: new Ext.data.SimpleStore({
                    fields: ["textAttr", "valueAttr"],
                    data: [
                        ["打球", "batting"],
                        ["看书", "lookbook"],
                        ["睡觉", "sleeping"],
                        ["购物", "shopping"],
                        ["打游戏", "games"],
                        ["唱歌", "sing"]
                    ]
                }),
                editable: true,
                emptyText:"请选择",
                //allowBlank: false,
                valueField: "textAttr",
                displayField: "valueAttr",
                labelSeparator: ":",
                valueSeparator: "#",
                displaySeparator: ",",
                //value:"batting,sleeping",
                hiddenName: "interest",
                forceSelection: true,
                triggerAction: "all"
             });
             this.on("select", function (field, record, index) {
                 alert(field.getValue() + "%%%%" + field.getRawValue() + Ext.fly("interest").dom.value);
             }, this);
         }
    });
     
    Ext.onReady(function () {
        Ext.BLANK_IMAGE_URL = "../ext2/resources/images/default/s.gif";
        Ext.QuickTips.init();
        Ext.form.Field.prototype.msgTarget = "qtip";
        
        new Ext.hoo.form.InterestMultiComboBox();
    });

    五、动态Combobox Tree(下拉列表树)组件

    clip_image008

    可以多选、单选、checkbox

    需要的文件

    动态下列列表树插件:Ext.ux.form.DynamicTreeCombox.js

    示例文件:Ext.hoo.form.DynaTreeCombo.js

    代码如下:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
        <head>
            <title>form Component -- MultiComboBox</title>
            <meta http-equiv="pragma" content="no-cache"/>
            <meta http-equiv="cache-control" content="no-cache"/>
            <meta http-equiv="expires" content="0"/>
            <meta http-equiv="content-Type" content="text/html; charset=utf-8"/>
            <meta http-equiv="author" content="hoojo"/>
            <meta http-equiv="email" content="hoojo_@126.com"/>
            <meta http-equiv="ext-lib" content="version 2.2"/>
            <meta http-equiv="blog" content="http://blog.csdn.net/IBM_hoojo"/>        
            <link rel="stylesheet" type="text/css" href="../ext2/resources/css/ext-all.css"/>
            <script type="text/javascript" src="../ext2/adapter/ext/ext-base.js"></script>
            <script type="text/javascript" src="../ext2/ext-all.js"></script>
            <script type="text/javascript" src="../ext2/build/locale/ext-lang-zh_CN-min.js"></script>
            <script type="text/javascript" src="Ext.ux.form.DynamicTreeCombox.js"></script>
            <script type="text/javascript" src="Ext.hoo.form.DynaTreeCombo.js"></script>
      </head>
      
      <body>
          <div id="show" style="float: left; margin: 100px 0 0 100px;"></div>
          <div id="showBasic" style="float: left; margin: 100px 0 0 100px;"></div>
          <div id="showConstom" style="float: left; margin: 100px 0 0 100px;"></div>
      </body>
    </html>

    Ext.ux.form.DynamicTreeCombox.js

    Ext.ns("Ext.ux.form");   
    Ext.ux.form.DynamicTreeCombox = Ext.extend(Ext.form.ComboBox, {   
        initComponent:function(){   
            Ext.ux.form.DynamicTreeCombox.superclass.initComponent.call(this);   
            this.addEvents('beforeClickNode','afterClickNode', 'select');   
            if(!this.tree){   
                var root = this.root || new Ext.tree.AsyncTreeNode();
                this.tree = new Ext.tree.TreePanel({   
                    containerScroll: true,   
                    rootVisible: false, 
                    border: false,
                    root: root   
                });   
                this.tree.loader = new Ext.tree.TreeLoader(this.loaderConfig||{dataUrl:"",baseAttrs:{}});   
                this.tree.loader.addListener("beforeload",this.beforeLoad,this);   
                this.tree.loader.addListener("load",this.onLoad,this);   
                this.tree.addListener('collapsenode',this.onNodeCollapse,this);   
                this.tree.addListener('expandnode',this.onNodeExpand,this);   
            }   
            var fieldMp = {   
                text: "text",   
                qtip: "qtip",   
                parentFuncId: "id",   
                icon: "icon"  
            };   
            if(!this.fieldMapping){   
                this.fieldMapping = fieldMp;   
            }else{   
                Ext.applyIf(this.fieldMapping, fieldMp);   
            }   
        },   
        initList:function(){   
            if(!this.list){   
                var cls = 'x-combo-list';   
                this.list = new Ext.Layer({   
                    shadow: this.shadow, cls: [cls, this.listClass].join(' '), constrain:false  
                });   
                var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);   
                this.list.setWidth(lw);   
                this.list.swallowEvent('mousewheel');   
                this.innerList = this.list.createChild({cls:cls+'-inner'});   
                this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));   
                this.innerList.setHeight("100%");   
            }   
        },   
           
        doQuery:function(){   
            if(this.expandAll){   
                var loader=this.tree.loader;   
                if(loader.baseAttrs){   
                    Ext.apply(loader.baseAttrs,{expanded:this.expandAll});   
                }else{   
                    loader.baseAttrs={expanded:this.expandAll};   
                }              
            }   
            if(!this.tree.rendered){   
                this.tree.render(this.innerList);   
                this.tree.addListener("click",this.clickNode,this);   
            }   
            this.expand();   
        },   
           
        beforeLoad:function(loader,node){   
            if(node!=node.getOwnerTree().root){                                                                                                                    
                loader.baseParams.parentFuncId=node.attributes[this.fieldMapping.parentFuncId];                                                                                                                    
            }   
        },   
        
        onLoad:function(loader,node,res){   
            var nodeArr=node.childNodes;   
            for(var i=0,j=nodeArr.length;i<j;i++){   
                if(nodeArr[i].attributes[this.fieldMapping.icon]){   
                    nodeArr[i].getUI().getIconEl().src=nodeArr[i].attributes[this.fieldMapping.icon];   
                }   
                nodeArr[i].setText(nodeArr[i].attributes[this.fieldMapping.text]);   
                nodeArr[i].ui.textNode.setAttribute("qtip", nodeArr[i].attributes[this.fieldMapping.qtip]);   
            }      
        },   
           
        clickNode:function(node){   
            if(this.fireEvent('beforeClickNode',this,node)){   
                this.setValue(node.attributes[this.displayField]); 
                this.value = node.attributes[this.valField || "id"]; 
            }   
            this.fireEvent("afterClickNode",this,node);        
            this.fireEvent("select",this,node);        
            this.collapse();   
        },   
        onNodeCollapse:function(node){   
            this.list.setHeight(this.tree.getEl().getHeight()+2);   
        },   
        
        getValue: function () {
            return this.value;
        },
        
        onNodeExpand:function(node){   
            this.list.setHeight(this.tree.getEl().getHeight()+2);   
        },   
           
        onDestroy:function(){   
            if(this.view){   
                this.view.el.removeAllListeners();   
                this.view.el.remove();   
                this.view.purgeListeners();   
            }   
            if(this.tree.loader){   
                this.tree.loader.purgeListeners();   
            }   
            if(this.tree){   
                this.tree.el.removeAllListerers();   
                this.tree.el.remove();   
                this.tree.purgeListeners();   
            }   
            if(this.innerList){   
                this.innerList.destroy();   
            }   
            if(this.list){   
                this.list.destroy();   
            }   
            Ext.form.ComboBox.superclass.onDestroy.call(this);   
        }   
    });   
      
    Ext.reg("treecombox",Ext.ux.form.DynamicTreeCombox);

    Ext.hoo.form.DynaTreeCombo.js

    /**
     * @function 动态tree的combobox,本地数据
     * @auhor: hoojo
     * @createDate: Sep 11, 2010 6:33:13 PM
     * @blog: blog.csdn.net/IBM_hoojo
     * @email: hoojo_@126.com
     * @class Ext.hoo.form.DynaTreeCombo
     * @extends Ext.ux.form.DynamicTreeCombox
     */
    Ext.ns("Ext.hoo.form");
    Ext.hoo.form.DynaTreeCombo = Ext.extend(Ext.ux.form.DynamicTreeCombox, {
        constructor: function () {
            Ext.hoo.form.DynaTreeCombo.superclass.constructor.call(this, {
                renderTo: "show",
                expandAll: false,
                readOnly: true,
                 200,
                displayField: "text",
                valField: "id",
                root: new Ext.tree.AsyncTreeNode({
                    text: "ExtJS",
                    id: "0",
                    children: [{
                        text: "adpter",
                        qtip: "这是一个adpter的tip",
                        children: [{
                            text: "ext",
                            leaf: true,
                            qtip: "这是一个ext的tip",
                            checked: true
                        },{
                            text: "yui",
                            leaf: true
                        },{
                            text: "jquery",
                            leaf: true
                        },{
                            text: "prototype",
                            leaf: true,
                            checked: false
                        }]
                    },{
                        text: "air",
                        checked: false,
                        children: [{
                            text: "air.jsb",
                            leaf: true
                        },{
                            text: "ext-air.js",
                            leaf: true
                        }]
                    },{
                        text: "docs"
                    }]
                })
            });
            this.on("select", function (field, node) {
                alert(field.getValue() + "###" + field.getRawValue() + "##" + node.text);
            }, this);
            this.on("check", function (field, node) {
                alert(field.getValue() + "###" + field.getRawValue() + "##" + node.text);
            }, this);
        }
    });
     
    /**
     * @function DynamicTreeCombox 后台数据
     * @auhor: hoojo
     * @createDate: Sep 11, 2010 10:30:27 PM
     * @blog: blog.csdn.net/IBM_hoojo
     * @email: hoojo_@126.com
     */
    Ext.hoo.form.AsyncBasicDynaTreeCombo = Ext.extend(Ext.ux.form.DynamicTreeCombox, {
        constructor: function () {
            Ext.hoo.form.AsyncBasicDynaTreeCombo.superclass.constructor.call(this, {
                renderTo: "showBasic",
                expandAll: false,
                readOnly: true,
                 200,
                displayField: "text",
                valField: "id",
                loaderConfig:{   
                    dataUrl: "../ServiceDataServlet?method=basic"//加载树的URL   
                }
            });
            this.on("select", function (field, node) {
                alert(field.getValue() + "###" + field.getRawValue() + "##" + node.text);
            }, this);
        }
    });
     
    /**
     * @function 后台数据 
     * @auhor: hoojo
     * @createDate: Sep 11, 2010 10:30:59 PM
     * @blog: blog.csdn.net/IBM_hoojo
     * @email: hoojo_@126.com
     */
     
    Ext.hoo.form.AsyncConstomDynaTreeCombo = Ext.extend(Ext.ux.form.DynamicTreeCombox, {
        constructor: function () {
            Ext.hoo.form.AsyncConstomDynaTreeCombo.superclass.constructor.call(this, {
                renderTo: "showConstom",
                expandAll: false,
                readOnly: true,
                 200,
                displayField: "text",
                valField: "id",
                loaderConfig:{   
                    dataUrl: "../ServiceDataServlet?method=constom", 
                    baseParams:{parentFuncId:""}//如果传递parentFuncId就会查询当前id下的节点
                },   
                //后台数据中没有text、qtip、icon、parentFuncId属性,需加上fieldMapping进行属性映射,如果后台返回数据中有此属性可省略 
                fieldMapping: {  
                    text: "text",//映射node的text字段   
                    qtip: "tip",//映射node的qtip字段   
                    parentFuncId: "text"//映射动态请求后台的text属性作为请求参数   
                    //icon: "img"
                }
            });
            this.on("select", function (field, node) {
                alert(field.getValue() + "###" + field.getRawValue() + "##" + node.text);
            }, this);
        }
    });
     
    Ext.onReady(function () {
        Ext.BLANK_IMAGE_URL = "../ext2/resources/images/default/s.gif";
        Ext.QuickTips.init();
        Ext.form.Field.prototype.msgTarget = "qtip";
        
        new Ext.hoo.form.DynaTreeCombo();
        new Ext.hoo.form.AsyncBasicDynaTreeCombo();
        new Ext.hoo.form.AsyncConstomDynaTreeCombo();
    });

    ServiceDataServlet.java

    package com.hoo.servlet;
     
    import java.io.IOException;
    import java.io.PrintWriter;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
    public class ServiceDataServlet extends HttpServlet {
     
        private static final long serialVersionUID = 1L;
     
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
     
            response.setContentType("text/json");
            response.setCharacterEncoding("utf-8");
            PrintWriter out = response.getWriter();
            String method = request.getParameter("method");
            StringBuilder sb = new StringBuilder();
            if ("basic".equals(method)) {
                sb.append("[")
                    .append("{").append("text:\"").append("adpter").append("\", qtip: \"").append("qtip提示:ADPTER").append("\",");
                    sb.append("children: [")
                        .append("{").append("text:\"").append("ext").append("\", qtip: \"").append("qtip提示:ext").append("\",")
                        .append("leaf: true").append("},")
                        .append("{").append("text:\"").append("jquery")
                        .append("\",").append("leaf: true").append("}]").append("},")
                        .append("{").append("text:\"").append("air").append("\",");
                        sb.append("children: [")
                            .append("{").append("text:\"").append("air.jsb")
                            .append("\",").append("leaf: true").append("},")
                            .append("{").append("text:\"").append("ext-air.js")
                            .append("\",").append("leaf: true").append("}]").append("},")
                            .append("{").append("text:\"").append("readMe.text").append("\",")
                            .append("leaf: true}");
                sb.append("]");
            }
            if ("constom".equals(method)) {
                sb.append("[")
                    .append("{").append("text:\"").append("adpter").append("\", tip: \"").append("ADPTER").append("\",");
                    sb.append("children:[")
                        .append("{").append("text:\"").append("ext").append("\", tip: \"").append("EXT").append("\",")
                        .append("leaf: true").append("},")
                        .append("{").append("text:\"").append("jquery").append("\", tip: \"").append("JQUERY").append("\",")
                        .append("leaf: true").append("}]},")
                        .append("{").append("text:\"").append("air").append("\", tip: \"").append("AIR").append("\",");
                        sb.append("children:[")
                            .append("{").append("text:\"").append("air.jsb").append("\", tip: \"").append("AIR.JSB").append("\",")
                            .append("leaf: true").append("},")
                            .append("{").append("text:\"").append("ext-air.js").append("\", tip: \"").append("EXT-AIR.JS").append("\",")
                            .append("leaf: true").append("}]").append("},")
                            .append("{").append("text:\"").append("readMe.text").append("\", tip: \"").append("README.TEXT").append("\",")
                            .append("leaf: true}");
                sb.append("]");
            }
            out.print(sb.toString());
            out.flush();
            out.close();
        }
     
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            this.doGet(request, response);
        }
    }
  • 作者:hoojo
    出处:
    blog:http://blog.csdn.net/IBM_hoojo
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权所有,转载请注明出处 本文出自:
分享道版权所有,欢迎转载,转载请注明出处,谢谢
收藏
关注
评论
查看全文
  • 相关阅读:
    IOS越狱开发错误解决
    IOS越狱开发环境搭建
    ios越狱开发
    IOS开发常用的开源组件
    ios日期比较
    IOS RGB颜色转换
    UILabel基本用法
    ios根据字体大小设置
    第五篇 窗口管理机制之输入机制--管道过滤器模式
    第四篇 ANDROID窗口管理服务实现机制--远程代理模式
  • 原文地址:https://www.cnblogs.com/hoojo/p/2369769.html
  • Copyright © 2011-2022 走看看