Entrada de número HTML5 - sempre mostra 2 casas decimais

103

Existe alguma maneira de formatar um input[type='number']valor para mostrar sempre 2 casas decimais?

Exemplo: quero ver em 0.00vez de 0.

Guilherme Ferreira
fonte

Respostas:

62

Resolvido seguindo as sugestões e adicionando um pedaço de jQuery para forçar o formato em inteiros:

parseFloat($(this).val()).toFixed(2)
Guilherme Ferreira
fonte
step = '0.01' não funciona para mim no Chrome 66.0 parseFloat funciona perfeitamente. robot_speed = parseFloat(robot_speed).toFixed(2)
05032 Mendicant Bias
Ótimo! Você pode adicionar este código ao changemétodo para acioná-lo sempre que o campo mudar: stackoverflow.com/a/58502237/2056125
mhellmeier
60

Você não pode realmente, mas você está no meio do caminho:

<input type='number' step='0.01' value='0.00' placeholder='0.00' />

Rich Bradshaw
fonte
16
Isso não funciona no Chrome 55.0.2883.75. Se eu criar um elemento de formulário, coloque a marcação acima dentro, digite '1200' na entrada e pressione tab para longe do elemento, o texto exibido ainda é '1200' e não '1200,00'.
Rick Glos
8
tudo isso parece fazer é controlar o que as setas de etapa fazem. definir um valor de 1/3 não limitará o resultado a 2 decimais
Sonic Soul
Não funciona para o Chrome versão 78.0.3904.108 (versão oficial) (64 bits)
Fasco
13

Usar o stepatributo irá ativá-lo . Ele não apenas determina quanto deve circular, mas também os números permitidos. Usar step="0.01" deve resolver, mas isso pode depender de como o navegador adere ao padrão.

<input type='number' step='0.01' value='5.00'>

Raiva dissidente
fonte
7
não funciona para mim. Se eu clicar em até 5.01 e, em seguida, descer diz 5, não 5,00 no Chrome 72
gman
Se você está procurando por uma interpretação estritamente numérica, este é o comportamento correto, "5,00" é uma string.
Dissident Rage
1
irrelevante. A questão é procurar mostrar sempre 2 casas decimais e essa resposta não faz isso.
gman
Em seguida, eles estão procurando input[type="text"]com todos os sinos e assobios nativos que vêm input[type="number"]totalmente reimplementados para ele, ou trocando este campo por outro para exibir o valor dependendo do estado do elemento.
Dissident Rage
8

As soluções que usam input="number" step="0.01" funcionam muito bem para mim no Chrome, porém não funcionam em alguns navegadores, especificamente o Frontmotion Firefox 35 no meu caso .. que devo apoiar.

Minha solução foi jQuery com o plugin jQuery Mask de Igor Escobar, da seguinte maneira:

<script src="/your/path/to/jquery-mask.js"></script>
<script>
    $(document).ready(function () {
        $('.usd_input').mask('00000.00', { reverse: true });
    });
</script>

<input type="text" autocomplete="off" class="usd_input" name="dollar_amt">

Isso funciona bem, é claro que deve-se verificar o valor enviado posteriormente :) NOTA, se eu não tivesse que fazer isso para compatibilidade do navegador, eu usaria a resposta acima de @Rich Bradshaw.

passarinho
fonte
2
Não sei por que isso foi rejeitado .. para minha surpresa. Como eu disse na minha resposta, esta é uma solução alternativa apenas para aqueles que (como eu) estão presos a navegadores em que a outra resposta não funciona. E sei que funciona porque atualmente está em produção e funcionando!
little_birdie
Javascript, neste caso, deve ser um substituto, não um comportamento padrão. Se a funcionalidade não existir, é apropriado conectar o Javascript a ela. Você pode verificar isso testando se o typeatributo da entrada é numberou text. Se ele retornar textmesmo que o HTML esteja escrito como, numberentão o navegador não oferece suporte a esse tipo, e conectar esse comportamento a ele é uma ação apropriada.
Dissident Rage
Se você tivesse indicado isso em um comentário, eu teria alterado minha resposta para incluir essa funcionalidade. A maioria dos aplicativos hoje em dia não funciona sem o js .. ou quase não funciona .. então está se tornando discutível. Mas concordo que colocar um cheque melhoraria a resposta. No momento, estou viajando .. Vou corrigi-lo quando voltar.
little_birdie
5

