Working NumericField / CurrencyField

  1. #1

    NumericField / CurrencyField

    Doesn't work.
    Value is send to server with currency sign and thousand seperator.
    Then in NumberFieldBase.Number it does the following:

    Convert.ToDouble(this.Value == null ? this.EmptyValue : this.Value)


    On ExtJs someone made a NumericField from a NumberField for ExtJs 4:
    http://www.sencha.com/forum/showthre...support-ExtJS4

    Didn't find any on the forums here.
    Except for TextFields that act like one.
    So made a ExtNet 2 control from it.

    JavaScript I used from the link above:
    Don't forget to set the "Build Action" to "Embedded Resource".
    Will probable change the negative sign to be in front of the value instead of the currency symbol.
    /*
     * 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);
        }
    });
    Control:
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Web.UI;
    using System.Xml.Serialization;
    using Ext.Net;
    using Newtonsoft.Json;
    
    [assembly: WebResource("TestWebApp.Controls.ExtNet.NumericField.js", "text/javascript")]
    namespace TestWebApp.Controls.ExtNet
    {
        public class NumericField : NumberField
        {
            #region Members
    
            private string _currencySymbol;
            private bool _useThousandSeparator = true;
            private string _thousandSeparator = ",";
            private bool _alwaysDisplayDecimals;
            private string _fieldStyle = "text-align:right;";
    
            #endregion Members
    
    
            #region Properties
    
            #region Custom
    
            [DefaultValue((string)null)]
            public string CurrencySymbol
            {
                get { return _currencySymbol; }
                set { _currencySymbol = value; }
            }
    
            [DefaultValue((string)null)]
            public bool UseThousandSeparator
            {
                get { return _useThousandSeparator; }
                set { _useThousandSeparator = value; }
            }
    
            [DefaultValue((string)null)]
            public string ThousandSeparator
            {
                get { return _thousandSeparator; }
                set { _thousandSeparator = value; }
            }
    
            [DefaultValue((string)null)]
            public bool AlwaysDisplayDecimals
            {
                get { return _alwaysDisplayDecimals; }
                set { _alwaysDisplayDecimals = value; }
            }
    
            [DefaultValue((string)null)]
            public string FieldStyle
            {
                get { return _fieldStyle; }
                set { _fieldStyle = value; }
            }
    
            #endregion Custom
    
            #region Override
    
            /// <summary>
            /// 
            /// </summary>
            [Browsable(false)]
            [EditorBrowsable(EditorBrowsableState.Never)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
            [XmlIgnore]
            [JsonIgnore]
            public override ConfigOptionsCollection ConfigOptions
            {
                get
                {
                    ConfigOptionsCollection list = base.ConfigOptions;
    
                    list.Add("currencySymbol", new ConfigOption("currencySymbol", null, true, CurrencySymbol));
                    list.Add("useThousandSeparator", new ConfigOption("useThousandSeparator", null, null, UseThousandSeparator));
                    list.Add("thousandSeparator", new ConfigOption("thousandSeparator", null, null, ThousandSeparator));
                    list.Add("alwaysDisplayDecimals", new ConfigOption("alwaysDisplayDecimals", null, null, AlwaysDisplayDecimals));
                    list.Add("fieldStyle", new ConfigOption("fieldStyle", null, "identificador", FieldStyle));
    
                    return list;
                }
            }
    
            /// <summary>
            /// 
            /// </summary>
            [Description("")]
            protected override List<ResourceItem> Resources
            {
                get
                {
                    List<ResourceItem> resources = base.Resources;
    
                    resources.Capacity += 1;
                    resources.Add(new ClientScriptItem(GetType(), "TestWebApp.Controls.ExtNet.NumericField.js", @"/Controls/ExtNet/NumericField.js"));
    
                    return resources;
                }
            }
    
            /// <summary>
            /// 
            /// </summary>
            [Category("0. About")]
            [Description("")]
            public override string InstanceOf { get { return "Ext.ux.form.NumericField"; } }
    
            /// <summary>
            /// 
            /// </summary>
            [Category("0. About")]
            [Description("")]
            public override string XType { get { return "numericfield"; } }
    
            #endregion Override
    
            #endregion Properties
    
    
            #region Constructors
    
            public NumericField() : base() { }
    
            public NumericField(Config config) : base(config) { }
    
            #endregion
        }
    }
    Made a separate control to have the default setting I want:
    using System.Globalization;
    
    namespace TestWebApp.Controls.ExtNet
    {
        public class LocalizedCurrencyField : NumericField
        {
            public LocalizedCurrencyField()
            {
                CurrencySymbol = NumberFormatInfo.CurrentInfo.CurrencySymbol;
                base.DecimalSeparator = NumberFormatInfo.CurrentInfo.CurrencyDecimalSeparator;
                ThousandSeparator = NumberFormatInfo.CurrentInfo.CurrencyGroupSeparator;
                AlwaysDisplayDecimals = true;
                FieldStyle = "text-align:left;";
                base.SelectOnFocus = true;
            }
        }
    }
    Last edited by mturnhout; Feb 13, 2015 at 2:07 PM.
  2. #2
    Can retrieve the right value in the console with:
    Ext.getCmp('Input_currencyField').getValue()

    But at server side:
    Value = -1.7976931348623157E+308
    Text = ""

    It sends the value to the server as:
    ? 2.343,00
    Last edited by mturnhout; Feb 12, 2015 at 8:18 AM.

Similar Threads

  1. Replies: 0
    Last Post: Oct 07, 2014, 8:06 AM
  2. Replies: 0
    Last Post: Oct 30, 2012, 5:34 PM
  3. Replies: 3
    Last Post: Feb 21, 2012, 7:46 AM
  4. MaxLength validation in TextField & NumericField
    By madhugumma in forum 1.x Help
    Replies: 0
    Last Post: Aug 06, 2009, 4:46 AM

Tags for this Thread

Posting Permissions