如何强制 ExtJS NumberField 中的小数显示达到一定的精度?

Posted

技术标签:

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

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

这是我的声明:

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

【问题讨论】:

【参考方案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 ?

【讨论】:

以上是关于如何强制 ExtJS NumberField 中的小数显示达到一定的精度?的主要内容,如果未能解决你的问题,请参考以下文章

禁用 ExtJS 数字字段中的特殊字符

在 ExtJS4 网格面板中获取对分页文本字段的引用

Extjs 获取输入框焦点,并选中值

Ext.tip (Extjs 3.4) 中的强制高度和滚动条

ExtJS 动态设置Grid列是否可编辑

带有 LabelAlign 顶部(中心)的 ExtJS 文本字段