Entrée numérique HTML5 - Toujours afficher 2 décimales

103

Existe-t-il un moyen de formater une input[type='number']valeur pour toujours afficher 2 décimales?

Exemple: je veux voir 0.00au lieu de 0.

Guilherme Ferreira
la source

Réponses:

62

Résolu en suivant les suggestions et en ajoutant un morceau de jQuery pour forcer le format sur les entiers:

parseFloat($(this).val()).toFixed(2)
Guilherme Ferreira
la source
step = '0.01' ne fonctionne pas pour moi sur Chrome 66.0 parseFloat fonctionne comme un charme. robot_speed = parseFloat(robot_speed).toFixed(2)
05032 Mendicant Bias
Génial! Vous pouvez ajouter ce code dans la changeméthode pour le déclencher à chaque fois que le champ change: stackoverflow.com/a/58502237/2056125
mhellmeier
60

Vous ne pouvez pas vraiment, mais vous pourriez être à mi-chemin:

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

Rich Bradshaw
la source
16
Cela ne fonctionne pas dans Chrome 55.0.2883.75. Si je crée un élément de formulaire, placez le balisage ci-dessus à l'intérieur, tapez «1200» dans l'entrée et appuyez sur l'onglet à l'écart de l'élément, le texte affiché est toujours «1200» et non «1200,00».
Rick Glos
8
tout cela semble faire est de contrôler ce que font les flèches de pas. définir une valeur de 1/3 ne limitera pas le résultat à 2 décimales
Sonic Soul
Cela ne fonctionne pas pour Chrome Version 78.0.3904.108 (version officielle) (64 bits)
Fasco
13

L'utilisation de l' stepattribut l'activera . Il détermine non seulement combien il est censé faire du cycle, mais aussi les nombres autorisés. L'utilisation step="0.01" devrait faire l'affaire, mais cela peut dépendre de la façon dont le navigateur adhère à la norme.

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

Rage dissidente
la source
7
ne fonctionne pas pour moi. Si je clique jusqu'à 5,01 puis vers le bas, il indique 5 et non 5,00 dans Chrome 72
gman
Si vous recherchez une interprétation strictement numérique, c'est le comportement correct, "5.00" est une chaîne.
Dissident Rage
1
hors du sujet. La question cherche à toujours afficher 2 décimales et cette réponse ne le fait pas.
gman le
Ensuite, ils recherchent input[type="text"]toutes les cloches et sifflets natifs qui sont input[type="number"]complètement réimplémentés, ou remplacent ce champ par un autre pour afficher la valeur en fonction de l'état de l'élément.
Dissident Rage
8

Les solutions qui utilisent input="number" step="0.01"fonctionnent très bien pour moi dans Chrome, mais ne fonctionnent pas dans certains navigateurs, en particulier Frontmotion Firefox 35 dans mon cas .. que je dois prendre en charge.

Ma solution était de jQuery avec le plugin jQuery Mask d'Igor Escobar, comme suit:

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

Cela fonctionne bien, bien sûr, il faut vérifier la valeur soumise par la suite :) REMARQUE, si je n'avais pas à le faire pour la compatibilité du navigateur, j'utiliserais la réponse ci-dessus de @Rich Bradshaw.

little_birdie
la source
2
Je ne sais pas pourquoi cela a été déclassé ... à ma grande surprise. Comme je l'ai dit dans ma réponse, il s'agit d'une solution alternative uniquement pour ceux qui (comme moi) sont bloqués en prenant en charge les navigateurs dans lesquels l'autre réponse ne fonctionne pas. Et je sais que cela fonctionne car il est actuellement en production et fonctionne!
little_birdie
Javascript dans ce cas devrait être un comportement de secours, pas un comportement par défaut. Si la fonctionnalité n'existe pas, il est approprié d'y accrocher Javascript. Vous pouvez vérifier cela en testant si l' typeattribut de l'entrée est numberou text. S'il retourne textmême si le code HTML est écrit comme cela, numberle navigateur ne prend pas en charge ce type, et y accrocher ce comportement est une action appropriée.
Dissident Rage
Si vous aviez indiqué cela dans un commentaire, j'aurais modifié ma réponse pour inclure cette fonctionnalité. La plupart des applications ces jours-ci ne fonctionnent pas du tout sans js .. ou fonctionnent à peine .. donc cela devient sans objet. Mais je suis d'accord que faire un chèque améliorerait la réponse. Je voyage actuellement .. Je le modifierai à mon retour.
little_birdie
5

