MOVED Roo/bootstrap/TriggerField.js to Roo/bootstrap/form/TriggerField.js
authorAlan Knowles <alan@roojs.com>
Fri, 30 Jul 2021 07:09:46 +0000 (15:09 +0800)
committerAlan Knowles <alan@roojs.com>
Fri, 30 Jul 2021 07:09:46 +0000 (15:09 +0800)
MOVED Roo/bootstrap/TextArea.js to Roo/bootstrap/form/TextArea.js
Roo/bootstrap/TriggerField.js
Roo/bootstrap/TextArea.js
MOVED Roo/bootstrap/TimeField.js to Roo/bootstrap/form/TimeField.js
Roo/bootstrap/TimeField.js
MOVED Roo/bootstrap/SecurePass.js to Roo/bootstrap/form/SecurePass.js
Roo/bootstrap/SecurePass.js

Roo/bootstrap/form/SecurePass.js [new file with mode: 0644]
Roo/bootstrap/form/TextArea.js [new file with mode: 0644]
Roo/bootstrap/form/TimeField.js [new file with mode: 0644]
Roo/bootstrap/form/TriggerField.js [new file with mode: 0644]

diff --git a/Roo/bootstrap/form/SecurePass.js b/Roo/bootstrap/form/SecurePass.js
new file mode 100644 (file)
index 0000000..bbb84ca
--- /dev/null
@@ -0,0 +1,354 @@
+/*
+ * - LGPL
+ *
+ * Input
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.SecurePass
+ * @extends Roo.bootstrap.Input
+ * Bootstrap SecurePass class
+ *
+ * 
+ * @constructor
+ * Create a new SecurePass
+ * @param {Object} config The config object
+ */
+Roo.bootstrap.SecurePass = function (config) {
+    // these go here, so the translation tool can replace them..
+    this.errors = {
+        PwdEmpty: "Please type a password, and then retype it to confirm.",
+        PwdShort: "Your password must be at least 6 characters long. Please type a different password.",
+        PwdLong: "Your password can't contain more than 16 characters. Please type a different password.",
+        PwdBadChar: "The password contains characters that aren't allowed. Please type a different password.",
+        IDInPwd: "Your password can't include the part of your ID. Please type a different password.",
+        FNInPwd: "Your password can't contain your first name. Please type a different password.",
+        LNInPwd: "Your password can't contain your last name. Please type a different password.",
+        TooWeak: "Your password is Too Weak."
+    },
+    this.meterLabel = "Password strength:";
+    this.pwdStrengths = ["Too Weak", "Weak", "Medium", "Strong"];
+    this.meterClass = [
+        "roo-password-meter-tooweak", 
+        "roo-password-meter-weak", 
+        "roo-password-meter-medium", 
+        "roo-password-meter-strong", 
+        "roo-password-meter-grey"
+    ];
+    
+    this.errors = {};
+    
+    Roo.bootstrap.SecurePass.superclass.constructor.call(this, config);
+}
+
+Roo.extend(Roo.bootstrap.SecurePass, Roo.bootstrap.Input, {
+    /**
+     * @cfg {String/Object} errors A Error spec, or true for a default spec (defaults to
+     * {
+     *  PwdEmpty: "Please type a password, and then retype it to confirm.",
+     *  PwdShort: "Your password must be at least 6 characters long. Please type a different password.",
+     *  PwdLong: "Your password can't contain more than 16 characters. Please type a different password.",
+     *  PwdBadChar: "The password contains characters that aren't allowed. Please type a different password.",
+     *  IDInPwd: "Your password can't include the part of your ID. Please type a different password.",
+     *  FNInPwd: "Your password can't contain your first name. Please type a different password.",
+     *  LNInPwd: "Your password can't contain your last name. Please type a different password."
+     * })
+     */
+    // private
+    
+    meterWidth: 300,
+    errorMsg :'',    
+    errors: false,
+    imageRoot: '/',
+    /**
+     * @cfg {String/Object} Label for the strength meter (defaults to
+     * 'Password strength:')
+     */
+    // private
+    meterLabel: '',
+    /**
+     * @cfg {String/Object} pwdStrengths A pwdStrengths spec, or true for a default spec (defaults to
+     * ['Weak', 'Medium', 'Strong'])
+     */
+    // private    
+    pwdStrengths: false,    
+    // private
+    strength: 0,
+    // private
+    _lastPwd: null,
+    // private
+    kCapitalLetter: 0,
+    kSmallLetter: 1,
+    kDigit: 2,
+    kPunctuation: 3,
+    
+    insecure: false,
+    // private
+    initEvents: function ()
+    {
+        Roo.bootstrap.SecurePass.superclass.initEvents.call(this);
+
+        if (this.el.is('input[type=password]') && Roo.isSafari) {
+            this.el.on('keydown', this.SafariOnKeyDown, this);
+        }
+
+        this.el.on('keyup', this.checkStrength, this, {buffer: 50});
+    },
+    // private
+    onRender: function (ct, position)
+    {
+        Roo.bootstrap.SecurePass.superclass.onRender.call(this, ct, position);
+        this.wrap = this.el.wrap({cls: 'x-form-field-wrap'});
+        this.trigger = this.wrap.createChild({tag: 'div', cls: 'StrengthMeter ' + this.triggerClass});
+
+        this.trigger.createChild({
+                  cn: [
+                    {
+                    //id: 'PwdMeter',
+                    tag: 'div',
+                    cls: 'roo-password-meter-grey col-xs-12',
+                    style: {
+                        //width: 0,
+                        //width: this.meterWidth + 'px'                                                
+                        }
+                    },
+                    {                           
+                        cls: 'roo-password-meter-text'                          
+                    }
+                ]            
+        });
+
+         
+        if (this.hideTrigger) {
+            this.trigger.setDisplayed(false);
+        }
+        this.setSize(this.width || '', this.height || '');
+    },
+    // private
+    onDestroy: function ()
+    {
+        if (this.trigger) {
+            this.trigger.removeAllListeners();
+            this.trigger.remove();
+        }
+        if (this.wrap) {
+            this.wrap.remove();
+        }
+        Roo.bootstrap.TriggerField.superclass.onDestroy.call(this);
+    },
+    // private
+    checkStrength: function ()
+    {
+        var pwd = this.inputEl().getValue();
+        if (pwd == this._lastPwd) {
+            return;
+        }
+
+        var strength;
+        if (this.ClientSideStrongPassword(pwd)) {
+            strength = 3;
+        } else if (this.ClientSideMediumPassword(pwd)) {
+            strength = 2;
+        } else if (this.ClientSideWeakPassword(pwd)) {
+            strength = 1;
+        } else {
+            strength = 0;
+        }
+        
+        Roo.log('strength1: ' + strength);
+        
+        //var pm = this.trigger.child('div/div/div').dom;
+        var pm = this.trigger.child('div/div');
+        pm.removeClass(this.meterClass);
+        pm.addClass(this.meterClass[strength]);
+                
+        
+        var pt = this.trigger.child('/div').child('>*[class=roo-password-meter-text]').dom;        
+                
+        pt.innerHTML = this.meterLabel + '&nbsp;' + this.pwdStrengths[strength];
+        
+        this._lastPwd = pwd;
+    },
+    reset: function ()
+    {
+        Roo.bootstrap.SecurePass.superclass.reset.call(this);
+        
+        this._lastPwd = '';
+        
+        var pm = this.trigger.child('div/div');
+        pm.removeClass(this.meterClass);
+        pm.addClass('roo-password-meter-grey');        
+        
+        
+        var pt = this.trigger.child('/div').child('>*[class=roo-password-meter-text]').dom;        
+        
+        pt.innerHTML = '';
+        this.inputEl().dom.type='password';
+    },
+    // private
+    validateValue: function (value)
+    {
+        if (!Roo.bootstrap.SecurePass.superclass.validateValue.call(this, value)) {
+            return false;
+        }
+        if (value.length == 0) {
+            if (this.allowBlank) {
+                this.clearInvalid();
+                return true;
+            }
+
+            this.markInvalid(this.errors.PwdEmpty);
+            this.errorMsg = this.errors.PwdEmpty;
+            return false;
+        }
+        
+        if(this.insecure){
+            return true;
+        }
+        
+        if (!value.match(/[\x21-\x7e]+/)) {
+            this.markInvalid(this.errors.PwdBadChar);
+            this.errorMsg = this.errors.PwdBadChar;
+            return false;
+        }
+        if (value.length < 6) {
+            this.markInvalid(this.errors.PwdShort);
+            this.errorMsg = this.errors.PwdShort;
+            return false;
+        }
+        if (value.length > 16) {
+            this.markInvalid(this.errors.PwdLong);
+            this.errorMsg = this.errors.PwdLong;
+            return false;
+        }
+        var strength;
+        if (this.ClientSideStrongPassword(value)) {
+            strength = 3;
+        } else if (this.ClientSideMediumPassword(value)) {
+            strength = 2;
+        } else if (this.ClientSideWeakPassword(value)) {
+            strength = 1;
+        } else {
+            strength = 0;
+        }
+
+        
+        if (strength < 2) {
+            //this.markInvalid(this.errors.TooWeak);
+            this.errorMsg = this.errors.TooWeak;
+            //return false;
+        }
+        
+        
+        console.log('strength2: ' + strength);
+        
+        //var pm = this.trigger.child('div/div/div').dom;
+        
+        var pm = this.trigger.child('div/div');
+        pm.removeClass(this.meterClass);
+        pm.addClass(this.meterClass[strength]);
+                
+        var pt = this.trigger.child('/div').child('>*[class=roo-password-meter-text]').dom;        
+                
+        pt.innerHTML = this.meterLabel + '&nbsp;' + this.pwdStrengths[strength];
+        
+        this.errorMsg = ''; 
+        return true;
+    },
+    // private
+    CharacterSetChecks: function (type)
+    {
+        this.type = type;
+        this.fResult = false;
+    },
+    // private
+    isctype: function (character, type)
+    {
+        switch (type) {  
+            case this.kCapitalLetter:
+                if (character >= 'A' && character <= 'Z') {
+                    return true;
+                }
+                break;
+            
+            case this.kSmallLetter:
+                if (character >= 'a' && character <= 'z') {
+                    return true;
+                }
+                break;
+            
+            case this.kDigit:
+                if (character >= '0' && character <= '9') {
+                    return true;
+                }
+                break;
+            
+            case this.kPunctuation:
+                if ('!@#$%^&*()_+-=\'";:[{]}|.>,</?`~'.indexOf(character) >= 0) {
+                    return true;
+                }
+                break;
+            
+            default:
+                return false;
+        }
+
+    },
+    // private
+    IsLongEnough: function (pwd, size)
+    {
+        return !(pwd == null || isNaN(size) || pwd.length < size);
+    },
+    // private
+    SpansEnoughCharacterSets: function (word, nb)
+    {
+        if (!this.IsLongEnough(word, nb))
+        {
+            return false;
+        }
+
+        var characterSetChecks = new Array(
+            new this.CharacterSetChecks(this.kCapitalLetter), new this.CharacterSetChecks(this.kSmallLetter),
+            new this.CharacterSetChecks(this.kDigit), new this.CharacterSetChecks(this.kPunctuation)
+        );
+        
+        for (var index = 0; index < word.length; ++index) {
+            for (var nCharSet = 0; nCharSet < characterSetChecks.length; ++nCharSet) {
+                if (!characterSetChecks[nCharSet].fResult && this.isctype(word.charAt(index), characterSetChecks[nCharSet].type)) {
+                    characterSetChecks[nCharSet].fResult = true;
+                    break;
+                }
+            }
+        }
+
+        var nCharSets = 0;
+        for (var nCharSet = 0; nCharSet < characterSetChecks.length; ++nCharSet) {
+            if (characterSetChecks[nCharSet].fResult) {
+                ++nCharSets;
+            }
+        }
+
+        if (nCharSets < nb) {
+            return false;
+        }
+        return true;
+    },
+    // private
+    ClientSideStrongPassword: function (pwd)
+    {
+        return this.IsLongEnough(pwd, 8) && this.SpansEnoughCharacterSets(pwd, 3);
+    },
+    // private
+    ClientSideMediumPassword: function (pwd)
+    {
+        return this.IsLongEnough(pwd, 7) && this.SpansEnoughCharacterSets(pwd, 2);
+    },
+    // private
+    ClientSideWeakPassword: function (pwd)
+    {
+        return this.IsLongEnough(pwd, 6) || !this.IsLongEnough(pwd, 0);
+    }
+          
+})
\ No newline at end of file
diff --git a/Roo/bootstrap/form/TextArea.js b/Roo/bootstrap/form/TextArea.js
new file mode 100644 (file)
index 0000000..3eb51d9
--- /dev/null
@@ -0,0 +1,369 @@
+/*
+ * - LGPL
+ *
+ * Input
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.TextArea
+ * @extends Roo.bootstrap.Input
+ * Bootstrap TextArea class
+ * @cfg {Number} cols Specifies the visible width of a text area
+ * @cfg {Number} rows Specifies the visible number of lines in a text area
+ * @cfg {string} wrap (soft|hard)Specifies how the text in a text area is to be wrapped when submitted in a form
+ * @cfg {string} resize (none|both|horizontal|vertical|inherit|initial)
+ * @cfg {string} html text
+ * 
+ * @constructor
+ * Create a new TextArea
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.TextArea = function(config){
+    Roo.bootstrap.TextArea.superclass.constructor.call(this, config);
+   
+};
+
+Roo.extend(Roo.bootstrap.TextArea, Roo.bootstrap.Input,  {
+     
+    cols : false,
+    rows : 5,
+    readOnly : false,
+    warp : 'soft',
+    resize : false,
+    value: false,
+    html: false,
+    
+    getAutoCreate : function(){
+        
+        var align = (!this.labelAlign) ? this.parentLabelAlign() : this.labelAlign;
+        
+        var id = Roo.id();
+        
+        var cfg = {};
+        
+        if(this.inputType != 'hidden'){
+            cfg.cls = 'form-group' //input-group
+        }
+        
+        var input =  {
+            tag: 'textarea',
+            id : id,
+            warp : this.warp,
+            rows : this.rows,
+            value : this.value || '',
+            html: this.html || '',
+            cls : 'form-control',
+            placeholder : this.placeholder || '' 
+            
+        };
+        
+        if(this.maxLength && this.maxLength != Number.MAX_VALUE){
+            input.maxLength = this.maxLength;
+        }
+        
+        if(this.resize){
+            input.style = (typeof(input.style) == 'undefined') ? 'resize:' + this.resize : input.style + 'resize:' + this.resize;
+        }
+        
+        if(this.cols){
+            input.cols = this.cols;
+        }
+        
+        if (this.readOnly) {
+            input.readonly = true;
+        }
+        
+        if (this.name) {
+            input.name = this.name;
+        }
+        
+        if (this.size) {
+            input.cls = (typeof(input.cls) == 'undefined') ? 'input-' + this.size : input.cls + ' input-' + this.size;
+        }
+        
+        var settings=this;
+        ['xs','sm','md','lg'].map(function(size){
+            if (settings[size]) {
+                cfg.cls += ' col-' + size + '-' + settings[size];
+            }
+        });
+        
+        var inputblock = input;
+        
+        if(this.hasFeedback && !this.allowBlank){
+            
+            var feedback = {
+                tag: 'span',
+                cls: 'glyphicon form-control-feedback'
+            };
+
+            inputblock = {
+                cls : 'has-feedback',
+                cn :  [
+                    input,
+                    feedback
+                ] 
+            };  
+        }
+        
+        
+        if (this.before || this.after) {
+            
+            inputblock = {
+                cls : 'input-group',
+                cn :  [] 
+            };
+            if (this.before) {
+                inputblock.cn.push({
+                    tag :'span',
+                    cls : 'input-group-addon',
+                    html : this.before
+                });
+            }
+            
+            inputblock.cn.push(input);
+            
+            if(this.hasFeedback && !this.allowBlank){
+                inputblock.cls += ' has-feedback';
+                inputblock.cn.push(feedback);
+            }
+            
+            if (this.after) {
+                inputblock.cn.push({
+                    tag :'span',
+                    cls : 'input-group-addon',
+                    html : this.after
+                });
+            }
+            
+        }
+        
+        if (align ==='left' && this.fieldLabel.length) {
+            cfg.cn = [
+                {
+                    tag: 'label',
+                    'for' :  id,
+                    cls : 'control-label',
+                    html : this.fieldLabel
+                },
+                {
+                    cls : "",
+                    cn: [
+                        inputblock
+                    ]
+                }
+
+            ];
+            
+            if(this.labelWidth > 12){
+                cfg.cn[0].style = "width: " + this.labelWidth + 'px';
+            }
+
+            if(this.labelWidth < 13 && this.labelmd == 0){
+                this.labelmd = this.labelWidth;
+            }
+
+            if(this.labellg > 0){
+                cfg.cn[0].cls += ' col-lg-' + this.labellg;
+                cfg.cn[1].cls += ' col-lg-' + (12 - this.labellg);
+            }
+
+            if(this.labelmd > 0){
+                cfg.cn[0].cls += ' col-md-' + this.labelmd;
+                cfg.cn[1].cls += ' col-md-' + (12 - this.labelmd);
+            }
+
+            if(this.labelsm > 0){
+                cfg.cn[0].cls += ' col-sm-' + this.labelsm;
+                cfg.cn[1].cls += ' col-sm-' + (12 - this.labelsm);
+            }
+
+            if(this.labelxs > 0){
+                cfg.cn[0].cls += ' col-xs-' + this.labelxs;
+                cfg.cn[1].cls += ' col-xs-' + (12 - this.labelxs);
+            }
+            
+        } else if ( this.fieldLabel.length) {
+            cfg.cn = [
+
+               {
+                   tag: 'label',
+                   //cls : 'input-group-addon',
+                   html : this.fieldLabel
+
+               },
+
+               inputblock
+
+           ];
+
+        } else {
+
+            cfg.cn = [
+
+                inputblock
+
+            ];
+                
+        }
+        
+        if (this.disabled) {
+            input.disabled=true;
+        }
+        
+        return cfg;
+        
+    },
+    /**
+     * return the real textarea element.
+     */
+    inputEl: function ()
+    {
+        return this.el.select('textarea.form-control',true).first();
+    },
+    
+    /**
+     * Clear any invalid styles/messages for this field
+     */
+    clearInvalid : function()
+    {
+        
+        if(!this.el || this.preventMark){ // not rendered
+            return;
+        }
+        
+        var label = this.el.select('label', true).first();
+        var icon = this.el.select('i.fa-star', true).first();
+        
+        if(label && icon){
+            icon.remove();
+        }
+        this.el.removeClass( this.validClass);
+        this.inputEl().removeClass('is-invalid');
+         
+        if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank){
+            
+            var feedback = this.el.select('.form-control-feedback', true).first();
+            
+            if(feedback){
+                this.el.select('.form-control-feedback', true).first().removeClass(this.invalidFeedbackClass);
+            }
+            
+        }
+        
+        this.fireEvent('valid', this);
+    },
+    
+     /**
+     * Mark this field as valid
+     */
+    markValid : function()
+    {
+        if(!this.el  || this.preventMark){ // not rendered
+            return;
+        }
+        
+        this.el.removeClass([this.invalidClass, this.validClass]);
+        this.inputEl().removeClass(['is-valid', 'is-invalid']);
+        
+        var feedback = this.el.select('.form-control-feedback', true).first();
+            
+        if(feedback){
+            this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
+        }
+
+        if(this.disabled || this.allowBlank){
+            return;
+        }
+        
+        var label = this.el.select('label', true).first();
+        var icon = this.el.select('i.fa-star', true).first();
+        
+        if(label && icon){
+            icon.remove();
+        }
+        if (Roo.bootstrap.version == 3) {
+            this.el.addClass(this.validClass);
+        } else {
+            this.inputEl().addClass('is-valid');
+        }
+        
+        
+        if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank && (this.getValue().length || this.forceFeedback)){
+            
+            var feedback = this.el.select('.form-control-feedback', true).first();
+            
+            if(feedback){
+                this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
+                this.el.select('.form-control-feedback', true).first().addClass([this.validFeedbackClass]);
+            }
+            
+        }
+        
+        this.fireEvent('valid', this);
+    },
+    
+     /**
+     * Mark this field as invalid
+     * @param {String} msg The validation message
+     */
+    markInvalid : function(msg)
+    {
+        if(!this.el  || this.preventMark){ // not rendered
+            return;
+        }
+        
+        this.el.removeClass([this.invalidClass, this.validClass]);
+        this.inputEl().removeClass(['is-valid', 'is-invalid']);
+        
+        var feedback = this.el.select('.form-control-feedback', true).first();
+            
+        if(feedback){
+            this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
+        }
+
+        if(this.disabled || this.allowBlank){
+            return;
+        }
+        
+        var label = this.el.select('label', true).first();
+        var icon = this.el.select('i.fa-star', true).first();
+        
+        if(!this.getValue().length && label && !icon){
+            this.el.createChild({
+                tag : 'i',
+                cls : 'text-danger fa fa-lg fa-star',
+                tooltip : 'This field is required',
+                style : 'margin-right:5px;'
+            }, label, true);
+        }
+        
+        if (Roo.bootstrap.version == 3) {
+            this.el.addClass(this.invalidClass);
+        } else {
+            this.inputEl().addClass('is-invalid');
+        }
+        
+        // fixme ... this may be depricated need to test..
+        if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank){
+            
+            var feedback = this.el.select('.form-control-feedback', true).first();
+            
+            if(feedback){
+                this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
+                
+                if(this.getValue().length || this.forceFeedback){
+                    this.el.select('.form-control-feedback', true).first().addClass([this.invalidFeedbackClass]);
+                }
+                
+            }
+            
+        }
+        
+        this.fireEvent('invalid', this, msg);
+    }
+});
+
diff --git a/Roo/bootstrap/form/TimeField.js b/Roo/bootstrap/form/TimeField.js
new file mode 100644 (file)
index 0000000..b258728
--- /dev/null
@@ -0,0 +1,517 @@
+/*
+ * - LGPL
+ *
+ * TimeField
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.TimeField
+ * @extends Roo.bootstrap.Input
+ * Bootstrap DateField class
+ * 
+ * 
+ * @constructor
+ * Create a new TimeField
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.TimeField = function(config){
+    Roo.bootstrap.TimeField.superclass.constructor.call(this, config);
+    this.addEvents({
+            /**
+             * @event show
+             * Fires when this field show.
+             * @param {Roo.bootstrap.DateField} thisthis
+             * @param {Mixed} date The date value
+             */
+            show : true,
+            /**
+             * @event show
+             * Fires when this field hide.
+             * @param {Roo.bootstrap.DateField} this
+             * @param {Mixed} date The date value
+             */
+            hide : true,
+            /**
+             * @event select
+             * Fires when select a date.
+             * @param {Roo.bootstrap.DateField} this
+             * @param {Mixed} date The date value
+             */
+            select : true
+        });
+};
+
+Roo.extend(Roo.bootstrap.TimeField, Roo.bootstrap.Input,  {
+    
+    /**
+     * @cfg {String} format
+     * The default time format string which can be overriden for localization support.  The format must be
+     * valid according to {@link Date#parseDate} (defaults to 'H:i').
+     */
+    format : "H:i",
+
+    getAutoCreate : function()
+    {
+        this.after = '<i class="fa far fa-clock"></i>';
+        return Roo.bootstrap.TimeField.superclass.getAutoCreate.call(this);
+        
+         
+    },
+    onRender: function(ct, position)
+    {
+        
+        Roo.bootstrap.TimeField.superclass.onRender.call(this, ct, position);
+                
+        this.pickerEl = Roo.get(document.body).createChild(Roo.bootstrap.TimeField.template);
+        
+        this.picker().setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        
+        this.pop = this.picker().select('>.datepicker-time',true).first();
+        this.pop.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+        
+        this.picker().on('mousedown', this.onMousedown, this);
+        this.picker().on('click', this.onClick, this);
+        
+        this.picker().addClass('datepicker-dropdown');
+    
+        this.fillTime();
+        this.update();
+            
+        this.pop.select('.hours-up', true).first().on('click', this.onIncrementHours, this);
+        this.pop.select('.hours-down', true).first().on('click', this.onDecrementHours, this);
+        this.pop.select('.minutes-up', true).first().on('click', this.onIncrementMinutes, this);
+        this.pop.select('.minutes-down', true).first().on('click', this.onDecrementMinutes, this);
+        this.pop.select('button.period', true).first().on('click', this.onTogglePeriod, this);
+        this.pop.select('button.ok', true).first().on('click', this.setTime, this);
+
+    },
+    
+    fireKey: function(e){
+        if (!this.picker().isVisible()){
+            if (e.keyCode == 27) { // allow escape to hide and re-show picker
+                this.show();
+            }
+            return;
+        }
+
+        e.preventDefault();
+        
+        switch(e.keyCode){
+            case 27: // escape
+                this.hide();
+                break;
+            case 37: // left
+            case 39: // right
+                this.onTogglePeriod();
+                break;
+            case 38: // up
+                this.onIncrementMinutes();
+                break;
+            case 40: // down
+                this.onDecrementMinutes();
+                break;
+            case 13: // enter
+            case 9: // tab
+                this.setTime();
+                break;
+        }
+    },
+    
+    onClick: function(e) {
+        e.stopPropagation();
+        e.preventDefault();
+    },
+    
+    picker : function()
+    {
+        return this.pickerEl;
+    },
+    
+    fillTime: function()
+    {    
+        var time = this.pop.select('tbody', true).first();
+        
+        time.dom.innerHTML = '';
+        
+        time.createChild({
+            tag: 'tr',
+            cn: [
+                {
+                    tag: 'td',
+                    cn: [
+                        {
+                            tag: 'a',
+                            href: '#',
+                            cls: 'btn',
+                            cn: [
+                                {
+                                    tag: 'i',
+                                    cls: 'hours-up fa fas fa-chevron-up'
+                                }
+                            ]
+                        } 
+                    ]
+                },
+                {
+                    tag: 'td',
+                    cls: 'separator'
+                },
+                {
+                    tag: 'td',
+                    cn: [
+                        {
+                            tag: 'a',
+                            href: '#',
+                            cls: 'btn',
+                            cn: [
+                                {
+                                    tag: 'i',
+                                    cls: 'minutes-up fa fas fa-chevron-up'
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    tag: 'td',
+                    cls: 'separator'
+                }
+            ]
+        });
+        
+        time.createChild({
+            tag: 'tr',
+            cn: [
+                {
+                    tag: 'td',
+                    cn: [
+                        {
+                            tag: 'span',
+                            cls: 'timepicker-hour',
+                            html: '00'
+                        }  
+                    ]
+                },
+                {
+                    tag: 'td',
+                    cls: 'separator',
+                    html: ':'
+                },
+                {
+                    tag: 'td',
+                    cn: [
+                        {
+                            tag: 'span',
+                            cls: 'timepicker-minute',
+                            html: '00'
+                        }  
+                    ]
+                },
+                {
+                    tag: 'td',
+                    cls: 'separator'
+                },
+                {
+                    tag: 'td',
+                    cn: [
+                        {
+                            tag: 'button',
+                            type: 'button',
+                            cls: 'btn btn-primary period',
+                            html: 'AM'
+                            
+                        }
+                    ]
+                }
+            ]
+        });
+        
+        time.createChild({
+            tag: 'tr',
+            cn: [
+                {
+                    tag: 'td',
+                    cn: [
+                        {
+                            tag: 'a',
+                            href: '#',
+                            cls: 'btn',
+                            cn: [
+                                {
+                                    tag: 'span',
+                                    cls: 'hours-down fa fas fa-chevron-down'
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    tag: 'td',
+                    cls: 'separator'
+                },
+                {
+                    tag: 'td',
+                    cn: [
+                        {
+                            tag: 'a',
+                            href: '#',
+                            cls: 'btn',
+                            cn: [
+                                {
+                                    tag: 'span',
+                                    cls: 'minutes-down fa fas fa-chevron-down'
+                                }
+                            ]
+                        }
+                    ]
+                },
+                {
+                    tag: 'td',
+                    cls: 'separator'
+                }
+            ]
+        });
+        
+    },
+    
+    update: function()
+    {
+        
+        this.time = (typeof(this.time) === 'undefined') ? new Date() : this.time;
+        
+        this.fill();
+    },
+    
+    fill: function() 
+    {
+        var hours = this.time.getHours();
+        var minutes = this.time.getMinutes();
+        var period = 'AM';
+        
+        if(hours > 11){
+            period = 'PM';
+        }
+        
+        if(hours == 0){
+            hours = 12;
+        }
+        
+        
+        if(hours > 12){
+            hours = hours - 12;
+        }
+        
+        if(hours < 10){
+            hours = '0' + hours;
+        }
+        
+        if(minutes < 10){
+            minutes = '0' + minutes;
+        }
+        
+        this.pop.select('.timepicker-hour', true).first().dom.innerHTML = hours;
+        this.pop.select('.timepicker-minute', true).first().dom.innerHTML = minutes;
+        this.pop.select('button', true).first().dom.innerHTML = period;
+        
+    },
+    
+    place: function()
+    {   
+        this.picker().removeClass(['bottom-left', 'bottom-right', 'top-left', 'top-right']);
+        
+        var cls = ['bottom'];
+        
+        if((Roo.lib.Dom.getViewHeight() + Roo.get(document.body).getScroll().top) - (this.inputEl().getBottom() + this.picker().getHeight()) < 0){ // top
+            cls.pop();
+            cls.push('top');
+        }
+        
+        cls.push('right');
+        
+        if((Roo.lib.Dom.getViewWidth() + Roo.get(document.body).getScroll().left) - (this.inputEl().getLeft() + this.picker().getWidth()) < 0){ // left
+            cls.pop();
+            cls.push('left');
+        }
+        //this.picker().setXY(20000,20000);
+        this.picker().addClass(cls.join('-'));
+        
+        var _this = this;
+        
+        Roo.each(cls, function(c){
+            if(c == 'bottom'){
+                (function() {
+                 //  
+                }).defer(200);
+                 _this.picker().alignTo(_this.inputEl(),   "tr-br", [0, 10], false);
+                //_this.picker().setTop(_this.inputEl().getHeight());
+                return;
+            }
+            if(c == 'top'){
+                 _this.picker().alignTo(_this.inputEl(),   "br-tr", [0, 10], false);
+                
+                //_this.picker().setTop(0 - _this.picker().getHeight());
+                return;
+            }
+            /*
+            if(c == 'left'){
+                _this.picker().setLeft(_this.inputEl().getLeft() + _this.inputEl().getWidth() - _this.el.getLeft() - _this.picker().getWidth());
+                return;
+            }
+            if(c == 'right'){
+                _this.picker().setLeft(_this.inputEl().getLeft() - _this.el.getLeft());
+                return;
+            }
+            */
+        });
+        
+    },
+  
+    onFocus : function()
+    {
+        Roo.bootstrap.TimeField.superclass.onFocus.call(this);
+        this.show();
+    },
+    
+    onBlur : function()
+    {
+        Roo.bootstrap.TimeField.superclass.onBlur.call(this);
+        this.hide();
+    },
+    
+    show : function()
+    {
+        this.picker().show();
+        this.pop.show();
+        this.update();
+        this.place();
+        
+        this.fireEvent('show', this, this.date);
+    },
+    
+    hide : function()
+    {
+        this.picker().hide();
+        this.pop.hide();
+        
+        this.fireEvent('hide', this, this.date);
+    },
+    
+    setTime : function()
+    {
+        this.hide();
+        this.setValue(this.time.format(this.format));
+        
+        this.fireEvent('select', this, this.date);
+        
+        
+    },
+    
+    onMousedown: function(e){
+        e.stopPropagation();
+        e.preventDefault();
+    },
+    
+    onIncrementHours: function()
+    {
+        Roo.log('onIncrementHours');
+        this.time = this.time.add(Date.HOUR, 1);
+        this.update();
+        
+    },
+    
+    onDecrementHours: function()
+    {
+        Roo.log('onDecrementHours');
+        this.time = this.time.add(Date.HOUR, -1);
+        this.update();
+    },
+    
+    onIncrementMinutes: function()
+    {
+        Roo.log('onIncrementMinutes');
+        this.time = this.time.add(Date.MINUTE, 1);
+        this.update();
+    },
+    
+    onDecrementMinutes: function()
+    {
+        Roo.log('onDecrementMinutes');
+        this.time = this.time.add(Date.MINUTE, -1);
+        this.update();
+    },
+    
+    onTogglePeriod: function()
+    {
+        Roo.log('onTogglePeriod');
+        this.time = this.time.add(Date.HOUR, 12);
+        this.update();
+    }
+    
+   
+});
+
+Roo.apply(Roo.bootstrap.TimeField,  {
+  
+    template : {
+        tag: 'div',
+        cls: 'datepicker dropdown-menu',
+        cn: [
+            {
+                tag: 'div',
+                cls: 'datepicker-time',
+                cn: [
+                {
+                    tag: 'table',
+                    cls: 'table-condensed',
+                    cn:[
+                        {
+                            tag: 'tbody',
+                            cn: [
+                                {
+                                    tag: 'tr',
+                                    cn: [
+                                    {
+                                        tag: 'td',
+                                        colspan: '7'
+                                    }
+                                    ]
+                                }
+                            ]
+                        },
+                        {
+                            tag: 'tfoot',
+                            cn: [
+                                {
+                                    tag: 'tr',
+                                    cn: [
+                                    {
+                                        tag: 'th',
+                                        colspan: '7',
+                                        cls: '',
+                                        cn: [
+                                            {
+                                                tag: 'button',
+                                                cls: 'btn btn-info ok',
+                                                html: 'OK'
+                                            }
+                                        ]
+                                    }
+                    
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                }
+                ]
+            }
+        ]
+    }
+});
+
+
\ No newline at end of file
diff --git a/Roo/bootstrap/form/TriggerField.js b/Roo/bootstrap/form/TriggerField.js
new file mode 100644 (file)
index 0000000..73731e4
--- /dev/null
@@ -0,0 +1,606 @@
+/*
+ * - LGPL
+ *
+ * trigger field - base class for combo..
+ * 
+ */
+/**
+ * @class Roo.bootstrap.TriggerField
+ * @extends Roo.bootstrap.Input
+ * Provides a convenient wrapper for TextFields that adds a clickable trigger button (looks like a combobox by default).
+ * The trigger has no default action, so you must assign a function to implement the trigger click handler by
+ * overriding {@link #onTriggerClick}. You can create a TriggerField directly, as it renders exactly like a combobox
+ * for which you can provide a custom implementation.  For example:
+ * <pre><code>
+var trigger = new Roo.bootstrap.TriggerField();
+trigger.onTriggerClick = myTriggerFn;
+trigger.applyTo('my-field');
+</code></pre>
+ *
+ * However, in general you will most likely want to use TriggerField as the base class for a reusable component.
+ * {@link Roo.bootstrap.DateField} and {@link Roo.bootstrap.ComboBox} are perfect examples of this.
+ * @cfg {String} triggerClass An additional CSS class used to style the trigger button.  The trigger will always get the
+ * class 'x-form-trigger' by default and triggerClass will be <b>appended</b> if specified.
+ * @cfg {String} caret (search|calendar) BS3 only - carat fa name
+
+ * @constructor
+ * Create a new TriggerField.
+ * @param {Object} config Configuration options (valid {@Roo.bootstrap.Input} config options will also be applied
+ * to the base TextField)
+ */
+Roo.bootstrap.TriggerField = function(config){
+    this.mimicing = false;
+    Roo.bootstrap.TriggerField.superclass.constructor.call(this, config);
+};
+
+Roo.extend(Roo.bootstrap.TriggerField, Roo.bootstrap.Input,  {
+    /**
+     * @cfg {String} triggerClass A CSS class to apply to the trigger
+     */
+     /**
+     * @cfg {Boolean} hideTrigger True to hide the trigger element and display only the base text field (defaults to false)
+     */
+    hideTrigger:false,
+
+    /**
+     * @cfg {Boolean} removable (true|false) special filter default false
+     */
+    removable : false,
+    
+    /** @cfg {Boolean} grow @hide */
+    /** @cfg {Number} growMin @hide */
+    /** @cfg {Number} growMax @hide */
+
+    /**
+     * @hide 
+     * @method
+     */
+    autoSize: Roo.emptyFn,
+    // private
+    monitorTab : true,
+    // private
+    deferHeight : true,
+
+    
+    actionMode : 'wrap',
+    
+    caret : false,
+    
+    
+    getAutoCreate : function(){
+       
+        var align = this.labelAlign || this.parentLabelAlign();
+        
+        var id = Roo.id();
+        
+        var cfg = {
+            cls: 'form-group' //input-group
+        };
+        
+        
+        var input =  {
+            tag: 'input',
+            id : id,
+            type : this.inputType,
+            cls : 'form-control',
+            autocomplete: 'new-password',
+            placeholder : this.placeholder || '' 
+            
+        };
+        if (this.name) {
+            input.name = this.name;
+        }
+        if (this.size) {
+            input.cls += ' input-' + this.size;
+        }
+        
+        if (this.disabled) {
+            input.disabled=true;
+        }
+        
+        var inputblock = input;
+        
+        if(this.hasFeedback && !this.allowBlank){
+            
+            var feedback = {
+                tag: 'span',
+                cls: 'glyphicon form-control-feedback'
+            };
+            
+            if(this.removable && !this.editable  ){
+                inputblock = {
+                    cls : 'has-feedback',
+                    cn :  [
+                        inputblock,
+                        {
+                            tag: 'button',
+                            html : 'x',
+                            cls : 'roo-combo-removable-btn close'
+                        },
+                        feedback
+                    ] 
+                };
+            } else {
+                inputblock = {
+                    cls : 'has-feedback',
+                    cn :  [
+                        inputblock,
+                        feedback
+                    ] 
+                };
+            }
+
+        } else {
+            if(this.removable && !this.editable ){
+                inputblock = {
+                    cls : 'roo-removable',
+                    cn :  [
+                        inputblock,
+                        {
+                            tag: 'button',
+                            html : 'x',
+                            cls : 'roo-combo-removable-btn close'
+                        }
+                    ] 
+                };
+            }
+        }
+        
+        if (this.before || this.after) {
+            
+            inputblock = {
+                cls : 'input-group',
+                cn :  [] 
+            };
+            if (this.before) {
+                inputblock.cn.push({
+                    tag :'span',
+                    cls : 'input-group-addon input-group-prepend input-group-text',
+                    html : this.before
+                });
+            }
+            
+            inputblock.cn.push(input);
+            
+            if(this.hasFeedback && !this.allowBlank){
+                inputblock.cls += ' has-feedback';
+                inputblock.cn.push(feedback);
+            }
+            
+            if (this.after) {
+                inputblock.cn.push({
+                    tag :'span',
+                    cls : 'input-group-addon input-group-append input-group-text',
+                    html : this.after
+                });
+            }
+            
+        };
+        
+      
+        
+        var ibwrap = inputblock;
+        
+        if(this.multiple){
+            ibwrap = {
+                tag: 'ul',
+                cls: 'roo-select2-choices',
+                cn:[
+                    {
+                        tag: 'li',
+                        cls: 'roo-select2-search-field',
+                        cn: [
+
+                            inputblock
+                        ]
+                    }
+                ]
+            };
+                
+        }
+        
+        var combobox = {
+            cls: 'roo-select2-container input-group',
+            cn: [
+                 {
+                    tag: 'input',
+                    type : 'hidden',
+                    cls: 'form-hidden-field'
+                },
+                ibwrap
+            ]
+        };
+        
+        if(!this.multiple && this.showToggleBtn){
+            
+            var caret = {
+                        tag: 'span',
+                        cls: 'caret'
+             };
+            if (this.caret != false) {
+                caret = {
+                     tag: 'i',
+                     cls: 'fa fa-' + this.caret
+                };
+                
+            }
+            
+            combobox.cn.push({
+                tag :'span',
+                cls : 'input-group-addon input-group-append input-group-text btn dropdown-toggle',
+                cn : [
+                    Roo.bootstrap.version == 3 ? caret : '',
+                    {
+                        tag: 'span',
+                        cls: 'combobox-clear',
+                        cn  : [
+                            {
+                                tag : 'i',
+                                cls: 'icon-remove'
+                            }
+                        ]
+                    }
+                ]
+
+            })
+        }
+        
+        if(this.multiple){
+            combobox.cls += ' roo-select2-container-multi';
+        }
+         var indicator = {
+            tag : 'i',
+            cls : 'roo-required-indicator ' + (this.indicatorpos == 'right'  ? 'right' : 'left') +'-indicator text-danger fa fa-lg fa-star',
+            tooltip : 'This field is required'
+        };
+        if (Roo.bootstrap.version == 4) {
+            indicator = {
+                tag : 'i',
+                style : 'display:none'
+            };
+        }
+        
+        
+        if (align ==='left' && this.fieldLabel.length) {
+            
+            cfg.cls += ' roo-form-group-label-left'  + (Roo.bootstrap.version == 4 ? ' row' : '');
+
+            cfg.cn = [
+                indicator,
+                {
+                    tag: 'label',
+                    'for' :  id,
+                    cls : 'control-label',
+                    html : this.fieldLabel
+
+                },
+                {
+                    cls : "", 
+                    cn: [
+                        combobox
+                    ]
+                }
+
+            ];
+            
+            var labelCfg = cfg.cn[1];
+            var contentCfg = cfg.cn[2];
+            
+            if(this.indicatorpos == 'right'){
+                cfg.cn = [
+                    {
+                        tag: 'label',
+                        'for' :  id,
+                        cls : 'control-label',
+                        cn : [
+                            {
+                                tag : 'span',
+                                html : this.fieldLabel
+                            },
+                            indicator
+                        ]
+                    },
+                    {
+                        cls : "", 
+                        cn: [
+                            combobox
+                        ]
+                    }
+
+                ];
+                
+                labelCfg = cfg.cn[0];
+                contentCfg = cfg.cn[1];
+            }
+            
+            if(this.labelWidth > 12){
+                labelCfg.style = "width: " + this.labelWidth + 'px';
+            }
+            
+            if(this.labelWidth < 13 && this.labelmd == 0){
+                this.labelmd = this.labelWidth;
+            }
+            
+            if(this.labellg > 0){
+                labelCfg.cls += ' col-lg-' + this.labellg;
+                contentCfg.cls += ' col-lg-' + (12 - this.labellg);
+            }
+            
+            if(this.labelmd > 0){
+                labelCfg.cls += ' col-md-' + this.labelmd;
+                contentCfg.cls += ' col-md-' + (12 - this.labelmd);
+            }
+            
+            if(this.labelsm > 0){
+                labelCfg.cls += ' col-sm-' + this.labelsm;
+                contentCfg.cls += ' col-sm-' + (12 - this.labelsm);
+            }
+            
+            if(this.labelxs > 0){
+                labelCfg.cls += ' col-xs-' + this.labelxs;
+                contentCfg.cls += ' col-xs-' + (12 - this.labelxs);
+            }
+            
+        } else if ( this.fieldLabel.length) {
+//                Roo.log(" label");
+            cfg.cn = [
+                indicator,
+               {
+                   tag: 'label',
+                   //cls : 'input-group-addon',
+                   html : this.fieldLabel
+
+               },
+
+               combobox
+
+            ];
+            
+            if(this.indicatorpos == 'right'){
+                
+                cfg.cn = [
+                    {
+                       tag: 'label',
+                       cn : [
+                           {
+                               tag : 'span',
+                               html : this.fieldLabel
+                           },
+                           indicator
+                       ]
+
+                    },
+                    combobox
+
+                ];
+
+            }
+
+        } else {
+            
+//                Roo.log(" no label && no align");
+                cfg = combobox
+                     
+                
+        }
+        
+        var settings=this;
+        ['xs','sm','md','lg'].map(function(size){
+            if (settings[size]) {
+                cfg.cls += ' col-' + size + '-' + settings[size];
+            }
+        });
+        
+        return cfg;
+        
+    },
+    
+    
+    
+    // private
+    onResize : function(w, h){
+//        Roo.bootstrap.TriggerField.superclass.onResize.apply(this, arguments);
+//        if(typeof w == 'number'){
+//            var x = w - this.trigger.getWidth();
+//            this.inputEl().setWidth(this.adjustWidth('input', x));
+//            this.trigger.setStyle('left', x+'px');
+//        }
+    },
+
+    // private
+    adjustSize : Roo.BoxComponent.prototype.adjustSize,
+
+    // private
+    getResizeEl : function(){
+        return this.inputEl();
+    },
+
+    // private
+    getPositionEl : function(){
+        return this.inputEl();
+    },
+
+    // private
+    alignErrorIcon : function(){
+        this.errorIcon.alignTo(this.inputEl(), 'tl-tr', [2, 0]);
+    },
+
+    // private
+    initEvents : function(){
+        
+        this.createList();
+        
+        Roo.bootstrap.TriggerField.superclass.initEvents.call(this);
+        //this.wrap = this.el.wrap({cls: "x-form-field-wrap"});
+        if(!this.multiple && this.showToggleBtn){
+            this.trigger = this.el.select('span.dropdown-toggle',true).first();
+            if(this.hideTrigger){
+                this.trigger.setDisplayed(false);
+            }
+            this.trigger.on("click", this.onTriggerClick, this, {preventDefault:true});
+        }
+        
+        if(this.multiple){
+            this.inputEl().on("click", this.onTriggerClick, this, {preventDefault:true});
+        }
+        
+        if(this.removable && !this.editable && !this.tickable){
+            var close = this.closeTriggerEl();
+            
+            if(close){
+                close.setVisibilityMode(Roo.Element.DISPLAY).hide();
+                close.on('click', this.removeBtnClick, this, close);
+            }
+        }
+        
+        //this.trigger.addClassOnOver('x-form-trigger-over');
+        //this.trigger.addClassOnClick('x-form-trigger-click');
+        
+        //if(!this.width){
+        //    this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
+        //}
+    },
+    
+    closeTriggerEl : function()
+    {
+        var close = this.el.select('.roo-combo-removable-btn', true).first();
+        return close ? close : false;
+    },
+    
+    removeBtnClick : function(e, h, el)
+    {
+        e.preventDefault();
+        
+        if(this.fireEvent("remove", this) !== false){
+            this.reset();
+            this.fireEvent("afterremove", this)
+        }
+    },
+    
+    createList : function()
+    {
+        this.list = Roo.get(document.body).createChild({
+            tag: Roo.bootstrap.version == 4 ? 'div' : 'ul',
+            cls: 'typeahead typeahead-long dropdown-menu shadow',
+            style: 'display:none'
+        });
+        
+        this.list.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';;
+        
+    },
+
+    // private
+    initTrigger : function(){
+       
+    },
+
+    // private
+    onDestroy : function(){
+        if(this.trigger){
+            this.trigger.removeAllListeners();
+          //  this.trigger.remove();
+        }
+        //if(this.wrap){
+        //    this.wrap.remove();
+        //}
+        Roo.bootstrap.TriggerField.superclass.onDestroy.call(this);
+    },
+
+    // private
+    onFocus : function(){
+        Roo.bootstrap.TriggerField.superclass.onFocus.call(this);
+        /*
+        if(!this.mimicing){
+            this.wrap.addClass('x-trigger-wrap-focus');
+            this.mimicing = true;
+            Roo.get(Roo.isIE ? document.body : document).on("mousedown", this.mimicBlur, this);
+            if(this.monitorTab){
+                this.el.on("keydown", this.checkTab, this);
+            }
+        }
+        */
+    },
+
+    // private
+    checkTab : function(e){
+        if(e.getKey() == e.TAB){
+            this.triggerBlur();
+        }
+    },
+
+    // private
+    onBlur : function(){
+        // do nothing
+    },
+
+    // private
+    mimicBlur : function(e, t){
+        /*
+        if(!this.wrap.contains(t) && this.validateBlur()){
+            this.triggerBlur();
+        }
+        */
+    },
+
+    // private
+    triggerBlur : function(){
+        this.mimicing = false;
+        Roo.get(Roo.isIE ? document.body : document).un("mousedown", this.mimicBlur);
+        if(this.monitorTab){
+            this.el.un("keydown", this.checkTab, this);
+        }
+        //this.wrap.removeClass('x-trigger-wrap-focus');
+        Roo.bootstrap.TriggerField.superclass.onBlur.call(this);
+    },
+
+    // private
+    // This should be overriden by any subclass that needs to check whether or not the field can be blurred.
+    validateBlur : function(e, t){
+        return true;
+    },
+
+    // private
+    onDisable : function(){
+        this.inputEl().dom.disabled = true;
+        //Roo.bootstrap.TriggerField.superclass.onDisable.call(this);
+        //if(this.wrap){
+        //    this.wrap.addClass('x-item-disabled');
+        //}
+    },
+
+    // private
+    onEnable : function(){
+        this.inputEl().dom.disabled = false;
+        //Roo.bootstrap.TriggerField.superclass.onEnable.call(this);
+        //if(this.wrap){
+        //    this.el.removeClass('x-item-disabled');
+        //}
+    },
+
+    // private
+    onShow : function(){
+        var ae = this.getActionEl();
+        
+        if(ae){
+            ae.dom.style.display = '';
+            ae.dom.style.visibility = 'visible';
+        }
+    },
+
+    // private
+    
+    onHide : function(){
+        var ae = this.getActionEl();
+        ae.dom.style.display = 'none';
+    },
+
+    /**
+     * The function that should handle the trigger's click event.  This method does nothing by default until overridden
+     * by an implementing function.
+     * @method
+     * @param {EventObject} e
+     */
+    onTriggerClick : Roo.emptyFn
+});
\ No newline at end of file