Entrada de números HTML5: mostrar siempre 2 decimales

103

¿Hay alguna forma de formatear un input[type='number']valor para que siempre muestre 2 lugares decimales?

Ejemplo: quiero ver en 0.00lugar de 0.

Guilherme Ferreira
fuente

Respuestas:

62

Resuelto siguiendo las sugerencias y agregando una pieza de jQuery para forzar el formato en enteros:

parseFloat($(this).val()).toFixed(2)
Guilherme Ferreira
fuente
step = '0.01' no me funciona en Chrome 66.0 parseFloat funciona como un encanto. robot_speed = parseFloat(robot_speed).toFixed(2)
05032 Mendicant Bias
¡Excelente! Puede agregar este código al changemétodo para activarlo cada vez que cambie el campo: stackoverflow.com/a/58502237/2056125
mhellmeier
60

Realmente no puedes, pero tu paso a mitad de camino podría ser:

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

Rich Bradshaw
fuente
16
Esto no funciona en Chrome 55.0.2883.75. Si creo un elemento de formulario, coloco el marcado de arriba en el interior, escriba '1200' en la entrada y presione la pestaña fuera del elemento, el texto que se muestra sigue siendo '1200' y no '1200.00'.
Rick Glos
8
todo lo que parece hacer es controlar lo que hacen las flechas de paso. establecer un valor de 1/3 no limitará el resultado a 2 decimales
Sonic Soul
No funciona para Chrome versión 78.0.3904.108 (compilación oficial) (64 bits)
Fasco
13

El uso del stepatributo lo habilitará . No solo determina cuánto se supone que debe ciclar, sino también los números permitidos. El uso step="0.01" debería funcionar , pero esto puede depender de cómo el navegador se adhiera al estándar.

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

Rabia disidente
fuente
7
no funciona para mí. Si hago clic hasta 5.01 y luego abajo dice 5 no 5.00 en Chrome 72
gman
Si está buscando una interpretación estrictamente numérica, este es el comportamiento correcto, "5.00" es una cadena.
Dissident Rage
1
irrelevante. La pregunta busca mostrar siempre 2 lugares decimales y esta respuesta no hace eso.
gman
Luego están buscando input[type="text"]con todas las campanas y silbidos nativos que vienen input[type="number"]completamente reimplificados, o cambiando este campo por otro para mostrar el valor según el estado del elemento.
Dissident Rage
8

Las soluciones que utilizo input="number" step="0.01"funcionan muy bien para mí en Chrome, sin embargo, no funcionan en algunos navegadores, específicamente Frontmotion Firefox 35 en mi caso .. que debo admitir.

Mi solución fue jQuery con el complemento jQuery Mask de Igor Escobar, de la siguiente manera:

<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">

Esto funciona bien, por supuesto, uno debe verificar el valor enviado después :) NOTA, si no tuviera que hacer esto para la compatibilidad del navegador, usaría la respuesta anterior de @Rich Bradshaw.

pajarito
fuente
2
No estoy seguro de por qué fue rechazado ... para mi sorpresa. Como dije en mi respuesta, esta es una solución alternativa solo para aquellos que (como yo) están atascados en navegadores de soporte en los que la otra respuesta no funciona. ¡Y sé que funciona porque actualmente está en producción y funcionando!
little_birdie
Javascript en este caso debería ser una alternativa, no un comportamiento predeterminado. Si la funcionalidad no existe, entonces es apropiado conectar Javascript. Puede verificar esto probando si el typeatributo de la entrada es numbero text. Si regresa texta pesar de que el HTML está escrito como, numberentonces el navegador no admite ese tipo, y vincular este comportamiento a él es una acción apropiada.
Dissident Rage
Si hubiera indicado eso en un comentario, habría modificado mi respuesta para incluir esa funcionalidad. La mayoría de las aplicaciones en estos días no funcionan en absoluto sin js ... o apenas funcionan ... por lo que se está volviendo discutible. Pero estoy de acuerdo en que poner un cheque mejoraría la respuesta. Actualmente estoy viajando. Lo modificaré cuando regrese.
little_birdie
5

Con base en esta respuesta de @Guilherme Ferreira, puede activar el parseFloatmétodo cada vez que cambia el campo. Por lo tanto, el valor siempre muestra dos lugares decimales, incluso si un usuario cambia el valor escribiendo manualmente un 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
fuente
Esto solo funciona cuando el elemento pierde el foco. si el usuario hace clic inmediatamente en el botón enviar después de completar el campo de entrada, no verá el valor corregido que podría ser engañoso.
Novato total
No estoy 100% seguro, pero creo que la change()función se activará en el corto tiempo entre la entrada del usuario y el clic del botón de envío. Por lo tanto, esto no debería ser un problema.
mhellmeier
Sí, de hecho cambia, pero el usuario no lo sabrá, por lo que podría generar confusión, ya que el usuario no verá el valor corregido antes de que se envíe instantáneamente. Aunque esto podría no ser un problema para la mayoría de los casos de uso
Total Newbie
3

Esto funciona para aplicar un máximo de 2 lugares decimales sin redondear automáticamente a 2 lugares si el usuario no ha terminado de escribir.

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
fuente
3

Si aterrizó aquí preguntándose cómo limitar a 2 lugares decimales , tengo una solución nativa de JavaScript:

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)" />

Tenga en cuenta que esto no puede AFAIK, defiéndase contra este error de Chrome con la entrada de número.

Stephen Paul
fuente
1

Sé que esta es una pregunta antigua, pero me parece que ninguna de estas respuestas parece responder a la pregunta que se hace, así que espero que esto ayude a alguien en el futuro.

Sí, siempre puede mostrar 2 lugares decimales, pero desafortunadamente no se puede hacer solo con los atributos del elemento, debe usar JavaScript.

Debo señalar que esto no es ideal para números grandes, ya que siempre forzará los ceros finales, por lo que el usuario tendrá que mover el cursor hacia atrás en lugar de eliminar caracteres para establecer un valor superior a 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
fuente
1

Este es un formateador rápido en JQuery que usa la .toFixed(2)función para dos lugares decimales.

<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: debe llamar a esto cada vez que se cambia el número de entrada para reformatearlo.

// 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 alguna razón, incluso si una entrada es de tipo 'número', jQuery val()devuelve una cadena. De ahí el parseFloat().

kblocks
fuente
0

Mi enfoque preferido, que usa dataatributos para mantener el estado del 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
fuente
0

La respuesta principal me dio la solución, pero no me gustó que la entrada del usuario se cambiara de inmediato, así que agregué un retraso que, en mi opinión, contribuye a una mejor experiencia del usuario.

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 novato
fuente
-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
fuente
Puedes probar esta pipa
RamakanthReddy Kowdampalli
-1

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

solo esto:

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

Si pones valor uno a uno ...

need: 120,01

dígito por dígito

 = 0,01
 = 0,12
 = 1,20
 = 12,00
 = 120,01 final number.
Raphael Vitor
fuente
Nada en la pregunta sobre Angular.
Dale K
-3

Eche un vistazo a esto :

 <input type="number" step="0.01" />
chris
fuente
5
Esto está bien para realizar pasos, pero no para formatear. Si desea 2 lugares decimales y alguien ingresa (o gira hasta) "0.1", permanecerá "0.1" (en lugar de lo que se desea "0.01") en todos los navegadores. El marcador de posición solo funciona para la condición vacía (tampoco es un formato)
MC9000
-3

Esta es la respuesta correcta:

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

Alex
fuente
4
Este es un enfoque mejor y más moderno que muchas de las otras respuestas, pero todavía no pone ceros a la derecha en lo que se ingresa
pcnate