Sur la base de cette réponse de @Guilherme Ferreira, vous pouvez déclencher la parseFloatméthode à chaque fois que le champ change. Par conséquent, la valeur affiche toujours deux décimales, même si un utilisateur modifie la valeur en tapant manuellement un nombre.

<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
la source
Cela ne fonctionne que lorsque l'élément perd le focus. si l'utilisateur clique immédiatement sur le bouton d'envoi après avoir rempli le champ de saisie, il ne verra pas la valeur corrigée qui pourrait être trompeuse.
Total Newbie
Je ne suis pas sûr à 100% mais je pense que la change()fonction sera déclenchée dans le court laps de temps entre l'entrée de l'utilisateur et le clic du bouton d'envoi. Par conséquent, cela ne devrait pas être un problème.
mhellmeier
Oui, cela change, mais l'utilisateur ne le saura pas, ce qui pourrait prêter à confusion car l'utilisateur ne verra pas la valeur corrigée avant qu'elle ne soit soumise instantanément. Bien que cela puisse ne pas être un problème pour la plupart des cas d'utilisation
Total Newbie
3

Cela fonctionne pour appliquer un maximum de 2 décimales sans arrondir automatiquement à 2 positions si l'utilisateur n'a pas fini de taper.

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
la source
3

Si vous êtes arrivé ici en vous demandant simplement comment limiter à 2 décimales, j'ai une solution javascript native:

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

Notez que cela ne peut pas AFAIK, se défendre contre ce bug de chrome avec l'entrée de nombre.

Stephen Paul
la source
1

Je sais que c'est une vieille question, mais il me semble qu'aucune de ces réponses ne semble répondre à la question posée, alors j'espère que cela aidera quelqu'un à l'avenir.

Oui, vous pouvez toujours afficher 2 décimales, mais malheureusement, cela ne peut pas être fait uniquement avec les attributs d'élément, vous devez utiliser JavaScript.

Je dois souligner que ce n'est pas idéal pour les grands nombres car cela forcera toujours les zéros de fin, de sorte que l'utilisateur devra déplacer le curseur en arrière au lieu de supprimer des caractères pour définir une valeur supérieure à 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
la source
1

Il s'agit d'un formateur rapide dans JQuery utilisant la .toFixed(2)fonction pour deux décimales.

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

Inconvénients: vous devez l'appeler chaque fois que le numéro d'entrée est modifié pour le reformater.

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

Remarque: pour une raison quelconque, même si une entrée est de type «nombre», jQuery val()renvoie une chaîne. D'où le parseFloat().

kblocks
la source
0

Mon approche préférée, qui utilise des dataattributs pour conserver l'état du nombre:

<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
la source
0

La meilleure réponse m'a donné la solution, mais je n'aimais pas que l'entrée utilisateur soit modifiée immédiatement, j'ai donc ajouté un délai qui, à mon avis, contribue à une meilleure expérience utilisateur.

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 débutant
la source
-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
la source
Vous pouvez essayer cette pipe
RamakanthReddy Kowdampalli
-1

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

seulement ça:

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

Si vous mettez la valeur une par une ...

need: 120,01

chiffre par chiffre

 = 0,01
 = 0,12
 = 1,20
 = 12,00
 = 120,01 final number.
Raphael Vitor
la source
Rien dans la question sur Angular.
Dale K
-3

Jetez un œil à ceci :

 <input type="number" step="0.01" />
Chris
la source
5
C'est correct pour le pas à pas, mais pas pour le formatage. Si vous voulez 2 décimales et que quelqu'un entre (ou tourne vers) «0,1», il restera «0,1» (au lieu de ce qui est souhaité «0,01») dans tous les navigateurs. L'espace réservé ne fonctionne que pour la condition vide (ce n'est pas non plus un format)
MC9000
-3

Voici la bonne réponse:

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

Alex
la source
4
C'est une approche meilleure et plus moderne que la plupart des autres réponses, mais qui ne met toujours pas de zéros à la fin de ce qui est entré
pcnate