【问题标题】:How do I force the display of a decimal in an ExtJS NumberField to a certain precision?如何强制 ExtJS NumberField 中的小数显示达到一定的精度?
【发布时间】:2009-08-17 12:04:28
【问题描述】:

我有一个带有NumberField 的表单,它从JSON 中获取float 类型的值。如果值恰好是整数,则不显示小数位。我想始终显示 2 位小数。有这个配置选项吗?

这是我的声明:

items: [
    { 
        fieldLabel: 'Net Sales',
        name: 'netSales',
        allowBlank:false,
        decimalPrecision:2
    },

【问题讨论】:

    标签: extjs extjs4 extjs3


    【解决方案1】:

    因为这是关于在 NumberField 中强制小数的搜索查询的最高结果,所以我想我会为那些使用 ExtJS 4+ 的人更新它

    自 ExtJS 4 以来的输入过滤已委托给 valueToRaw 函数,使用的 setValue 函数实际上来自 Ext.form.field.Text,所以这就是我在下面覆盖的内容。

    我还决定将强制显示小数作为每个 NumberField 可配置的选项(“forcePrecision”),这意味着覆盖将如下所示:

    Ext.override(Ext.form.NumberField, {
        forcePrecision : false,
    
        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, '.'));
            if (isNaN(value))
            {
              value = '';
            } else {
              value = me.forcePrecision ? value.toFixed(me.decimalPrecision) : parseFloat(value);
              value = String(value).replace(".", decimalSeparator);
            }
            return value;
        }
    });
    

    要在您的表单中使用它,您可以像这样实例化它:

    {
      xtype: 'numberfield',
      name:  'decimalsfield',
      forcePrecision: true,     #defaults to false
      decimalPrecision: 3       #defaults to 2
    }
    

    未使用 forcePrecision: true 实例化的字段的行为与默认值完全相同。

    【讨论】:

      【解决方案2】:

      流行的解决方案对我不起作用。事实上,解决方案中的代码与 EXT JS 3.3 源代码完全相同,对我来说,当 decimalPrecision 为 2 时显示“1”而不是“1.00”。根据流行的解决方案建议覆盖 setValue,这就是我做到了:

      Ext.override(Ext.form.NumberField, {
          setValue: function(v) {
              var dp = this.decimalPrecision;
              if (dp < 0 || !this.allowDecimals) {
                  dp = 0;
              }
              v = this.fixPrecision(v);
              v = Ext.isNumber(v) ? v : parseFloat(String(v).replace(this.decimalSeparator, "."));
              v = isNaN(v) ? '' : String(v.toFixed(dp)).replace(".", this.decimalSeparator);
              return Ext.form.NumberField.superclass.setValue.call(this, v);
          }
      });
      

      即使 fixPrecision 代码似乎以所需的精度格式化数字,javascript 在调用超类的 setValue 函数之前对两行执行的操作期间会丢失精度。在最终转换为字符串时使用 toFixed 设置精度使其工作。

      祝你好运!

      【讨论】:

        【解决方案3】:

        延长

        var myNumberField = Ext.extend(Ext.form.NumberField, {
                setValue : function(v){
                    v = typeof v == 'number' ? v : String(v).replace(this.decimalSeparator, ".");
                    v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
                    //  if you want to ensure that the values being set on the field is also forced to the required number of decimal places.
                    // (not extensively tested)
                    // v = isNaN(v) ? '' : this.fixPrecision(String(v).replace(".", this.decimalSeparator));
                    return Ext.form.NumberField.superclass.setValue.call(this, v);
                },
                fixPrecision : function(value){
                    var nan = isNaN(value);
                    if(!this.allowDecimals || this.decimalPrecision == -1 || nan || !value){
                       return nan ? '' : value;
                    }
                    return parseFloat(value).toFixed(this.decimalPrecision);
                }
            });
        
        ...
        ...
        
        items: [new myNumberField({
                id  : 'net',
                fieldLabel: 'Net Sales',
                allowBlank:false,
                decimalPrecision:2
            }),
        

        覆盖,这将影响应用程序中的所有数字字段:

        Ext.override(Ext.form.NumberField, {
            setValue : function(v){
                    v = typeof v == 'number' ? v : String(v).replace(this.decimalSeparator, ".");
                v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
                return Ext.form.NumberField.superclass.setValue.call(this, v);
            },
            fixPrecision : function(value){
                var nan = isNaN(value);
                if(!this.allowDecimals || this.decimalPrecision == -1 || nan || !value){
                   return nan ? '' : value;
                }
                return parseFloat(value).toFixed(this.decimalPrecision);
            }
        })
        
        items: [{
                xtype   : 'numberfield',
                fieldLabel: 'Net Sales',
                allowBlank:false,
                decimalPrecision:2
            },
        

        编辑

        注意第一个 setValue 方法中的注释部分。

        【讨论】:

        • 我已经尝试过您的覆盖,它在更改事件上效果很好。但是,当表单首次从 JsonStore 加载数据时,不会调用 fixPrecision。有没有办法触发它?
        • 工作就像一个魅力,约书亚。谢谢!
        【解决方案4】:

        最好的办法可能是为它添加一个模糊事件的侦听器,然后对字段的值使用内置的 Javascript .toFixed(2) 函数。

        【讨论】:

          【解决方案5】:

          选项decimalPrecision定义为: "小数点后显示的最大精度(默认为2)"

          没有强制格式的选项,您可能必须覆盖 NumberField 类。

          【讨论】:

            【解决方案6】:

            如果您想要以下内容:

            输入 50 > 你得到了 50

            50.10 > 50.10

            50.123 > 50.12

            试试这个:

            , setValue: function (v) {
                  if ( !v || isNaN(v)) {
                    v = '';
                  }
                  else if (v % 1 != 0) {    //means number is not whole number
                    v = this.fixPrecision(String(v).replace(".", this.decimalSeparator));
                  }
            
                 return Ext.form.NumberField.superclass.setValue.call(this, v);
            }
            , fixPrecision: function (value) {
                if (!this.allowDecimals || this.decimalPrecision == -1) {
                   return value;
                }
            
                return parseFloat(value).toFixed(this.decimalPrecision);
            }
            

            【讨论】:

              【解决方案7】:

              这段代码对我很有用。如果没有 ExtJS 4.2.0 中的“ValueToRow”覆盖,它将无法工作。

              var myNumberField = Ext.extend(Ext.form.NumberField, {
                  setValue : function(v){
                      v = typeof v == 'number' ? v : String(v).replace(this.decimalSeparator, ".");
                      v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
                      return Ext.form.NumberField.superclass.setValue.call(this, v);
                  },
                  fixPrecision : function(value){
                      var nan = isNaN(value);
                      if(!this.allowDecimals || this.decimalPrecision == -1 || nan || !value){
                      return nan ? '' : value;
                      }
                      var val = parseFloat(value).toFixed(this.decimalPrecision);
                      return val;
                  },
                  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 me.fixPrecision(value);
                  }
              });
              
              ...
              ...
              items: [new myNumberField({
                      id  : 'net',
                      fieldLabel: 'Net Sales',
                      allowBlank:false,
                      decimalPrecision:2
                  })
              

              参考: How to keep the trailing zeros in Ext.form.field.Number ?

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-02-27
                • 2023-03-03
                • 1970-01-01
                相关资源
                最近更新 更多