Number Field with currency symbol, thousand separator & international support ExtJS4
Number Field with currency symbol, thousand separator & international support ExtJS4
http://www.sencha.com/forum/showthread.php?147962-Number-Field-with-currency-symbol-thousand-separator-amp-international-support-ExtJS4/page2
/*
* GNU General Public License Usage
* This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
*
* http://www.gnu.org/licenses/lgpl.html
*
* @description: This class provide aditional format to numbers by extending Ext.form.field.Number
*
* @author: Greivin Britton
* @email: [email protected]
* @version: 2 compatible with ExtJS 4
*/
Ext.define('Ext.ux.form.NumericField', {
extend: 'Ext.form.field.Number',//Extending the NumberField
alias: 'widget.numericfield',//Defining the xtype,
currencySymbol: null,
currencySymbolPos : 'right', // left , right
useThousandSeparator: true,
thousandSeparator: ',',
alwaysDisplayDecimals: false,
fieldStyle: 'text-align: right;',
hideTrigger:true,
initComponent: function(){
if (this.useThousandSeparator && this.decimalSeparator == ',' && this.thousandSeparator == ',')
this.thousandSeparator = '.';
else
if (this.allowDecimals && this.thousandSeparator == '.' && this.decimalSeparator == '.')
this.decimalSeparator = ',';
this.callParent(arguments);
},
setValue: function(value){
Ext.ux.form.NumericField.superclass.setValue.call(this, value != null ? value.toString().replace('.', this.decimalSeparator) : value);
this.setRawValue(this.getFormattedValue(this.getValue()));
},
getFormattedValue: function(value){
if (Ext.isEmpty(value) || !this.hasFormat())
return value;
else
{
var neg = null;
value = (neg = value < 0) ? value * -1 : value;
value = this.allowDecimals && this.alwaysDisplayDecimals ? value.toFixed(this.decimalPrecision) : value;
if (this.useThousandSeparator)
{
if (this.useThousandSeparator && Ext.isEmpty(this.thousandSeparator))
throw ('NumberFormatException: invalid thousandSeparator, property must has a valid character.');
if (this.thousandSeparator == this.decimalSeparator)
throw ('NumberFormatException: invalid thousandSeparator, thousand separator must be different from decimalSeparator.');
value = value.toString();
var ps = value.split('.');
ps[1] = ps[1] ? ps[1] : null;
var whole = ps[0];
var r = /(\d+)(\d{3})/;
var ts = this.thousandSeparator;
while (r.test(whole))
whole = whole.replace(r, '$1' + ts + '$2');
value = whole + (ps[1] ? this.decimalSeparator + ps[1] : '');
}
if (this.currencySymbolPos == 'right') { return Ext.String.format('{0}{1}{2}', (neg ? '-' : ''), value, (Ext.isEmpty(this.currencySymbol) ? '' : ' ' + this.currencySymbol)); } else {
return Ext.String.format('{0}{1}{2}', (neg ? '-' : ''), (Ext.isEmpty(this.currencySymbol) ? '' : this.currencySymbol + ' '), value); }
}
},
/**
* overrides parseValue to remove the format applied by this class
*/
parseValue: function(value){
//Replace the currency symbol and thousand separator
return Ext.ux.form.NumericField.superclass.parseValue.call(this, this.removeFormat(value));
},
/**
* Remove only the format added by this class to let the superclass validate with it's rules.
* @param {Object} value
*/
removeFormat: function(value){
if (Ext.isEmpty(value) || !this.hasFormat())
return value;
else
{
if (this.currencySymbolPos == 'right') { value = value.toString().replace(' ' + this.currencySymbol, ''); } else { value = value.toString().replace(this.currencySymbol + ' ', ''); }
value = this.useThousandSeparator ? value.replace(new RegExp('[' + this.thousandSeparator + ']', 'g'), '') : value;
return value;
}
},
/**
* Remove the format before validating the the value.
* @param {Number} value
*/
getErrors: function(value){
return Ext.ux.form.NumericField.superclass.getErrors.call(this, this.removeFormat(value));
},
hasFormat: function(){
return this.decimalSeparator != '.' || (this.useThousandSeparator == true && this.getRawValue() != null) || !Ext.isEmpty(this.currencySymbol) || this.alwaysDisplayDecimals;
},
/**
* Display the numeric value with the fixed decimal precision and without the format using the setRawValue, don't need to do a setValue because we don't want a double
* formatting and process of the value because beforeBlur perform a getRawValue and then a setValue.
*/
onFocus: function(){
this.setRawValue(this.removeFormat(this.getRawValue()));
this.callParent(arguments);
},
processRawValue: function(value) {
return this.removeFormat(value);
}
});
OK, I think I figured out a way to get this to submit the "raw" (i.e. unformatted, numeric-only) value. And I think you were on the right track with processRawValue, brittongr. At least it appears to be working for me. Changes to the source (just the one function override) from the zip file are shown below in bold:
onFocus: function(){
this.setRawValue(this.removeFormat(this.getRawValue()));
this.callParent(arguments);
},
processRawValue: function(value) {
return this.removeFormat(value);
}
Ext.define('Teller.ext.CurrencyField', {
extend: 'Ext.form.field.Number',
alias: 'widget.currencyfield',
hideTrigger: true,
setValue: function (v) {
this.callParent(arguments);
if (!Ext.isEmpty(this.getValue())) {
this.setRawValue(Ext.util.Format.currency(this.getValue()));
} }, removeFormat: function (v) {
if (Ext.isEmpty(v)) {
return '';
} else {
v = v.toString().replace(Ext.util.Format.currencySign, '').replace(Ext.util.Format.thousandSeparator, '');
if (v % 1 === 0) { // Return value formatted with no precision since there are no digits after the decimal return Ext.util.Format.number(v, '0'); } else { // Return value formatted with precision of two digits since there are digits after the decimal
return Ext.util.Format.number(v, '0.00'); } } }, // Override parseValue to remove the currency format
parseValue: function (v) { return this.callParent([this.removeFormat(v)]); }, // Remove the format before validating the value getErrors: function (v) {
return this.callParent([this.removeFormat(v)]); }, /* Override getSubmitData to remove the currency format on the value that will be passed out from the getValues method of the form */ getSubmitData: function () { var returnObject = {}; returnObject[this.name] = this.removeFormat(this.callParent(arguments)[this.name]);
return returnObject; }, // Override preFocus to remove the format during edit preFocus: function () {
this.setRawValue(this.removeFormat(this.getRawValue()));
this.callParent(arguments); } });
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
문자열 길이를 계산하고 중국어로 두 개를 계산합니다.
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
/*
* GNU General Public License Usage
* This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
*
* http://www.gnu.org/licenses/lgpl.html
*
* @description: This class provide aditional format to numbers by extending Ext.form.field.Number
*
* @author: Greivin Britton
* @email: [email protected]
* @version: 2 compatible with ExtJS 4
*/
Ext.define('Ext.ux.form.NumericField', {
extend: 'Ext.form.field.Number',//Extending the NumberField
alias: 'widget.numericfield',//Defining the xtype,
currencySymbol: null,
currencySymbolPos : 'right', // left , right
useThousandSeparator: true,
thousandSeparator: ',',
alwaysDisplayDecimals: false,
fieldStyle: 'text-align: right;',
hideTrigger:true,
initComponent: function(){
if (this.useThousandSeparator && this.decimalSeparator == ',' && this.thousandSeparator == ',')
this.thousandSeparator = '.';
else
if (this.allowDecimals && this.thousandSeparator == '.' && this.decimalSeparator == '.')
this.decimalSeparator = ',';
this.callParent(arguments);
},
setValue: function(value){
Ext.ux.form.NumericField.superclass.setValue.call(this, value != null ? value.toString().replace('.', this.decimalSeparator) : value);
this.setRawValue(this.getFormattedValue(this.getValue()));
},
getFormattedValue: function(value){
if (Ext.isEmpty(value) || !this.hasFormat())
return value;
else
{
var neg = null;
value = (neg = value < 0) ? value * -1 : value;
value = this.allowDecimals && this.alwaysDisplayDecimals ? value.toFixed(this.decimalPrecision) : value;
if (this.useThousandSeparator)
{
if (this.useThousandSeparator && Ext.isEmpty(this.thousandSeparator))
throw ('NumberFormatException: invalid thousandSeparator, property must has a valid character.');
if (this.thousandSeparator == this.decimalSeparator)
throw ('NumberFormatException: invalid thousandSeparator, thousand separator must be different from decimalSeparator.');
value = value.toString();
var ps = value.split('.');
ps[1] = ps[1] ? ps[1] : null;
var whole = ps[0];
var r = /(\d+)(\d{3})/;
var ts = this.thousandSeparator;
while (r.test(whole))
whole = whole.replace(r, '$1' + ts + '$2');
value = whole + (ps[1] ? this.decimalSeparator + ps[1] : '');
}
if (this.currencySymbolPos == 'right') { return Ext.String.format('{0}{1}{2}', (neg ? '-' : ''), value, (Ext.isEmpty(this.currencySymbol) ? '' : ' ' + this.currencySymbol)); } else {
return Ext.String.format('{0}{1}{2}', (neg ? '-' : ''), (Ext.isEmpty(this.currencySymbol) ? '' : this.currencySymbol + ' '), value); }
}
},
/**
* overrides parseValue to remove the format applied by this class
*/
parseValue: function(value){
//Replace the currency symbol and thousand separator
return Ext.ux.form.NumericField.superclass.parseValue.call(this, this.removeFormat(value));
},
/**
* Remove only the format added by this class to let the superclass validate with it's rules.
* @param {Object} value
*/
removeFormat: function(value){
if (Ext.isEmpty(value) || !this.hasFormat())
return value;
else
{
if (this.currencySymbolPos == 'right') { value = value.toString().replace(' ' + this.currencySymbol, ''); } else { value = value.toString().replace(this.currencySymbol + ' ', ''); }
value = this.useThousandSeparator ? value.replace(new RegExp('[' + this.thousandSeparator + ']', 'g'), '') : value;
return value;
}
},
/**
* Remove the format before validating the the value.
* @param {Number} value
*/
getErrors: function(value){
return Ext.ux.form.NumericField.superclass.getErrors.call(this, this.removeFormat(value));
},
hasFormat: function(){
return this.decimalSeparator != '.' || (this.useThousandSeparator == true && this.getRawValue() != null) || !Ext.isEmpty(this.currencySymbol) || this.alwaysDisplayDecimals;
},
/**
* Display the numeric value with the fixed decimal precision and without the format using the setRawValue, don't need to do a setValue because we don't want a double
* formatting and process of the value because beforeBlur perform a getRawValue and then a setValue.
*/
onFocus: function(){
this.setRawValue(this.removeFormat(this.getRawValue()));
this.callParent(arguments);
},
processRawValue: function(value) {
return this.removeFormat(value);
}
});
OK, I think I figured out a way to get this to submit the "raw" (i.e. unformatted, numeric-only) value. And I think you were on the right track with processRawValue, brittongr. At least it appears to be working for me. Changes to the source (just the one function override) from the zip file are shown below in bold:
onFocus: function(){
this.setRawValue(this.removeFormat(this.getRawValue()));
this.callParent(arguments);
},
processRawValue: function(value) {
return this.removeFormat(value);
}
Ext.define('Teller.ext.CurrencyField', {
extend: 'Ext.form.field.Number',
alias: 'widget.currencyfield',
hideTrigger: true,
setValue: function (v) {
this.callParent(arguments);
if (!Ext.isEmpty(this.getValue())) {
this.setRawValue(Ext.util.Format.currency(this.getValue()));
} }, removeFormat: function (v) {
if (Ext.isEmpty(v)) {
return '';
} else {
v = v.toString().replace(Ext.util.Format.currencySign, '').replace(Ext.util.Format.thousandSeparator, '');
if (v % 1 === 0) { // Return value formatted with no precision since there are no digits after the decimal return Ext.util.Format.number(v, '0'); } else { // Return value formatted with precision of two digits since there are digits after the decimal
return Ext.util.Format.number(v, '0.00'); } } }, // Override parseValue to remove the currency format
parseValue: function (v) { return this.callParent([this.removeFormat(v)]); }, // Remove the format before validating the value getErrors: function (v) {
return this.callParent([this.removeFormat(v)]); }, /* Override getSubmitData to remove the currency format on the value that will be passed out from the getValues method of the form */ getSubmitData: function () { var returnObject = {}; returnObject[this.name] = this.removeFormat(this.callParent(arguments)[this.name]);
return returnObject; }, // Override preFocus to remove the format during edit preFocus: function () {
this.setRawValue(this.removeFormat(this.getRawValue()));
this.callParent(arguments); } });
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
문자열 길이를 계산하고 중국어로 두 개를 계산합니다.텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.