Bagaimana cara mendapatkan nilai mentah bidang <input type = "number">?

117

Bagaimana saya bisa mendapatkan nilai "nyata" dari suatu <input type="number">bidang?


Saya memiliki sebuah inputkotak, dan saya menggunakan jenis input HTML5 yang lebih baru number:

<input id="edQuantity" type="number">

Ini sebagian besar didukung di Chrome 29:

masukkan deskripsi gambar di sini

Yang saya perlukan sekarang adalah kemampuan untuk membaca nilai "mentah" yang telah dimasukkan pengguna di kotak masukan. Jika pengguna telah memasukkan nomor:

masukkan deskripsi gambar di sini

kemudian edQuantity.value = 4, dan semuanya baik-baik saja.

Tetapi jika pengguna memasukkan teks yang tidak valid, saya ingin mewarnai kotak input dengan warna merah:

masukkan deskripsi gambar di sini

Sayangnya, untuk type="number"kotak masukan, jika nilai di kotak teks bukan angka maka valuemengembalikan string kosong:

edQuantity.value = "" (String);

(setidaknya di Chrome 29)

Bagaimana saya bisa mendapatkan nilai "mentah" dari sebuah <input type="number">kontrol?

saya mencoba melihat-lihat daftar properti Chrome lainnya dari kotak input:

masukkan deskripsi gambar di sini

saya tidak melihat apa pun yang menyerupai masukan sebenarnya.

Saya juga tidak dapat menemukan cara untuk mengetahui apakah kotak itu "kosong" , atau tidak. Mungkin saya bisa menyimpulkan:

value          isEmpty        Conclusion
=============  =============  ================
"4"            false          valid number
""             true           empty box; not a problem
""             false          invalid text; color it red

Catatan : Anda dapat mengabaikan semuanya setelah aturan horizontal; itu hanya pengisi untuk membenarkan pertanyaan itu. Juga: jangan bingung antara contoh dengan pertanyaan. Orang mungkin ingin jawaban untuk pertanyaan ini untuk alasan lainnya selain mewarnai kotak merah (Salah satu contoh: mengubah teks "four"ke dalam latin "4"simbol selama acara onBlur)

Bagaimana saya bisa mendapatkan nilai "mentah" dari sebuah <input type="number">kontrol?

Bonus Membaca

Ian Boyd
sumber
2
Nilai 'real' dari field input numerik harus berupa angka. Jika Anda ingin mengizinkan input selain nilai numerik, maka numberbukan jenis input yang Anda cari; gunakan textinput normal .
robertc
7
@robertc Chrome adalah agen yang mengizinkan masukan selain angka; saya hanya perlu tahu bahwa mereka telah memasukkan hal-hal selain angka.
Ian Boyd
1
Periksa bidang ini validitynegara - saya harapkan typeMismatchtapi saya belum diperiksa sendiri.
robertc
2
@ int32_t Baca baris keenam ke bawah (yaitu "Tetapi jika pengguna memasukkan ..." )
Ian Boyd
6
Kasus penggunaan saya ... Saya memiliki dua bidang numerik: lintang dan bujur. Saya ingin mendeteksi jika seseorang menempelkan "lat, lon" dan menangani dengan tepat. Saat ini tidak mungkin dengan type = "number". karena "lat, lon" tidak valid .. tidak ada cara untuk mendapatkan nilai "raw" untuk menjalankan regex. Kasus penggunaan lain: menampilkan kesalahan pelanggan: " blahadalah nomor yang tidak valid".
Brad Kent

Jawaban:

55

Menurut WHATWG , Anda seharusnya tidak bisa mendapatkan nilai kecuali itu adalah input numerik yang valid. Algoritme sanitasi kolom nomor masukan mengatakan browser seharusnya menyetel nilai ke string kosong jika masukan bukan nomor floating point yang valid.

The algoritma nilai sanitasi adalah sebagai berikut: Jika nilai dari elemen bukanlah angka floating-point yang valid , kemudian set ke string kosong sebagai gantinya.

Dengan menentukan type ( <input type="number">) Anda meminta browser melakukan beberapa pekerjaan untuk Anda. Sebaliknya, jika Anda ingin dapat menangkap masukan non-numerik dan melakukan sesuatu dengannya, Anda harus bergantung pada bidang masukan teks yang sudah dicoba dan yang lama dan mengurai sendiri kontennya.

The W3 juga memiliki spesifikasi yang sama dan menambahkan:

Agen pengguna tidak boleh mengizinkan pengguna untuk menyetel nilai ke string tidak kosong yang bukan angka floating-point yang valid.

j08691
sumber
6
Akan berguna jika agen pengguna tidak mengizinkan pengguna untuk menyetel nilai ke string tidak kosong yang bukan angka floating-point yang valid. Tetapi jika whatwg mengatakan itu tidak dapat dilakukan; maka itulah jawabannya. Solusi untuk kebutuhan saya saat ini ditambahkan di bawah.
Ian Boyd
57
Dengan menentukan type ( <input type="number">) Anda meminta browser melakukan beberapa pekerjaan untuk Anda. Secara pribadi, saya hanya meminta browser seluler untuk menampilkan keypad numerik, dan mendapat validasi sebagai tambahan yang tidak menyenangkan. Sebagian besar masalah ini berasal dari fakta bahwa typeatribut menentukan baik aturan validasi maupun aturan tentang mekanisme input apa yang akan ditampilkan, tetapi sangat mungkin ingin menampilkan keyboard numerik ke pengguna seluler tanpa juga menginginkan validasi nomor diterapkan ke pengguna desktop. HTML 5.1 setidaknya akan menyelesaikan masalah ini pada akhirnya dengan inputmodeatributnya.
Mark Amery
4
tetapi ketika browser tidak berfungsi dengan baik, saya ingin dapat menyelesaikannya. seperti menghilangkan spasi di input, menyimpulkan titik desimal ...
njzk2
1
Selain itu, dalam berbagai bahasa, seperti perancis, ada 2 kata untuk angka. satu untuk angka sebagai pengenal, seperti nomor kartu kredit, dan satu untuk menghitung angka, seperti angka floating point.
njzk2
1
@MotiKorets tidak berfungsi untuk memasukkan angka floating point karena iPhone tidak meletakkan titik desimal pada keyboard. Sayangnya pengembang cukup kacau saat ini sejauh menyediakan entri floating point yang bagus UX ...
Andy
50