Com base nessa resposta de @Guilherme Ferreira você pode acionar o parseFloatmétodo toda vez que o campo mudar. Portanto, o valor sempre mostra duas casas decimais, mesmo se um usuário alterar o valor digitando manualmente um número.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
    $(document).ready(function () {
        $(".floatNumberField").change(function() {
            $(this).val(parseFloat($(this).val()).toFixed(2));
        });
    });
</script>

<input type="number" class="floatNumberField" value="0.00" placeholder="0.00" step="0.01" />

mhellmeier
fonte
Isso só funciona quando o elemento perde o foco. se o usuário clicar imediatamente no botão enviar após preencher o campo de entrada, ele não verá o valor corrigido, o que pode ser enganoso.
Total Newbie
Não tenho 100% de certeza, mas acho que a change()função será acionada no curto espaço de tempo entre a entrada do usuário e o clique no botão enviar. Portanto, isso não deve ser um problema.
mhellmeier
Sim, de fato muda, mas o usuário não saberá disso, então isso pode causar confusão, já que o usuário não verá o valor corrigido antes de ser enviado instantaneamente. Embora isso possa não ser um problema para a maioria dos casos de uso
Total Newbie
3

Isso funciona para forçar um máximo de 2 casas decimais sem arredondar automaticamente para 2 casas se o usuário não terminar de digitar.

function naturalRound(e) {

   let dec = e.target.value.indexOf(".")
   let tooLong = e.target.value.length > dec + 3
   let invalidNum = isNaN(parseFloat(e.target.value))

   if ((dec >= 0 && tooLong) || invalidNum) {
     e.target.value = e.target.value.slice(0, -1)
   }
}
SuperCodeBrah
fonte
3

Se você parou aqui apenas se perguntando como limitar a 2 casas decimais , tenho uma solução de javascript nativo:

Javascript:

function limitDecimalPlaces(e, count) {
  if (e.target.value.indexOf('.') == -1) { return; }
  if ((e.target.value.length - e.target.value.indexOf('.')) > count) {
    e.target.value = parseFloat(e.target.value).toFixed(count);
  }
}

HTML:

<input type="number" oninput="limitDecimalPlaces(event, 2)" />

Observe que isso não pode AFAIK, defender contra esse bug do cromo com a entrada de número.

Stephen Paul
fonte
1

Eu sei que esta é uma pergunta antiga, mas me parece que nenhuma dessas respostas parece responder à pergunta que está sendo feita, então espero que isso ajude alguém no futuro.

Sim, você sempre pode mostrar 2 casas decimais, mas infelizmente isso não pode ser feito apenas com os atributos do elemento, você tem que usar JavaScript.

Devo salientar que isso não é ideal para números grandes, pois sempre forçará os zeros à direita, então o usuário terá que mover o cursor para trás em vez de excluir caracteres para definir um valor maior que 9,99

