Pozostaw 2 miejsca po przecinku w <input type = „number”>


222

Mam <input type="number">i chcę ograniczyć wprowadzanie użytkowników do liczb czysto lub liczb dziesiętnych do 2 miejsc po przecinku.

Zasadniczo proszę o podanie ceny.

Chciałem uniknąć wyrażenia regularnego. Czy jest na to sposób?

<input type="number" required name="price" min="0" value="0" step="any">

2
type = „number” nie obsługuje szerokiej przeglądarki. Lepiej jest po prostu użyć pola tekstowego z javascript, aby upewnić się, że otrzymujesz pożądane dane wejściowe.
www139

6
Tak, ale dane wejściowe i type="text"tak wracają do , więc jakie to ma znaczenie?
Ultimater,


/^\d+\.\d{2,2}$/ pracował dla mnie wymagać 0,00
ZStoneDPM

Odpowiedzi:


336

Zamiast step="any", co pozwala na dowolną liczbę miejsc po przecinku, użyj step=".01", który pozwala na maksymalnie dwa miejsca po przecinku.

Więcej szczegółów w specyfikacji: https://www.w3.org/TR/html/sec-forms.html#the-step-attribute


38
To nie jest poprawna odpowiedź. krok reguluje tylko to, co dzieje się po kliknięciu lub naciśnięciu przycisku w górę i nie ogranicza niczego.
Ini

1
@Michael_B bez względu na to, czego oczekuje specyfikacja, testowanie tego jest dość trywialne: jsfiddle.net/9hvm0b5u nadal pozwala na wprowadzenie więcej niż 2 miejsc po przecinku. Kroki określają tylko, o ile przyciski +/- przesuwają kwotę. (Chrome)
Nathan

3
@Michael_B użytkownik nie jest w stanie wpisać liczby, takiej jak 500.12345w żadnym z danych wejściowych, być może nasze rozumienie wymagań jest inne.
Nathan

3
Należy zauważyć, że chociaż użytkownik może wpisać dowolną liczbę cyfr po przecinku, większość przeglądarek nie zezwala na przesłanie formularza z nieprawidłową wartością i selektorów CSS :validi :invalidsą stosowane zgodnie z oczekiwaniami.
Andrew Dinmore,

1
@Nathan, testowanie sprawdzania poprawności przeglądarki jest również banalne. Spróbuj podać wartość z więcej niż 2 miejscami po przecinku: jsfiddle.net/4yesgn7b
imclean

43

Jeśli przypadek, ktoś szuka wyrażenia regularnego, który dopuszcza tylko liczby z opcjonalnymi 2 miejscami dziesiętnymi

^\d*(\.\d{0,2})?$

Na przykład poniżej znalazłem rozwiązanie dość niezawodne

HTML:

<input name="my_field" pattern="^\d*(\.\d{0,2})?$" />

JS / JQuery:

$(document).on('keydown', 'input[pattern]', function(e){
  var input = $(this);
  var oldVal = input.val();
  var regex = new RegExp(input.attr('pattern'), 'g');

  setTimeout(function(){
    var newVal = input.val();
    if(!regex.test(newVal)){
      input.val(oldVal); 
    }
  }, 0);
});

2
Jaki jest cel setTimeout ()?
Derek

2
@Derek. Zakładam, że jest tak, że regex.test nie blokuje DOM. Wyszukaj to: developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
christo8989

2
@Derek Mogę tylko założyć, że setTimeout()trzeba poczekać na zakończenie keydownwydarzenia przed ustawieniem newVal(w przeciwnym razie będzie tak samo jak oldVal). Jednak po przekroczeniu limitu czasu 0 jest to bezcelowe i nie działa, ponieważ obie wartości są często takie same (w przeglądarce Firefox). Jeśli na przykład zostanie ustawiona wartość 1, będzie działać poprawnie.
alstr

Tak więc cofnąłem moją edycję w dwóch różnych postach z tego powodu, że „niezatwierdzona edycja obniża jakość formatowania odpowiedzi”. Czy możesz wyjaśnić, dlaczego moja edycja jest niezatwierdzona i jak dokładnie obniża jakość odpowiedzi? (IMO poprawia to, ponieważ ludzie mogą uruchamiać kod bezpośrednio z postu i nie muszą przechodzić do JSFiddle).
podwójny sygnał dźwiękowy

21

W przypadku waluty sugerowałbym:

<div><label>Amount $
    <input type="number" placeholder="0.00" required name="price" min="0" value="0" step="0.01" title="Currency" pattern="^\d+(?:\.\d{1,2})?$" onblur="
this.parentNode.parentNode.style.backgroundColor=/^\d+(?:\.\d{1,2})?$/.test(this.value)?'inherit':'red'
"></label></div>

Zobacz http://jsfiddle.net/vx3axsk5/1/