Itu tidak menjawab pertanyaan, tetapi solusi yang berguna adalah dengan memeriksanya

edQuantity.validity.valid

The ValidityStateobyek memberikan petunjuk tentang apa yang masuk pengguna. Pertimbangkan type="number"masukan dengan a mindan maxset

<input type="number" min="1" max="10">

Kami selalu ingin menggunakan .validity.valid.

Properti lain hanya memberikan informasi bonus:

User's Input  .value  .valid | .badInput  .rangeUnderflow  .rangeOverflow
============  ======  ====== | =========  ===============  ==============
""            ""      true   | false      false            false  ;valid because field not marked required
"1"           "1"     true   | false      false            false  
"10"          "10"    true   | false      false            false
"0"           "0"     false  | false      true             false  ;invalid because below min
"11"          "11"    false  | false      false            true   ;invalid because above max
"q"           ""      false  | true       false            false  ;invalid because not number
"³"           ""      false  | true       false            false  ;superscript digit 3
"٣"           ""      false  | true       false            false  ;arabic digit 3
"₃"           ""      false  | true       false            false  ;subscript digit 3

Anda harus memastikan bahwa browser mendukung validasi HTML5 sebelum menggunakannya:

function ValidateElementAsNumber(element)
{
   //Public Domain: no attribution required.
   if ((element.validity) && (!element.validity.valid))
   {
      //if html5 validation says it's bad: it's bad
      return false;
   }

   //Fallback to browsers that don't yet support html5 input validation
   //Or we maybe want to perform additional validations
   var value = StrToInt(element.value);
   if (value != null)
      return true;
   else
      return false;
}

Bonus

Spudly memiliki jawaban berguna yang dia hapus:

Cukup gunakan :invalidpemilih CSS untuk ini.

input[type=number]:invalid {
    background-color: #FFCCCC;
}

Ini akan memicu elemen Anda menjadi merah setiap kali valid non-numerik dimasukkan.

Dukungan browser untuk <input type='number'>hampir sama :invalid, jadi tidak ada masalah di sana.

Baca lebih lanjut tentang di :invalid sini .

Ian Boyd
sumber
Tidak berfungsi di Opera. Ia mengatakan valid bahkan jika Anda memasukkan string.
Bergi
Opera mendukung .validityproperti, tetapi tidak menangani dengan benar .valid?!
Ian Boyd
Ya, tetapi kapan input angka tidak valid ? Itu hanya bertindak seolah-olah input itu kosong. A typeMismatchmungkin masuk akal, tetapi itu hanya untuk jenis email atau url…
Bergi
@Bergi Tabel di atas memberikan contoh di mana masukan angka bisa tidak valid: "q", "11" (maka maksimal 10), "0" (bila min adalah 1), "" (maka elemennya adalah required)
Ian Boyd
1
@Bergi .badInputditambahkan 20/11/20 . Tetapi tidak ada yang harus badInputmelihat apakah masukan itu valid; mereka harus melihat .valid. Ini mungkin (dan benar) untuk .badInputmenjadi salah, dan masih memiliki masukan yang tidak valid. .validdidefinisikan sebagai tidak adanya kesalahan validasi (Misalnya ketidakcocokan, luapan, aliran kurang), yang .badInputhanya merupakan satu jenis kesalahan. Perhatikan grafik di atas .badInputyang salah, tetapi inputnya masih tidak valid.
Ian Boyd
4

Lacak semua tombol yang ditekan berdasarkan kode kuncinya

Saya kira seseorang dapat mendengarkan acara keyup dan menyimpan array dari semua karakter yang dimasukkan, berdasarkan kode kuncinya. Tapi itu tugas yang cukup membosankan dan mungkin rentan terhadap bug.

http://unixpapa.com/js/key.html

Pilih input dan dapatkan seleksi sebagai string

document.querySelector('input').addEventListener('input', onInput);

function onInput(){
  this.select(); 
  console.log( window.getSelection().toString() )
}
<input type='number'>

Semua kredit ke: int32_t

batu pasir
sumber
Solusi itu telah dicoba di tempat lain, dan tidak berhasil . Terutama ketika pengguna menekan Delete, Backspace, Ctrl+X, Ctrl+V, Right-click-cut, Right-click-paste.
Ian Boyd
Saya setuju dengan Anda, pada dasarnya apa yang diminta OP tidak mungkin. Namun, kedua peretasan yang saya sebutkan (dan mereka peretasan, saya tidak menyangkal itu) berfungsi sampai batas tertentu. Mungkin mereka bisa berguna bagi seseorang, dalam beberapa kasus?
badai pasir mulai
luar biasa, pemilihan tampaknya berhasil. Apa batasan dari metode itu?
njzk2
Batasan: teks dipilih secara visual. Jika pengguna mengetik sesuatu, konten akan hilang
fregante
Diedit dengan demo langsung yang menunjukkan seberapa buruk metode ini
vsync