Apakah ada cara untuk mencegah input type = "number" mendapatkan nilai negatif?

302

Saya hanya ingin mendapatkan nilai positif, apakah ada cara untuk mencegahnya dengan hanya menggunakan html.
Mohon jangan menyarankan metode validasi

Cuplikan layar kontrol input

Tural Ali
sumber
3
Utas ini menjawab pertanyaan yang sama dengan tingkat yang jauh lebih baik: stackoverflow.com/questions/31575496/…
PiotrWolkowski

Jawaban:

658

Gunakan minatribut seperti ini:

<input type="number" min="0">
Abraham
sumber
6
Inilah sumber referensi yang lebih andal .
Álvaro González
222
Ini akan memblokir angka negatif agar tidak dimasukkan menggunakan tombol panah / pemintal. Namun, pengguna masih bisa memasukkan angka negatif secara manual dan meminta nilai bidang itu dibaca sebagai angka negatif, sehingga melewati atribut min.
ecbrodie
52
@demaniak No. Dan bagaimana jawaban ini mendapatkan begitu banyak upvotes ketika setengah menjawab pertanyaan itu adalah sebuah misteri
GôTô
1
@Abraham Bagaimana jika data dimuat dengan nilai -ve dalam formulir, itu tidak menandainya sebagai merah.
Kamini
2
Ini tidak berhasil, pengguna masih dapat memasukkan angka negatif secara manual.
Altef four
129

Saya tidak puas dengan jawaban @Abhrabm karena:

Itu hanya mencegah angka negatif dimasukkan dari panah atas / bawah, sedangkan pengguna dapat mengetik angka negatif dari keyboard.

Solusi adalah mencegah dengan kode kunci :

// Select your input element.
var number = document.getElementById('number');

// Listen for input event on numInput.
number.onkeydown = function(e) {
    if(!((e.keyCode > 95 && e.keyCode < 106)
      || (e.keyCode > 47 && e.keyCode < 58) 
      || e.keyCode == 8)) {
        return false;
    }
}
<form action="" method="post">
  <input type="number" id="number" min="0" />
  <input type="submit" value="Click me!"/>
</form>

Klarifikasi diberikan oleh @Hugh Guiney :

Kode kunci apa yang sedang diperiksa:

  • 95, <106 sesuai dengan Numpad 0 hingga 9;
  • 47, <58 sesuai dengan 0 hingga 9 pada Baris Nomor; dan 8 adalah Backspace.

Jadi skrip ini mencegah kunci yang tidak valid dimasukkan dalam input.

Manwal
sumber
20
Tervvatifikasi tetapi saya pikir akan membantu untuk mengklarifikasi kode kunci apa yang sedang diperiksa:> 95, <106 sesuai dengan Numpad 0 hingga 9; > 47, <58 sesuai dengan 0 hingga 9 pada Baris Nomor; dan 8 adalah Backspace. Jadi skrip ini mencegah kunci apa pun selain yang dimasukkan. Ini menyeluruh tapi saya pikir itu mungkin berlebihan untuk browser yang secara native mendukung input angka, yang sudah menyaring kunci alfabet (kecuali untuk karakter seperti "e" yang dapat memiliki arti numerik). Mungkin cukup untuk mencegah 189 (dash) dan 109 (kurangi). Dan kemudian bergabung dengan min="0".
Hugh Guiney
1
@Manwal Membatasi untuk menyalin dan menempelkan nomor menggunakan keyboard. Dan memungkinkan saya untuk menyalin nomor negatif tempel menggunakan mouse.
Beniton
1
@Beniton Terima kasih sudah memberikan use case ini. Bisakah Anda memberi saya sedikit gambaran tentang apa yang Anda lakukan. Selalu saya bisa membantu Anda. Harap berikan sedikit kode runnable atau biola. Anda dapat memiliki formulir Kirim validasi level dalam kode Anda. Meskipun saya selalu memeriksa di Backend jika saya tidak mengizinkan angka negatif.
Manwal
1
Cukup salin-tempel ke bidang pada dasarnya. Ini bukan kasus khusus atau apa pun. Daripada menangani validasi melalui kode kunci, mungkin lebih baik melakukannya di Change atau focusOut dan membangun sedikit fungsi validasi untuk menangkap angka negatif apa pun.
ulisesrmzroche
1
Kondisi untuk tombol panah (37, 38, 39, 41) juga harus diletakkan. || (e.keyCode>36 && e.keyCode<41)Ini tidak memungkinkan pengguna untuk menambah / mengurangi angka melalui panah atas / bawah dan ke kanan / kiri untuk mengedit nomor.
vusan
86

