¿Cómo fuerzo la pantalla de un decimal en una ExtJS NumberField a una cierta precisión?

StackOverflow https://stackoverflow.com/questions/1287584

  •  18-09-2019
  •  | 
  •  

Pregunta

Tengo un formulario con un NumberField que obtiene valores de tipo float de JSON. Si los valores resultan ser números enteros, a continuación, se muestran sin decimales. Me gustaría mostrar 2 decimales en todo momento. ¿Hay una opción de configuración para esto?

Aquí está mi declaración:

items: [
    { 
        fieldLabel: 'Net Sales',
        name: 'netSales',
        allowBlank:false,
        decimalPrecision:2
    },
¿Fue útil?

Solución

extender :

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
    }),

o anulación , y que afectará a todos los NumberFields en su aplicación:

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
    },

editar

Note la sección comentado en el primer método setValue.

Otros consejos

Como este fue el primer resultado de una consulta de búsqueda de obligar a los decimales en un NumberField, pensé que iba a actualizar esto para aquellos que utilizan ExtJS 4 +

El filtrado de entrada desde ExtJS 4 ha sido delegada a una función valueToRaw, la función setValue utilizado es en realidad de Ext.form.field.Text, así que eso es lo que estoy reemplazando a continuación.

También decidió que el forzamiento de mostrar decimales a ser una opción ( 'forcePrecision') configurable por NumberField, lo que significa la anulación se vería así:

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;
    }
});

Para utilizar esto en su forma, que te una instancia de esta manera:

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

Los campos que no se crea una instancia de forcePrecision:. True se comportan exactamente igual que el valor por defecto

La solución popular no funcionó para mí. De hecho, el código de la solución es un duplicado exacto del código 3.3 fuente EXT JS, que, para mí, se visualiza "1" en lugar de "1,00" cuando decimalPrecision es 2. Sobre la base de la sugerencia de la solución popular para anular setValue, esto es lo hice:

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);
    }
});

A pesar de que el código fixPrecision parece dar formato al número con la precisión deseada, javascript perdería la precisión durante la manipulación se hace en las dos líneas antes de la llamada a la función setValue de la superclase. Ajuste de la precisión con la toFixed cuando finalmente se convierte en una secuencia hacer que funcione.

Buena suerte!

La mejor opción es probablemente añadir un oyente al evento desenfoque por ella, y luego utilizar el construido en función de Javascript .toFixed (2) sobre el valor del campo.

La definición decimalPrecision opción es: "La precisión máxima a indicar después del separador decimal (por defecto 2)"

No hay ninguna opción para forzar el formato, usted tiene que anular problably clase NumberField.

si quieres algo, como a continuación:

Introduce 50> u consiguió 50

50.10> 50.10

50.123> 50,12

Prueba esto:

, 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);
}

Este código funciona muy bien para mí. No lo puedo trabajar sin la anulación "ValueToRow" en ExtJS 4.2.0.

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
    })

Referencia: Cómo mantener los ceros a la derecha en Ext.form. field.Number?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top