Reputation: 2113
I am using ExtJS 4.1, and trying to display my currency field as value / 1000, but only on display. For example, if user input 1234.56, it will appear as 1,234.56 on screen, but only when it is displayed on screen. For everything else, it is stored as 1234560. In every calculation behind that number is treated as 1234560. I am using bigint as store, and I want to avoid float, since in my country, 2 billion is a normal number, but will also need the fraction part.
How can you do that?
Thank you.
Upvotes: 1
Views: 8884
Reputation: 954
One way would be to create a new component extending the base text box, add a property named something like storedValue to it, and register handlers for the focus and blur events to convert the stored value to a decimal value for display/editing, then to a comma formatted version and updated the stored value with the integer value.
EDIT
Just got back to work an thought this old snippet of code might be useful. It is the currency field that I created for myself a while back. The listeners on the parent form only work with my extended version of the form that has a before/after update event. There is probably a better way to do that like overloading the getValue, getSubmitValue, and getSubmitData functions as needed in your application. My need was just to show currency symbols and commas so it will need to be modified for your needs but it should provide a decent starting point if you aren't too far along yet or are having any trouble. Good luck.
Ext.define('Ext.ux.form.field.Currency', {
extend: 'Ext.form.field.Text',
alias: 'widget.currencyfield',
initComponent: function (config) {
this.callParent(arguments);
},
hasFocus: false,
listeners: {
render: function () {
var form = this.findParentByType('form');
form.on('afterLoadRecord', function () {
this.toRaw();
if (this.getRawValue() == 0) {
this.setRawValue('');
} else {
this.toFormatted();
}
}, this);
form.on('beforeUpdateRecord', function () {
this.toRaw();
}, this);
form.on('afterUpdateRecord', function () {
this.toRaw();
if (this.getRawValue() == 0) {
this.setRawValue('');
} else {
this.toFormatted();
}
}, this);
},
focus: function (field, e, eOpts) {
this.toRaw();
this.hasFocus = true;
},
blur: function (field, e, eOpts) {
//Clear out commas and $
this.toRaw();
//If there's a value, format it
if(field.getValue() != '') {
this.toFormatted();
this.hasFocus = false;
}
}
},
stripAlpha: function (value) {
return value.replace(/[^0-9.]/g, '');
},
toRaw: function () {
if (this.readOnly !== true) {
this.setRawValue(this.stripAlpha(this.getRawValue()));
}
},
toFormatted: function () {
this.setRawValue(Ext.util.Format.currency(this.getRawValue(), '$ ', 0));
},
getValue: function () {
return parseFloat(this.stripAlpha(this.getRawValue()));
}
});
Upvotes: 1
Reputation: 2113
After playing around, I have another solution, one based on model. Create a non-existent field, such as price_display, and use it to display;
Ext.define('app.model.PriceSample', {
extend: 'Ext.data.Model',
field: [
{name: 'price', type: 'int'},
{name: 'price_display', type: 'float', convert: function (value, records) {
if (value) { //on write
record.set('price', value * 1000);
return value;
} else {
return record.get('price') / 1000;
}
}}
]
}
on your grid or combo or anything use price_display instead of price. but when you want to perform a math, use price.
Upvotes: 0