//Use keyup to capture user input & mouse up to catch when user is changing the value with the arrows
    $('.trailing-decimal-input').on('keyup mouseup', function (e) {

        // on keyup check for backspace & delete, to allow user to clear the input as required
        var key = e.keyCode || e.charCode;
        if (key == 8 || key == 46) {
            return false;
        };

        // get the current input value
        let correctValue = $(this).val().toString();

         //if there is no decimal places add trailing zeros
        if (correctValue.indexOf('.') === -1) {
            correctValue += '.00';
        }

        else {

            //if there is only one number after the decimal add a trailing zero
            if (correctValue.toString().split(".")[1].length === 1) {
                correctValue += '0'
            }

            //if there is more than 2 decimal places round backdown to 2
            if (correctValue.toString().split(".")[1].length > 2) {
                correctValue = parseFloat($(this).val()).toFixed(2).toString();
            }
        }

        //update the value of the input with our conditions
        $(this).val(correctValue);
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="my-number-input" class="form-control trailing-decimal-input" type="number" min="0.01" step="0.01" value="0.00" />

Verno
fonte
1

Este é um formatador rápido em JQuery que usa a .toFixed(2)função para duas casas decimais.

<input class="my_class_selector" type='number' value='33'/>


// if this first call is in $(document).ready() it will run
// after the page is loaded and format any of these inputs

$(".my_class_selector").each(format_2_dec);
function format_2_dec() {
    var curr_val = parseFloat($(this).val());
    $(this).val(curr_val.toFixed(2));
}

Contras: você precisa ligar para isso sempre que o número de entrada for alterado para reformatá-lo.

// listener for input being changed
$(".my_class_selector").change(function() {
    // potential code wanted after a change

    // now reformat it to two decimal places
    $(".my_class_selector").each(format_2_dec);
});

Nota: por algum motivo, mesmo se uma entrada for do tipo 'número', o jQuery val()retorna uma string. Daí o parseFloat().

kblocks
fonte
0

Minha abordagem preferida, que usa dataatributos para manter o estado do número:

<input type='number' step='0.01'/>

// react to stepping in UI
el.addEventListener('onchange', ev => ev.target.dataset.val = ev.target.value * 100)

// react to keys
el.addEventListener('onkeyup', ev => {

    // user cleared field
    if (!ev.target.value) ev.target.dataset.val = ''

    // non num input
    if (isNaN(ev.key)) {

        // deleting
        if (ev.keyCode == 8)

            ev.target.dataset.val = ev.target.dataset.val.slice(0, -1)

    // num input
    } else ev.target.dataset.val += ev.key

    ev.target.value = parseFloat(ev.target.dataset.val) / 100

})
nikk wong
fonte
0

A primeira resposta me deu a solução, mas não gostei que a entrada do usuário fosse alterada imediatamente, então adicionei um atraso, o que, em minha opinião, contribui para uma melhor experiência do usuário

var delayTimer;
function input(ele) {
    clearTimeout(delayTimer);
    delayTimer = setTimeout(function() {
       ele.value = parseFloat(ele.value).toFixed(2).toString();
    }, 800); 
}
<input type='number' oninput='input(this)'>

https://jsfiddle.net/908rLhek/1/

Total Newbie
fonte
-1
import { Component, Pipe, PipeTransform } from '@angular/core';

@Pipe({
    name: 'replace'
})

export class ReplacePipe implements PipeTransform {
    transform(value: any): any {
        value = String(value).toString();
        var afterPoint = '';
        var plus = ',00';
        if (value.length >= 4) {
            if (value.indexOf('.') > 0) {
                afterPoint = value.substring(value.indexOf('.'), value.length);
                var te = afterPoint.substring(0, 3);
                if (te.length == 2) {
                    te = te + '0';
                }
            }
            if (value.indexOf('.') > 0) {
                if (value.indexOf('-') == 0) {
                    value = parseInt(value);
                    if (value == 0) {
                        value = '-' + value + te;
                        value = value.toString();
                    }
                    else {
                        value = value + te;
                        value = value.toString();
                    }
                }
                else {
                    value = parseInt(value);
                    value = value + te;
                    value = value.toString();
                }
            }
            else {
                value = value.toString() + plus;
            }
            var lastTwo = value.substring(value.length - 2);
            var otherNumbers = value.substring(0, value.length - 3);
            if (otherNumbers != '')
                lastTwo = ',' + lastTwo;
            let newValue = otherNumbers.replace(/\B(?=(\d{3})+(?!\d))/g, ".") + lastTwo;
            parseFloat(newValue);
            return `${newValue}`;
        }
}
}
RamakanthReddy Kowdampalli
fonte
Você pode tentar este cachimbo
RamakanthReddy Kowdampalli
-1

ui-number-mask para angular, https://github.com/assisrafael/angular-input-masks

só isso:

<input ui-number-mask ng-model="valores.irrf" />

Se você colocar um valor um por um ....

need: 120,01

dígito por dígito

 = 0,01
 = 0,12
 = 1,20
 = 12,00
 = 120,01 final number.
Raphael Vitor
fonte
Nada na pergunta sobre Angular.
Dale K
-3

Dê uma olhada nisso :

 <input type="number" step="0.01" />
chris
fonte
5
Isso é adequado para revisão, mas não para formatação. Se você quiser 2 casas decimais e alguém inserir (ou girar para) "0,1", ele permanecerá "0,1" (ao invés do desejado "0,01") em todos os navegadores. O marcador de posição funciona apenas para a condição vazia (também não é um formato)
MC9000 de
-3

Essa é a resposta correta:

<input type="number" step="0.01" min="-9999999999.99" max="9999999999.99"/>

Alex
fonte
4
Esta é uma abordagem melhor e mais moderna do que muitas das outras respostas, mas ainda não coloca zeros à direita no que é inserido
ocorre