如何强制在ExtJS NumberField中显示小数点,以特定的精度为准?

15

我有一个表单,其中包含一个用于从JSON获取float类型值的NumberField。如果这些值恰好是整数,则不显示小数位。我希望始终显示2个小数位。是否有此配置选项?

以下是我的声明:

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

15

由于这是关于在NumberField中强制小数的搜索结果中排名最高的文章,所以我想为那些使用ExtJS 4+的人更新一下。

自从ExtJS 4以来,输入过滤已经委托给了一个valueToRaw函数,所使用的setValue函数实际上是来自于Ext.form.field.Text,因此下面我要覆盖它。

我还决定让显示小数点后几位成为可选项(“forcePrecision”),可以在每个NumberField中进行配置,这意味着覆盖代码看起来像这样:

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 实例化的字段与默认行为完全相同。


11

流行的解决方案对我没用。实际上,这个解决方案中的代码与 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,在最后转换为字符串时使其正常工作。

祝好运!


9

扩展(extend):

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函数。是否有一种方法来触发它? - Mike Sickler
非常顺利,Joshua。谢谢! - Mike Sickler

2

最好的方法可能是为其添加一个失焦事件监听器,然后在字段的值上使用内置的Javascript .toFixed(2)函数。


1

选项decimalPrecision的定义是: “小数分隔符后要显示的最大精度(默认为2)”

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


0
如果你想要以下的输出:
输入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);
}

0

这段代码对我来说非常有效。在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
    })

参考: 如何在 Ext.form.field.Number 中保留尾随零?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接