Ext.define('Ext.form.field.Number', {
extend:'Ext.form.field.Spinner',
alias: 'widget.numberfield',
alternateClassName: ['Ext.form.NumberField', 'Ext.form.Number'],
allowDecimals : true,
decimalSeparator : '.',
submitLocaleSeparator: true,
decimalPrecision : 2,
minValue: Number.NEGATIVE_INFINITY,
maxValue: Number.MAX_VALUE,
step: 1,
minText : 'The minimum value for this field is {0}',
maxText : 'The maximum value for this field is {0}',
nanText : '{0} is not a valid number',
negativeText : 'The value cannot be negative',
baseChars : '0123456789',
autoStripChars: false,
initComponent: function() {
var me = this,
allowed;
me.callParent();
me.setMinValue(me.minValue);
me.setMaxValue(me.maxValue);
if (me.disableKeyFilter !== true) {
allowed = me.baseChars + '';
if (me.allowDecimals) {
allowed += me.decimalSeparator;
}
if (me.minValue < 0) {
allowed += '-';
}
allowed = Ext.String.escapeRegex(allowed);
me.maskRe = new RegExp('[' + allowed + ']');
if (me.autoStripChars) {
me.stripCharsRe = new RegExp('[^' + allowed + ']', 'gi');
}
}
},
getErrors: function(value) {
var me = this,
errors = me.callParent(arguments),
format = Ext.String.format,
num;
value = Ext.isDefined(value) ? value : this.processRawValue(this.getRawValue());
if (value.length < 1) {
return errors;
}
value = String(value).replace(me.decimalSeparator, '.');
if(isNaN(value)){
errors.push(format(me.nanText, value));
}
num = me.parseValue(value);
if (me.minValue === 0 && num < 0) {
errors.push(this.negativeText);
}
else if (num < me.minValue) {
errors.push(format(me.minText, me.minValue));
}
if (num > me.maxValue) {
errors.push(format(me.maxText, me.maxValue));
}
return errors;
},
rawToValue: function(rawValue) {
var value = this.fixPrecision(this.parseValue(rawValue));
if (value === null) {
value = rawValue || null;
}
return value;
},
valueToRaw: function(value) {
var me = this,
decimalSeparator = me.decimalSeparator;
value = me.parseValue(value);
value = me.fixPrecision(value);
value = Ext.isNumber(value) ? value : parseFloat(String(value).replace(decimalSeparator, '.'));
value = isNaN(value) ? '' : String(value).replace('.', decimalSeparator);
return value;
},
getSubmitValue: function() {
var me = this,
value = me.callParent();
if (!me.submitLocaleSeparator) {
value = value.replace(me.decimalSeparator, '.');
}
return value;
},
onChange: function() {
this.toggleSpinners();
this.callParent(arguments);
},
toggleSpinners: function(){
var me = this,
value = me.getValue(),
valueIsNull = value === null;
me.setSpinUpEnabled(valueIsNull || value < me.maxValue);
me.setSpinDownEnabled(valueIsNull || value > me.minValue);
},
setMinValue : function(value) {
this.minValue = Ext.Number.from(value, Number.NEGATIVE_INFINITY);
this.toggleSpinners();
},
setMaxValue: function(value) {
this.maxValue = Ext.Number.from(value, Number.MAX_VALUE);
this.toggleSpinners();
},
parseValue : function(value) {
value = parseFloat(String(value).replace(this.decimalSeparator, '.'));
return isNaN(value) ? null : value;
},
fixPrecision : function(value) {
var me = this,
nan = isNaN(value),
precision = me.decimalPrecision;
if (nan || !value) {
return nan ? '' : value;
} else if (!me.allowDecimals || precision <= 0) {
precision = 0;
}
return parseFloat(Ext.Number.toFixed(parseFloat(value), precision));
},
beforeBlur : function() {
var me = this,
v = me.parseValue(me.getRawValue());
if (!Ext.isEmpty(v)) {
me.setValue(v);
}
},
onSpinUp: function() {
var me = this;
if (!me.readOnly) {
me.setValue(Ext.Number.constrain(me.getValue() + me.step, me.minValue, me.maxValue));
}
},
onSpinDown: function() {
var me = this;
if (!me.readOnly) {
me.setValue(Ext.Number.constrain(me.getValue() - me.step, me.minValue, me.maxValue));
}
}
});