Como faço para forçar a exibição de um decimal em uma ExtJS NumberField a uma certa precisão?

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

  •  18-09-2019
  •  | 
  •  

Pergunta

Eu tenho um formulário com uma NumberField que recebe valores do tipo float de JSON. Se os valores de acontecer de ser números inteiros, em seguida, são mostrados lugares sem decimais. Eu gostaria de mostrar 2 casas decimais em todos os momentos. Existe uma opção de configuração para isso?

Aqui está a minha declaração:

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

Solução

qualquer estender :

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

ou override , e que afetarão todos os numberfields em sua aplicação:

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 a seção comentada no primeiro método setValue.

Outras dicas

Como este foi o primeiro resultado de uma consulta de pesquisa sobre como forçar decimais em um NumberField, pensei que eu iria atualizar esta para aqueles que utilizam ExtJS 4 +

A entrada de filtragem desde ExtJS 4 foi delegada a uma função valueToRaw, a função setValue usado é realmente de Ext.form.field.Text, então é isso que eu estou imperiosas abaixo.

Eu também decidiu que o forçando de exibir decimais a ser uma opção ( 'forcePrecision') configurável por NumberField, o que significa a substituição será parecido com este:

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 usar isso em seu formulário, você teria instanciá-lo como este:

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

Os campos não instanciado com forcePrecision:. True se comportam exatamente como o padrão

A solução popular não funcionou para mim. Na verdade o código na solução é uma cópia exata do código 3.3 fonte EXT JS que, para mim, exibe "1" em vez de "1,00" quando decimalPrecision é 2. Com base na sugestão do solução popular para substituir setValue, isso é o que eu fiz:

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

Mesmo que o código fixPrecision parece formatar o número com a precisão desejada, javascript iria perder a precisão durante a manipulação faz nas duas linhas antes da chamada para a função setValue da superclasse. Definir a precisão com toFixed quando é finalmente convertido em um String fez funcionar.

Boa sorte!

A melhor aposta é provavelmente a adicionar um ouvinte para o evento borrão para ele, e, em seguida, usar o construída em Javascript .toFixed (2) função do valor do campo.

A definição opção decimalPrecision é: "A precisão máxima para exibição após o separador decimal (o padrão é 2)"

Não há nenhuma opção para forçar o formato, você problably tem que substituir classe NumberField.

Se você quer algo como abaixo:

digite 50> u tem 50

50.10> 50.10

50,123> 50.12

Tente isto:

, 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 muito bem para mim. Isso não vai funcionar com o override "ValueToRow" em 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
    })

Referência: Como manter os zeros à direita em Ext.form. field.Number?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top