Izinkan 2 tempat desimal di <input type = "number">

222

Saya punya <input type="number"> dan saya ingin membatasi input pengguna ke angka murni atau angka dengan desimal hingga 2 tempat desimal.

Pada dasarnya, saya meminta input harga.

Saya ingin menghindari melakukan regex. Apakah ada cara untuk melakukannya?

<input type="number" required name="price" min="0" value="0" step="any">
nubteens
sumber
2
type = "number" tidak memiliki dukungan browser yang luas. Lebih baik menggunakan kotak teks dengan beberapa javascript untuk memastikan bahwa Anda mendapatkan input yang diinginkan.
www139
6
Ya, tetapi input kembali ke type="text"anyways, jadi apa masalahnya?
Ultimater
Kemungkinan rangkap dari Apakah ada tipe input mengambang di HTML5?
OhadR
/^\d+\.\d{2,2}$/ bekerja untuk saya membutuhkan 0,00
ZStoneDPM

Jawaban:

337

Alih-alih step="any", yang memungkinkan untuk sejumlah tempat desimal, gunakan step=".01", yang memungkinkan hingga dua tempat desimal.

Lebih detail dalam spesifikasi: https://www.w3.org/TR/html/sec-forms.html#the-step-attribute

Michael Benjamin
sumber
38
Ini bukan jawaban yang benar. langkah hanya mengatur apa yang terjadi ketika Anda mengklik atau menekan dan itu tidak membatasi apa pun.
Ini
1
@Michael_B terlepas dari apa yang diharapkan oleh spec, ini cukup sepele untuk diuji: jsfiddle.net/9hvm0b5u masih memungkinkan lebih dari 2 desimal sebagai input. Langkah-langkah hanya mengatur berapa tombol +/- memindahkan jumlah. (Chrome)
Nathan
3
@Michael_B pengguna tidak dicegah mengetik nomor seperti 500.12345di salah satu input, mungkin pemahaman kita tentang persyaratan berbeda.
Nathan
3
Perlu dicatat bahwa, sementara pengguna dapat mengetik sejumlah digit setelah tempat desimal, sebagian besar browser tidak akan mengizinkan pengiriman formulir dengan nilai yang tidak valid dan pemilih CSS :validdan :invalidditerapkan seperti yang diharapkan.
Andrew Dinmore
1
@Nathan, ini juga mudah untuk menguji validasi browser. Coba kirimkan nilai dengan lebih dari 2 tempat desimal: jsfiddle.net/4yesgn7b
imclean
43

Jika ada yang mencari regex yang memungkinkan hanya angka dengan 2 desimal opsional

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

Sebagai contoh, saya menemukan solusi di bawah ini cukup dapat diandalkan

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);
});
Weston Ganger
sumber
2
Apa tujuan memiliki setTimeout ()?
Derek
2
@ Derek. Saya berasumsi begitu regex.test tidak memblokir DOM. Cari ini: developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
christo8989
2
@ Serek Saya hanya bisa berasumsi bahwa setTimeout()is untuk menunggu keydownacara selesai sebelum mengatur newVal(kalau tidak akan sama dengan oldVal). Namun, dengan batas waktu 0, tidak ada gunanya dan tidak berfungsi karena kedua nilai seringkali sama (di Firefox). Jika Anda mengaturnya ke 1, misalnya, itu berfungsi dengan baik.
alstr
Jadi, Anda memutar kembali edit saya di dua pos berbeda dengan alasan "edit yang tidak disetujui menurunkan kualitas format jawaban". Bisakah Anda jelaskan bagaimana hasil edit saya tidak disetujui dan bagaimana tepatnya hal itu menurunkan kualitas jawaban? (IMO, itu meningkatkannya, karena orang dapat menjalankan kode langsung dari pos dan mereka tidak perlu pergi ke JSFiddle).
bunyi bip ganda
21

Untuk mata uang, saya sarankan:

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

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