Bagi saya solusinya adalah:

<input type="number" min="0" oninput="this.value = Math.abs(this.value)">
Renato Machado
sumber
1
Benar-benar solusi terbaik setelah Anda menggunakan pola dan noformvalidate dengan sudut, karena model ini tidak diperbarui jika tidak dalam jangkauan. Kasus saya:<input ng-model="row.myValue" type="{{row.code == 1 ? 'text' : 'number'}}" min="0" ng-pattern="..." noformvalidate oninput="if (this.type=='text') this.value=Math.abs(this.value) ">
sebius
ini bekerja paling baik ketika pengguna tahu nilai default adalah 0. Pengguna bijak lain menjadi bingung pada backspace tekan mengapa bidang tidak dihapus. Kecuali ini, ini adalah solusi terbaik. + 1
Deep 3015
1
Anda menyelamatkan hari saya
stackmalux
Yang ini bekerja paling baik, dan dalam hal menggunakan desimal juga. Saya telah menggunakan jawaban lain di atas, itu berhenti berfungsi ketika desimal diizinkan. Apakah ada cara kita dapat memindahkan jawaban ini ke atas sehingga sebagian besar orang dapat menggunakan ini.
Subhan Ahmed
31

Kode ini berfungsi dengan baik untuk saya. Bisakah Anda periksa:

<input type="number" name="test" min="0" oninput="validity.valid||(value='');">
Chinmay235
sumber
2
Ini berfungsi tetapi mengosongkan seluruh input setelah Anda mencoba mengetik -bukanlah ide yang bagus.
extempl
9
@extempl Kedengarannya seperti hukuman yang adil bagi pengguna yang mencoba memasukkan negatif di bidang di mana akal sehat menunjukkan tidak ada negatif.
KhoPhi
3
<input type="number" name="test" min="0" oninput="validity.valid||(value=value.replace(/\D+/g, ''))">- ini akan menghapus semua simbol non-digit
Oleh Melnyk
@Rexford Saya setuju, Tapi saya telah menetapkan min="0"sehingga tidak ada tanda negatif. Jika Anda ingin nilai negatif maka hapus atribut ini.
Chinmay235
1
Saya mencoba ini tetapi juga mencegah angka dengan titik desimal dimasukkan.
Klent
21

Metode mudah:

<input min='0' type="number" onkeypress="return (event.charCode == 8 || event.charCode == 0) ? null : event.charCode >= 48 && event.charCode <= 57">

Rouvé
sumber
Bagus dan mudah ... tetapi tetap saja, angka negatif dapat disisipkan.
Ralf
10

Saya ingin mengizinkan angka desimal dan tidak menghapus seluruh input jika input negatif dimasukkan. Ini berfungsi dengan baik di chrome setidaknya:

<input type="number" min="0" onkeypress="return event.charCode != 45">
Ya kata Reinstate Monica
sumber
Bagaimana bisa menambahkan lebih banyak nomor ascii di sini. untuk mis. dengan 45 saya ingin menambahkan 46 juga. Bagaimana itu bisa dilakukan?
Pradeep Singh
3
@PradeepSingh "return [45, 46] .indexOf (event.charCode) == -1"
ykay mengatakan Reinstate Monica
Tolong pikirkan di luar kotak. Apakah Anda benar-benar yakin satu keypress-satunya cara seseorang dapat memasukkan angka negatif ke dalam input ...
Roko C. Buljan
6

Jawaban @Manwal baik, tetapi saya suka kode dengan lebih sedikit baris kode untuk keterbacaan yang lebih baik. Saya juga ingin menggunakan penggunaan onclick / onkeypress di html sebagai gantinya.

Solusi saya yang disarankan melakukan hal yang sama: Tambah

min="0" onkeypress="return isNumberKey(event)"

ke input html dan

function isNumberKey(evt){
    var charCode = (evt.which) ? evt.which : event.keyCode;
    return !(charCode > 31 && (charCode < 48 || charCode > 57));
}

sebagai fungsi javascript.

