2009-08-17 23 views
14

Tengo un formulario con un NumberField que obtiene valores del tipo float de JSON. Si los valores son números enteros, no se muestran los decimales. Me gustaría mostrar 2 decimales en todo momento. ¿Hay una opción de configuración para esto?¿Cómo fuerzo la visualización de un decimal en un campo numérico ExtJS con una cierta precisión?

aquí está mi declaración:

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

Respuesta

8

ya sea extienden:

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

Observe la sección comentada en el primer método setValue.

+0

he intentado su anulación, y funciona muy bien en un evento de cambio. Sin embargo, cuando el formulario carga datos desde una JsonStore, no se llama a fixPrecision. ¿Hay alguna manera de activarlo? –

+0

¿Hace que un JsonReader, no un JsonStore ... –

+0

marque como "respondido"? :) – Joshua

0

La definición opción decimalPrecision 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 , probablemente tenga que anular la clase NumberField.

1

La mejor opción es, probablemente, agregar un oyente para el evento de desenfoque, y luego usar la función incorporada en JavaScript .toFixed (2) en el valor del campo.

11

La solución popular no funcionó para mí. De hecho, el código en la solución es un duplicado exacto del código fuente de EXT JS 3.3 que, para mí, muestra "1" en lugar de "1.00" cuando decimalPrecision es 2. Basado en la sugerencia de la popular solución 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. Establecer la precisión con toFixed cuando finalmente se convierte en una cadena lo hizo funcionar.

¡Buena suerte!

14

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 delegadas a una función valueToRaw, la función setValue utilizada es en realidad de Ext.form.field.Text, así que eso es lo que estoy redefiniendo a continuación.

también decidí tener el forzamiento de mostrar decimales a ser una opción ('forcePrecision') configurable por NumberField, lo que significa la anulación se verá 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 le crea una instancia de esta manera:

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

campos no instanciados con forcePrecision: verdadera se comportan exactamente igual que el valor predeterminado.

0

si quieres algo, como a continuación:

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

Este el código funciona bien para mí No funcionará 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: How to keep the trailing zeros in Ext.form.field.Number ?

Cuestiones relacionadas