Properti HTML5 "langkah", "min" dan "pola" akan divalidasi ketika formulir dikirimkan, bukan di blur. Anda tidak perlu stepjika Anda memiliki patterndan Anda tidak perlu patternjika Anda punya step. Jadi Anda bisa kembali kestep="any" dengan kode saya karena pola akan memvalidasinya.

Jika Anda ingin memvalidasi onblur, saya yakin memberi pengguna isyarat visual juga membantu seperti mewarnai latar belakang merah. Jika browser pengguna tidak mendukung type="number"itu akan mundur ke type="text". Jika browser pengguna tidak mendukung validasi pola HTML5, cuplikan JavaScript saya tidak mencegah pengiriman formulir, tetapi memberikan isyarat visual. Jadi untuk orang-orang dengan dukungan HTML5 yang buruk, dan orang-orang yang mencoba meretas ke dalam basis data dengan JavaScript dinonaktifkan atau memalsukan Permintaan HTTP, Anda harus memvalidasi lagi di server. Poin dengan validasi di front-end adalah untuk pengalaman pengguna yang lebih baik. Jadi, selama sebagian besar pengguna Anda memiliki pengalaman yang baik, tidak masalah untuk mengandalkan fitur HTML5 asalkan kode tersebut masih berfungsi dan Anda dapat memvalidasi di back-end.

Ultimater
sumber
2
Menurut MDN , patterntidak berfungsi untuk 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 Catatan bagus. Perhatikan juga saya benar-benar mencatat Anda tidak perlu keduanya dan memberikan tiga cara: Langkah, pola, dan onblur. Alasan saya pada saat itu adalah jika suatu browser mencekik salah satu karena alasan yang lain. Mungkin aman untuk mengandalkan langkah hari ini untuk validasi frontend.
Ultimater
16

Langkah 1: Kaitkan kotak input nomor HTML Anda ke acara pertukaran

myHTMLNumberInput.onchange = setTwoNumberDecimal;

atau dalam kode HTML

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

Langkah 2: Tulis setTwoDecimalPlacemetodenya

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

Anda dapat mengubah jumlah tempat desimal dengan memvariasikan nilai yang diteruskan ke toFixed()metode. Lihat dokumen MDN .

toFixed(2); // 2 decimal places
toFixed(4); // 4 decimal places
toFixed(0); // integer
Sachin Sudhakar Sonawane
sumber
3
parseFloat (parseFloat (this.value) .toFixed (2)); Jika Anda ingin tipe desimal atau angka, Anda dapat membungkus semuanya dalam parseFloat () sebagai metode toFixed () default mengembalikan string.
spacedev
6

Saya menemukan menggunakan jQuery adalah solusi terbaik saya.

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

Coba ini untuk memungkinkan hanya 2 desimal dalam tipe input

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

Atau Gunakan jQuery seperti yang disarankan oleh @SamohtVII

$( "#ELEMENTID" ).blur(function() {
    this.value = parseFloat(this.value).toFixed(2);
});
Nilesh Gajare
sumber
21
Ini tidak membatasi desimal hingga 2 tempat di Chrome 57
mintedsky
1
Ini tidak benar. langkah hanya mengatur apa yang terjadi ketika Anda mengklik atau menekan dan itu tidak membatasi apa pun.
Ini
Langkah ini juga mencegah angka seperti 1.000 dimasukkan.
Zapnologica
-2

Gunakan kode ini

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

Secara default, nilai Langkah untuk elemen Input HTML5 adalah langkah = "1".

Obaidul Haque
sumber
-4

hanya menulis

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

lang = 'nb "memungkinkan Anda menulis angka desimal Anda dengan koma atau titik

ILUSTRASI RAJA
sumber
"lang = 'nb' memungkinkan Anda menulis angka desimal Anda dengan koma atau titik" Tidak dapat berbicara untuk hal lain, tetapi itu tidak berfungsi di Chrome untuk saya.
Andrew Dinmore
-9

Pada masukan:

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

Pada skrip:

$(".two-decimals").change(function(){
  this.value = parseFloat(this.value).toFixed(2);
});
xemasiv
sumber
5
Harap hindari menggunakan penghinaan di pos Anda. Dan ingatlah untuk bersikap baik
James