Format Number Field with decimals, currency symbol, thousand separator ExtJS4

Force NumberField to show .00 by default in Ext JS

I have been trying to create a NumberField in Ext JS which by default should show an integer number lets say '4' as '4.00'. I searched lot of resources online to achieve this, finally I found a solution to the problem from sencha.com.

Here is the Extension.
Copy the below code and save the file as NumberField.js.
Place the file in the following path of your Project
extjs/ux/form/NumberField.js

/*
 * 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: brittongr@gmail.com
 * @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,
    useThousandSeparator: true,
    thousandSeparator: ',',
    alwaysDisplayDecimals: false,
    fieldStyle: 'text-align: right;',
    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] : '');
            }
           
            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
        {
            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);
    }
});


Now you can use the above NumberField in your application. To use the above custom made NumberFiled follow the below steps.
In your app.js or ServerApp.js add the below line.
Ext.require([
                         'Ext.ux.form.NumericField'
         ]);

If you already have this command with other Ext Libraries add this this ('Ext.ux.form.NumericField') entry also.

Now create a form field using the above extension. Here is the example

{
xtype: 'container',
columnWidth:.2,
title : 'Form Fields',
items: [

 Ext.create('Ext.ux.form.NumericField',
                                   {
                                         fieldLabel: '',
                                         name: 'Field-1',
                                         allowBlank:false,    
                                         useThousandSeparator: true,
                                         decimalPrecision: 2,
                                         alwaysDisplayDecimals: true,
                                         allowNegative: false,
                                         currencySymbol:'$',
                                         value: 0,
                                         thousandSeparator: ',',
                                         tabIndex:1                                 }
                                   }),

 Ext.create('Ext.ux.form.NumericField',
                                   {
                                         fieldLabel: '',
                                         name: 'Field-2',
                                         allowBlank:false,    
                                         useThousandSeparator: true,
                                         decimalPrecision: 2,
                                         alwaysDisplayDecimals: true,
                                         allowNegative: false,
                                         currencySymbol:'$',
                                         value: 0,
                                         thousandSeparator: ',',
                                         tabIndex:1                                 }
                                   })

]}

Check the Image below for all the Formats.
Click here for Image


This should solve your problem.
Many thanks to the Owner who wrote this extension. For original post refer the below link click here



7 comments:

Francisco José Hernández said...

Thank you.

I have added a new parameter to specify the position of currency symbol

Francisco José Hernández said...

Thank you.

I have added a new parameter to specify the position of currency symbol

Anonymous said...

Hey there! I could have sworn I've been to this blog before but after checking through some of the post I realized it's new to me.
Nonetheless, I'm definitely delighted I found it and I'll be book-marking and checking back
frequently!

Look at my site; pure garcinia cambogia

nattjar said...

Thank you.

nattjar said...

Thank you.

Omid Shariati said...

good. I wrote another one just support thousandSeparator. you can find it on https://github.com/omids20m/Ext.override.ThousandSeparatorNumberField

Anonymous said...

Thank you!Can you fix it to be compatible with extjs5? because it throws an error.thnx in advance..