Roo/bootstrap/ComboBox.js
[roojs1] / roojs-bootstrap-debug.js
index e89614e..0be573d 100644 (file)
@@ -7911,6 +7911,10 @@ clientValidation  Boolean          Applies to submit only.  Pass true to call fo
                         sd[field.displayField] = typeof(values[field.name]) == 'undefined' ? '' : values[field.name];
                         field.setFromData(sd);
 
+                    } else if(field.setFromData && (field.store && !field.store.isLocal)) {
+                        
+                        field.setFromData(values);
+                        
                     } else {
                         field.setValue(values[id]);
                     }
@@ -7963,10 +7967,13 @@ clientValidation  Boolean          Applies to submit only.  Pass true to call fo
         var items = this.getItems();
         var ret = {};
         items.each(function(f){
+            
             if (!f.getName()) {
                 return;
             }
+            
             var v = f.getValue();
+            
             if (f.inputType =='radio') {
                 if (typeof(ret[f.getName()]) == 'undefined') {
                     ret[f.getName()] = ''; // empty..
@@ -7979,6 +7986,10 @@ clientValidation  Boolean          Applies to submit only.  Pass true to call fo
                 v = f.el.dom.value;
 
             }
+            
+            if(f.xtype == 'MoneyField'){
+                ret[f.currencyName] = f.getCurrency();
+            }
 
             // not sure if this supported any more..
             if ((typeof(v) == 'object') && f.getRawValue) {
@@ -14070,6 +14081,7 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
                     
                     this.onLoad();
                     
+                    Roo.log('onload???');
                     
                 }else{
                     
@@ -39782,6 +39794,48 @@ Roo.bootstrap.MoneyField = function(config) {
 
 Roo.extend(Roo.bootstrap.MoneyField, Roo.bootstrap.ComboBox, {
     
+    /**
+     * @cfg {Boolean} allowDecimals False to disallow decimal values (defaults to true)
+     */
+    allowDecimals : true,
+    /**
+     * @cfg {String} decimalSeparator Character(s) to allow as the decimal separator (defaults to '.')
+     */
+    decimalSeparator : ".",
+    /**
+     * @cfg {Number} decimalPrecision The maximum precision to display after the decimal separator (defaults to 2)
+     */
+    decimalPrecision : 2,
+    /**
+     * @cfg {Boolean} allowNegative False to prevent entering a negative sign (defaults to true)
+     */
+    allowNegative : true,
+    /**
+     * @cfg {Number} minValue The minimum allowed value (defaults to Number.NEGATIVE_INFINITY)
+     */
+    minValue : Number.NEGATIVE_INFINITY,
+    /**
+     * @cfg {Number} maxValue The maximum allowed value (defaults to Number.MAX_VALUE)
+     */
+    maxValue : Number.MAX_VALUE,
+    /**
+     * @cfg {String} minText Error text to display if the minimum value validation fails (defaults to "The minimum value for this field is {minValue}")
+     */
+    minText : "The minimum value for this field is {0}",
+    /**
+     * @cfg {String} maxText Error text to display if the maximum value validation fails (defaults to "The maximum value for this field is {maxValue}")
+     */
+    maxText : "The maximum value for this field is {0}",
+    /**
+     * @cfg {String} nanText Error text to display if the value is not a valid number.  For example, this can happen
+     * if a valid character like '.' or '-' is left in the field with no number (defaults to "{value} is not a valid number")
+     */
+    nanText : "{0} is not a valid number",
+    /**
+     * @cfg {Boolean} castInt (true|false) cast int if true (defalut true)
+     */
+    castInt : true,
+    
     inputlg : 9,
     inputmd : 9,
     inputsm : 9,
@@ -39947,9 +40001,20 @@ Roo.extend(Roo.bootstrap.MoneyField, Roo.bootstrap.ComboBox, {
         });
         
         return cfg;
+        
     },
     
     initEvents : function()
+    {
+        this.indicator = this.indicatorEl();
+        
+        this.initCurrencyEvent();
+        
+        this.initNumberEvent();
+        
+    },
+    
+    initCurrencyEvent : function()
     {
         if (!this.store) {
             throw "can not find store for combo";
@@ -39960,15 +40025,168 @@ Roo.extend(Roo.bootstrap.MoneyField, Roo.bootstrap.ComboBox, {
         
         this.createList();
         
-        this.indicator = this.indicatorEl();
-        
         this.triggerEl = this.el.select('.input-group-addon', true).first();
         
         this.triggerEl.on("click", this.onTriggerClick, this, { preventDefault : true });
         
-        this.currencyEl = this.el.select('.roo-money-currency-input', true).first();
+        var _this = this;
+        
+        (function(){
+            var lw = _this.listWidth || Math.max(_this.inputEl().getWidth(), _this.minListWidth);
+            _this.list.setWidth(lw);
+        }).defer(100);
+        
+        this.list.on('mouseover', this.onViewOver, this);
+        this.list.on('mousemove', this.onViewMove, this);
+        this.list.on('scroll', this.onViewScroll, this);
+        
+        if(!this.tpl){
+            this.tpl = '<li><a href="#">{' + this.currencyField + '}</a></li>';
+        }
+        
+        this.view = new Roo.View(this.list, this.tpl, {
+            singleSelect:true, store: this.store, selectedClass: this.selectedClass
+        });
+        
+        this.view.on('click', this.onViewClick, this);
+        
+        this.store.on('beforeload', this.onBeforeLoad, this);
+        this.store.on('load', this.onLoad, this);
+        this.store.on('loadexception', this.onLoadException, this);
+        
+        this.keyNav = new Roo.KeyNav(this.currencyEl(), {
+            "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.collapse();
+                
+                if(this.fireEvent("specialkey", this, e)){
+                    this.onViewClick(false);
+                }
+                
+                return true;
+            },
+
+            "esc" : function(e){
+                this.collapse();
+            },
+
+            "tab" : function(e){
+                this.collapse();
+                
+                if(this.fireEvent("specialkey", this, e)){
+                    this.onViewClick(false);
+                }
+                
+                return true;
+            },
+
+            scope : this,
+
+            doRelay : function(foo, bar, hname){
+                if(hname == 'down' || this.scope.isExpanded()){
+                   return Roo.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 Roo.util.DelayedTask(this.initQuery, this);
+        
+        if(this.typeAhead){
+            this.taTask = new Roo.util.DelayedTask(this.onTypeAhead, this);
+        }
+        
+        this.currencyEl().on("keyup", this.onCurrencyKeyUp, this);
+        
+    },
+    
+    initNumberEvent : function(e)
+    {
+        this.inputEl().on("keydown" , this.fireKey,  this);
+        this.inputEl().on("focus", this.onFocus,  this);
+        this.inputEl().on("blur", this.onBlur,  this);
+        
+        this.inputEl().relayEvent('keyup', this);
+        
+        if(this.indicator){
+            this.indicator.addClass('invisible');
+        }
+        this.originalValue = this.getValue();
+        
+        if(this.validationEvent == 'keyup'){
+            this.validationTask = new Roo.util.DelayedTask(this.validate, this);
+            this.inputEl().on('keyup', this.filterValidation, this);
+        }
+        else if(this.validationEvent !== false){
+            this.inputEl().on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
+        }
+        
+        if(this.selectOnFocus){
+            this.on("focus", this.preFocus, this);
+            
+        }
+        if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Roo.form.VTypes[this.vtype+'Mask']))){
+            this.inputEl().on("keypress", this.filterKeys, this);
+        } else {
+            this.inputEl().relayEvent('keypress', this);
+        }
+        
+        var allowed = "0123456789";
+        
+        if(this.allowDecimals){
+            allowed += this.decimalSeparator;
+        }
+        
+        if(this.allowNegative){
+            allowed += "-";
+        }
         
-        this.amountEl = this.el.select('.roo-money-amount-input', true).first();
+        this.stripCharsRe = new RegExp('[^'+allowed+']', 'gi');
+        
+        var keyPress = function(e){
+            
+            var k = e.getKey();
+            
+            var c = e.getCharCode();
+            
+            if(
+                    (String.fromCharCode(c) == '.' || String.fromCharCode(c) == '-') &&
+                    allowed.indexOf(String.fromCharCode(c)) === -1
+            ){
+                e.stopEvent();
+                return;
+            }
+            
+            if(!Roo.isIE && (e.isSpecialKey() || k == e.BACKSPACE || k == e.DELETE)){
+                return;
+            }
+            
+            if(allowed.indexOf(String.fromCharCode(c)) === -1){
+                e.stopEvent();
+            }
+        };
+        
+        this.inputEl().on("keypress", keyPress, this);
         
     },
     
@@ -39985,7 +40203,9 @@ Roo.extend(Roo.bootstrap.MoneyField, Roo.bootstrap.ComboBox, {
             this.collapse();
             return;
         }
-        Roo.log('run on trigger click');
+        
+        this.hasFocus = true;
+        
         if(this.triggerAction == 'all') {
             this.doQuery(this.allQuery, true);
             return;
@@ -39994,10 +40214,280 @@ Roo.extend(Roo.bootstrap.MoneyField, Roo.bootstrap.ComboBox, {
         this.doQuery(this.getRawValue());
     },
     
+    getCurrency : function()
+    {   
+        var v = this.currencyEl().getValue();
+        
+        return v;
+    },
+    
     restrictHeight : function()
     {
-        this.list.alignTo(this.currencyEl, this.listAlign);
-        this.list.alignTo(this.currencyEl, this.listAlign);
+        this.list.alignTo(this.currencyEl(), this.listAlign);
+        this.list.alignTo(this.currencyEl(), this.listAlign);
+    },
+    
+    onViewClick : function(view, doFocus, el, e)
+    {
+        var index = this.view.getSelectedIndexes()[0];
+        
+        var r = this.store.getAt(index);
+        
+        if(r){
+            this.onSelect(r, index);
+        }
+    },
+    
+    onSelect : function(record, index){
+        
+        if(this.fireEvent('beforeselect', this, record, index) !== false){
+        
+            this.setFromCurrencyData(index > -1 ? record.data : false);
+            
+            this.collapse();
+            
+            this.fireEvent('select', this, record, index);
+        }
+    },
+    
+    setFromCurrencyData : function(o)
+    {
+        var currency = '';
+        
+        this.lastCurrency = o;
+        
+        if (this.currencyField) {
+            currency = !o || typeof(o[this.currencyField]) == 'undefined' ? '' : o[this.currencyField];
+        } else {
+            Roo.log('no  currencyField value set for '+ (this.name ? this.name : this.id));
+        }
+        
+        this.lastSelectionText = currency;
+        
+        this.setCurrency(currency);
+    },
+    
+    setFromData : function(o)
+    {
+        var c = {};
+        
+        c[this.currencyField] = !o || typeof(o[this.currencyName]) == 'undefined' ? '' : o[this.currencyName];
+        
+        this.setFromCurrencyData(c);
+        
+        var value = '';
+        
+        if (this.name) {
+            value = !o || typeof(o[this.name]) == 'undefined' ? '' : o[this.name];
+        } else {
+            Roo.log('no value set for '+ (this.name ? this.name : this.id));
+        }
+        
+        this.setValue(value);
+        
+    },
+    
+    setCurrency : function(v)
+    {   
+        this.currencyValue = v;
+        
+        if(this.rendered){
+            this.currencyEl().dom.value = (v === null || v === undefined ? '' : v);
+            this.validate();
+        }
+    },
+    
+    setValue : function(v)
+    {
+        v = this.fixPrecision(v);
+        
+        v = String(v).replace(".", this.decimalSeparator);
+        
+        this.value = v;
+        
+        if(this.rendered){
+            this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
+            this.validate();
+        }
+    },
+    
+    getRawValue : function()
+    {
+        var v = this.inputEl().getValue();
+        
+        return v;
+    },
+    
+    getValue : function()
+    {
+        return this.fixPrecision(this.parseValue(this.getRawValue()));
+    },
+    
+    parseValue : function(value)
+    {
+        value = parseFloat(String(value).replace(this.decimalSeparator, "."));
+        return isNaN(value) ? '' : value;
+    },
+    
+    fixPrecision : function(value)
+    {
+        var nan = isNaN(value);
+        
+        if(!this.allowDecimals || this.decimalPrecision == -1 || nan || !value){
+            return nan ? '' : value;
+        }
+        
+        return parseFloat(value).toFixed(this.decimalPrecision);
+    },
+    
+    decimalPrecisionFcn : function(v)
+    {
+        return Math.floor(v);
+    },
+    
+    validateValue : function(value)
+    {
+        if(!Roo.bootstrap.MoneyField.superclass.validateValue.call(this, value)){
+            return false;
+        }
+        
+        var num = this.parseValue(value);
+        
+        if(isNaN(num)){
+            this.markInvalid(String.format(this.nanText, value));
+            return false;
+        }
+        
+        if(num < this.minValue){
+            this.markInvalid(String.format(this.minText, this.minValue));
+            return false;
+        }
+        
+        if(num > this.maxValue){
+            this.markInvalid(String.format(this.maxText, this.maxValue));
+            return false;
+        }
+        
+        return true;
+    },
+    
+    validate : function()
+    {
+        if(this.disabled){
+            this.markValid();
+            return true;
+        }
+        
+        var currency = this.getCurrency();
+        
+        if(this.validateValue(this.getRawValue()) && currency.length){
+            this.markValid();
+            return true;
+        }
+        
+        this.markInvalid();
+        return false;
+    },
+    
+    getName: function()
+    {
+        return this.name;
+    },
+    
+    beforeBlur : function()
+    {
+        if(!this.castInt){
+            return;
+        }
+        
+        var v = this.parseValue(this.getRawValue());
+        
+        if(v){
+            this.setValue(v);
+        }
+    },
+    
+    onBlur : function()
+    {
+        this.beforeBlur();
+        
+        if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
+            //this.el.removeClass(this.focusClass);
+        }
+        
+        this.hasFocus = false;
+        
+        if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
+            this.validate();
+        }
+        
+        var v = this.getValue();
+        
+        if(String(v) !== String(this.startValue)){
+            this.fireEvent('change', this, v, this.startValue);
+        }
+        
+        this.fireEvent("blur", this);
+    },
+    
+    onCurrencyKeyUp : function(e)
+    {
+        Roo.log('on currency keyup');
+        if(!e.isSpecialKey()){
+            this.lastKey = e.getKey();
+            this.dqTask.delay(this.queryDelay);
+        }
+    },
+    
+    inputEl : function()
+    {
+        return this.el.select('.roo-money-amount-input', true).first();
+    },
+    
+    currencyEl : function()
+    {
+        return this.el.select('.roo-money-currency-input', true).first();
+    },
+    
+    initQuery : function()
+    {
+        var v = this.getCurrency();
+        Roo.log('initQuery???');
+        this.doQuery(v);
+    },
+    
+    onTypeAhead : function()
+    {
+        if(this.store.getCount() > 0){
+            var r = this.store.getAt(0);
+            var newValue = r.data[this.currencyField];
+            var len = newValue.length;
+            var selStart = this.getCurrency().length;
+            
+            if(selStart != len){
+                this.setCurrency(newValue);
+                this.selectText(selStart, newValue.length);
+            }
+        }
+    },
+    
+    selectText : function(start, end)
+    {
+        var v = this.getCurrency();
+        
+        if(v.length > 0){
+            start = start === undefined ? 0 : start;
+            end = end === undefined ? v.length : end;
+            var d = this.el.dom;
+            if(d.setSelectionRange){
+                d.setSelectionRange(start, end);
+            }else if(d.createTextRange){
+                var range = d.createTextRange();
+                range.moveStart("character", start);
+                range.moveEnd("character", v.length-end);
+                range.select();
+            }
+        }
     }
     
 });
\ No newline at end of file