Seperti yang dikatakan, itu melakukan hal yang sama. Ini hanya preferensi pribadi tentang cara mengatasi masalah.

Chris H.
sumber
5

Hanya untuk referensi: dengan jQuery Anda dapat menimpa nilai negatif pada fokus dengan kode berikut:

$(document).ready(function(){
    $("body").delegate('#myInputNumber', 'focusout', function(){
        if($(this).val() < 0){
            $(this).val('0');
        }
    });
});

Ini tidak menggantikan validasi sisi server!

Hafenkranich
sumber
Ini berfungsi dengan baik JIKA pengguna fokus keluar dari bidang input, namun jika mereka segera tekan enter saat masih di lapangan; mereka masih bisa memasukkan angka negatif.
NemyaNation
3

Inilah solusi 2 sudut:

buat kelas OnlyNumber

import {Directive, ElementRef, HostListener} from '@angular/core';

@Directive({
  selector: '[OnlyNumber]'
})
export class OnlyNumber {

  // Allow decimal numbers. The \. is only allowed once to occur
  private regex: RegExp = new RegExp(/^[0-9]+(\.[0-9]*){0,1}$/g);

  // Allow key codes for special events. Reflect :
  // Backspace, tab, end, home
  private specialKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home'];

  constructor(private el: ElementRef) {
  }

  @HostListener('keydown', ['$event'])
  onKeyDown(event: KeyboardEvent) {
    // Allow Backspace, tab, end, and home keys
    if (this.specialKeys.indexOf(event.key) !== -1) {
      return;
    }

    // Do not use event.keycode this is deprecated.
    // See: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
    let current: string = this.el.nativeElement.value;
    // We need this because the current value on the DOM element
    // is not yet updated with the value from this event
    let next: string = current.concat(event.key);
    if (next && !String(next).match(this.regex)) {
      event.preventDefault();
    }
  }
}

tambahkan OnlyNumber ke deklarasi di app.module.ts dan gunakan seperti ini di mana saja di aplikasi Anda