Właściwości „krok”, „min” i „wzorzec” HTML5 będą sprawdzane podczas przesyłania formularza, a nie w trybie onblur. Nie potrzebujesz, stepjeśli masz, patterni nie potrzebujesz, patternjeśli masz step. Możesz więc wrócić do step="any"mojego kodu, ponieważ wzorzec i tak go zweryfikuje.

Jeśli chcesz zweryfikować onblur, uważam, że wskazanie wizualne jest również pomocne, np. Zabarwienie tła na czerwono. Jeśli przeglądarka użytkownika nie obsługuje type="number", nastąpi powrót do type="text". Jeśli przeglądarka użytkownika nie obsługuje sprawdzania poprawności wzorca HTML5, mój fragment kodu JavaScript nie uniemożliwia przesłania formularza, ale daje wizualną wskazówkę. Tak więc dla osób ze słabą obsługą HTML5 i osób próbujących włamać się do bazy danych z wyłączoną obsługą JavaScript lub fałszowaniem żądań HTTP, i tak musisz ponownie sprawdzić poprawność na serwerze. Punktem sprawdzania poprawności w interfejsie jest lepsze wrażenia użytkownika. Tak długo, jak większość użytkowników ma dobre wrażenia, dobrze jest polegać na funkcjach HTML5, pod warunkiem, że kod będzie nadal działał i można zweryfikować na zapleczu.


2
Według MDN , patternnie działa dla input type=number:<input type="number"> elements do not support use of the pattern attribute for making entered values conform to a specific regex pattern. The rationale for this is that number inputs can't contain anything except numbers, and you can constrain the minimum and maximum number of valid digits using the min and max attributes, as explained above.
izogfif

@izogfif Dobra notatka. Zauważ też, że faktycznie zauważyłem, że nie potrzebujesz obu i podałem trzy sposoby: Krok, wzór i onblur. Moje uzasadnienie w tym czasie było takie, że przeglądarka dusi się z jednego powodu z innego powodu. Prawdopodobnie w tych dniach można polegać na krokach w celu sprawdzenia poprawności interfejsu użytkownika.
Ultimater

16

Krok 1: Podłącz swoje pole wprowadzania numeru HTML do zdarzenia onchange

myHTMLNumberInput.onchange = setTwoNumberDecimal;

lub w kodzie HTML

<input type="number" onchange="setTwoNumberDecimal" min="0" max="10" step="0.25" value="0.00" />

Krok 2: Napisz setTwoDecimalPlacemetodę

function setTwoNumberDecimal(event) {
    this.value = parseFloat(this.value).toFixed(2);
}

Możesz zmienić liczbę miejsc po przecinku, zmieniając wartość przekazywaną do toFixed()metody. Zobacz dokumenty MDN .

toFixed(2); // 2 decimal places
toFixed(4); // 4 decimal places
toFixed(0); // integer

3
parseFloat (parseFloat (this.value) .toFixed (2)); Jeśli chcesz użyć liczb dziesiętnych lub liczbowych, możesz owinąć całość w parseFloat (), ponieważ domyślnie metoda toFixed () zwraca ciąg znaków.
spacedev

6

Odkryłem, że użycie jQuery było moim najlepszym rozwiązaniem.

$( "#my_number_field" ).blur(function() {
    this.value = parseFloat(this.value).toFixed(2);
});

6

Spróbuj tego, ponieważ zezwala się na wprowadzanie tylko 2 miejsc po przecinku

<input type="number" step="0.01" class="form-control"  />

Lub użyj jQuery zgodnie z sugestią @SamohtVII

$( "#ELEMENTID" ).blur(function() {
    this.value = parseFloat(this.value).toFixed(2);
});

21
Nie ogranicza to miejsc po przecinku do 2 miejsc w Chrome 57
mintedsky 25.04.17

1
To nie jest poprawne. krok reguluje tylko to, co dzieje się po kliknięciu lub naciśnięciu przycisku w górę i nie ogranicza niczego.
Ini

krok zapobiega także wprowadzeniu liczby takiej jak 1.000.
Zapnologica

-2

Użyj tego kodu

<input type="number" step="0.01" name="amount" placeholder="0.00">

Domyślnie wartość kroku dla elementów wejściowych HTML5 to step = „1”.


-4

tylko napisz

<input type="number" step="0.1" lang="nb">

lang = 'nb "pozwala ci pisać liczby dziesiętne przecinkiem lub kropką


„lang = 'nb' pozwala pisać liczby dziesiętne przecinkiem lub kropką” Nie mogę mówić o niczym innym, ale dla mnie to nie działa w Chrome.
Andrew Dinmore,

-9

Na wejściu:

step="any"
class="two-decimals"

Na skrypcie:

$(".two-decimals").change(function(){
  this.value = parseFloat(this.value).toFixed(2);
});

5
Unikaj używania postów w swoim poście. I pamiętaj, aby być miłym
James
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.