<input OnlyNumber="true">
Sarath Nagesh
sumber
Apakah ada cara untuk mengizinkan Tempel untuk ini? Saya juga mengubah regex menjadi: /^-?[0-9[+(\.[0-9[*){0,1}$/g untuk memungkinkan angka negatif, tetapi sepertinya tidak berfungsi?
Dave Nottage
2
oninput="this.value=(this.value   < Number(this.min) || this.value   > Number(this.max))  ? '' : this.value;"
pengguna9276950
sumber
2
Sementara potongan kode ini dapat menyelesaikan pertanyaan, termasuk penjelasan sangat membantu untuk meningkatkan kualitas posting Anda. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, dan orang-orang itu mungkin tidak tahu alasan untuk saran kode Anda.
Sudheesh Singanamalla
Meskipun ini mungkin jawaban yang benar, itu tidak cukup detail. Tolong jelaskan mengapa ini bekerja. Saat menggunakan Stack Overflow, pertimbangkan bahwa ini adalah basis pengetahuan yang hidup , jawaban yang tidak berbagi pengetahuan jauh kurang berguna.
Marc LaFleur
2

Hanya menambahkan cara lain untuk melakukan ini (menggunakan Angular) jika Anda tidak ingin mengotori HTML dengan lebih banyak kode:

Anda hanya perlu berlangganan Perubahan nilai bidang dan menetapkan Nilai sebagai nilai absolut (menjaga agar tidak memancarkan event baru karena itu akan menyebabkan value changer yang lain karena itu panggilan rekursif dan memicu ukuran panggilan maksimum melebihi kesalahan)

KODE HTML

<form [formGroup]="myForm">
    <input type="number" formControlName="myInput"/>
</form>

TypeScript CODE (Di Dalam Komponen Anda)

formGroup: FormGroup;

ngOnInit() { 
    this.myInput.valueChanges 
    .subscribe(() => {
        this.myInput.setValue(Math.abs(this.myInput.value), {emitEvent: false});
    });
}

get myInput(): AbstractControl {
    return this.myForm.controls['myInput'];
}
Pedro B.
sumber
1

<input type="number" name="credit_days" pattern="[^\-]+" 
    #credit_days="ngModel" class="form-control" 
    placeholder="{{ 'Enter credit days' | translate }}" min="0" 
    [(ngModel)]="provider.credit_days"
    onkeypress="return (event.charCode == 8 || event.charCode == 0 || 
    event.charCode == 13) ? null : event.charCode >= 48 && event.charCode <= 
    57" onpaste="return false">

Hui Lin
sumber
1

Jawabannya tidak membantu. karena ini hanya berfungsi ketika Anda menggunakan tombol atas / bawah, tetapi jika Anda mengetik -11 itu tidak akan berfungsi. Jadi di sini adalah perbaikan kecil yang saya gunakan

ini untuk bilangan bulat

  $(".integer").live("keypress keyup", function (event) {
    //    console.log('int = '+$(this).val());
    $(this).val($(this).val().replace(/[^\d].+/, ""));
    if (event.which != 8 && (event.which < 48 || event.which > 57))
    {
        event.preventDefault();
    }
   });

ini ketika Anda memiliki jumlah harga

        $(".numeric, .price").live("keypress keyup", function (event) {
     //    console.log('numeric = '+$(this).val());
    $(this).val($(this).val().replace(/[^0-9\,\.]/g, ''));

    if (event.which != 8 && (event.which != 44 || $(this).val().indexOf(',') != -1) && (event.which < 48 || event.which > 57)) {
        event.preventDefault();
    }
   });
Ahmed Sunny
sumber
0

Solusi ini memungkinkan semua fungsionalitas keyboard termasuk salin tempel dengan keyboard. Ini mencegah menempelnya angka negatif dengan mouse. Ini bekerja dengan semua browser dan demo pada codepen menggunakan bootstrap dan jQuery. Ini harus bekerja dengan pengaturan dan keyboard non-bahasa Inggris. Jika browser tidak mendukung capture event paste (IE), itu akan menghapus tanda negatif setelah fokus keluar. Solusi ini berperilaku seperti seharusnya browser asli dengan min = 0 type = number.

Markup:

<form>
  <input class="form-control positive-numeric-only" id="id-blah1" min="0" name="nm1" type="number" value="0" />
  <input class="form-control positive-numeric-only" id="id-blah2" min="0" name="nm2" type="number" value="0" />
</form>

Javascript

$(document).ready(function() {
  $("input.positive-numeric-only").on("keydown", function(e) {
    var char = e.originalEvent.key.replace(/[^0-9^.^,]/, "");
    if (char.length == 0 && !(e.originalEvent.ctrlKey || e.originalEvent.metaKey)) {
      e.preventDefault();
    }
  });

  $("input.positive-numeric-only").bind("paste", function(e) {
    var numbers = e.originalEvent.clipboardData
      .getData("text")
      .replace(/[^0-9^.^,]/g, "");
    e.preventDefault();
    var the_val = parseFloat(numbers);
    if (the_val > 0) {
      $(this).val(the_val.toFixed(2));
    }
  });

  $("input.positive-numeric-only").focusout(function(e) {
    if (!isNaN(this.value) && this.value.length != 0) {
      this.value = Math.abs(parseFloat(this.value)).toFixed(2);
    } else {
      this.value = 0;
    }
  });
});
wilsotc
sumber
0

Ini adalah solusi yang paling cocok untuk saya dalam bidang QTY yang hanya memungkinkan angka.

// Only allow numbers, backspace and left/right direction on QTY input
    if(!((e.keyCode > 95 && e.keyCode < 106) // numpad numbers
        || (e.keyCode > 47 && e.keyCode < 58) // numbers
        || [8, 9, 35, 36, 37, 39].indexOf(e.keyCode) >= 0 // backspace, tab, home, end, left arrow, right arrow
        || (e.keyCode == 65 && (e.ctrlKey === true || e.metaKey === true)) // Ctrl/Cmd + A
        || (e.keyCode == 67 && (e.ctrlKey === true || e.metaKey === true)) // Ctrl/Cmd + C
        || (e.keyCode == 88 && (e.ctrlKey === true || e.metaKey === true)) // Ctrl/Cmd + X
        || (e.keyCode == 86 && (e.ctrlKey === true || e.metaKey === true)) // Ctrl/Cmd + V
    )) {
        return false;
    }
TheRealJAG
sumber
0

If Number is Negative or Positive Using ES6s Math.Sign

const num = -8;
// Old Way
num === 0 ? num : (num > 0 ? 1 : -1); // -1

// ES6 Way
Math.sign(num); // -1

Israt Jahan Simu
sumber