มีวิธีใดบ้างที่จะป้องกันไม่ให้ type = "number" รับค่าลบ?


302

ฉันต้องการได้รับค่าบวกเท่านั้นมีวิธีการป้องกันโดยใช้ html เท่านั้น
โปรดอย่าแนะนำวิธีตรวจสอบ

สกรีนช็อตของการควบคุมอินพุต


3
กระทู้นี้ตอบคำถามเดียวกันในระดับที่ดีขึ้นมาก: stackoverflow.com/questions/31575496/…
PiotrWolkowski

คำตอบ:


658

ใช้minคุณลักษณะเช่นนี้:

<input type="number" min="0">

6
ที่นี่เป็นแหล่งอ้างอิงที่น่าเชื่อถือมากขึ้น
ÁlvaroGonzález

222
วิธีนี้จะป้องกันไม่ให้มีการป้อนหมายเลขติดลบโดยใช้ปุ่มลูกศร / สปินเนอร์ อย่างไรก็ตามผู้ใช้ยังคงสามารถป้อนจำนวนลบด้วยตนเองและให้ค่าของฟิลด์นั้นอ่านเป็นจำนวนลบดังนั้นจึงข้ามแอตทริบิวต์ min
ecbrodie

52
@demaniak ไม่และคำตอบนี้ได้อย่างไร upvotes มากมายเมื่อครึ่งตอบคำถามเป็นปริศนา
GôTô

1
@Abraham เกิดอะไรขึ้นถ้าข้อมูลที่โหลดด้วยค่า -ve ในแบบฟอร์มมันไม่ได้ทำเครื่องหมายว่าเป็นสีแดง
Kamini

2
สิ่งนี้ไม่ทำงานผู้ใช้ยังสามารถป้อนหมายเลขติดลบด้วยตนเอง
อัลเต้สี่

129

ฉันไม่พอใจกับ@Abhrabm คำตอบเพราะ:

มันเป็นเพียงการป้องกันไม่ให้ตัวเลขติดลบจากลูกศรขึ้น / ลงในขณะที่ผู้ใช้สามารถพิมพ์หมายเลขติดลบจากคีย์บอร์ด

วิธีแก้ไขคือป้องกันด้วยรหัสคีย์ :

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

ชี้แจงโดย@Hugh Guiney :

กำลังตรวจสอบรหัสคีย์ใด:

  • 95, <106 สอดคล้องกับ Numpad 0 ถึง 9;
  • 47, <58 สอดคล้องกับ 0 ถึง 9 บนแถวหมายเลข; และ 8 คือ Backspace

ดังนั้นสคริปต์นี้จึงป้องกันไม่ให้ป้อนรหัสที่ไม่ถูกต้องในอินพุต


20
เพิ่มขึ้น แต่ฉันคิดว่ามันจะช่วยให้ชัดเจนว่ามีการตรวจสอบรหัสคีย์ใดบ้าง:> 95, <106 สอดคล้องกับ Numpad 0 ถึง 9; > 47, <58 สอดคล้องกับ 0 ถึง 9 ใน Number Row; และ 8 คือ Backspace ดังนั้นสคริปต์นี้ป้องกันคีย์ใด ๆ ยกเว้นที่ป้อน มันละเอียด แต่ฉันคิดว่ามันอาจเกินความเป็นจริงสำหรับเบราว์เซอร์ที่สนับสนุนการป้อนตัวเลขซึ่งคัดกรองคีย์ตัวอักษรแล้ว (ยกเว้นตัวอักษรเช่น "e" ซึ่งสามารถมีความหมายเป็นตัวเลขได้) อาจพอเพียงเพื่อป้องกัน 189 (ขีดกลาง) และ 109 (ลบ) min="0"แล้วรวมกับ
Hugh Guiney

1
@Manwal มัน จำกัด การคัดลอกและวางตัวเลขโดยใช้แป้นพิมพ์ และอนุญาตให้ฉันคัดลอกตัวเลขติดลบโดยใช้เมาส์
Beniton

1
@Beniton ขอขอบคุณที่ให้กรณีการใช้งานนี้ คุณช่วยบอกฉันเล็กน้อยเกี่ยวกับสิ่งที่คุณกำลังทำอยู่ได้ไหมฉันสามารถช่วยคุณได้ โปรดให้รหัสหรือซอเล็ก ๆ ที่เรียกคืนได้ คุณสามารถมีแบบฟอร์มการตรวจสอบระดับส่งสำหรับในรหัสของคุณ แม้ว่าฉันจะมีการตรวจสอบในแบ็กเอนด์เสมอถ้าฉันไม่อนุญาตให้มีจำนวนลบ
Manwal

1
เพียงคัดลอกวางลงในช่องโดยทั่วไป มันไม่ได้เป็นกรณีพิเศษหรืออะไร แทนที่จะจัดการการตรวจสอบความถูกต้องด้วยรหัสคีย์อาจเป็นการดีกว่าที่จะทำการเปลี่ยนหรือ focusOut และสร้างฟังก์ชันการตรวจสอบความถูกต้องเล็กน้อยเพื่อจับตัวเลขลบ
ulisesrmzroche

1
ควรใส่เงื่อนไขของปุ่มลูกศร (37, 38, 39, 41) || (e.keyCode>36 && e.keyCode<41)ไม่อนุญาตให้ผู้ใช้เพิ่ม / ลดจำนวนผ่านลูกศรขึ้น / ลงและไปทางขวา / ซ้ายเพื่อแก้ไขหมายเลข
vusan

86

สำหรับฉันทางออกคือ:

<input type="number" min="0" oninput="this.value = Math.abs(this.value)">

1
ทางออกที่ดีที่สุดจริงๆเมื่อคุณใช้รูปแบบและ noformvalidate กับเชิงมุมเนื่องจากรูปแบบไม่ได้รับการปรับปรุงหากไม่ได้อยู่ในช่วง กรณีของฉัน:<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

สิ่งนี้ทำงานได้ดีที่สุดเมื่อผู้ใช้รู้ว่าค่าเริ่มต้นคือ 0 ผู้ใช้ที่ชาญฉลาดคนอื่นสับสนในการกดแบ็คสเปซทำไมฟิลด์ไม่ล้าง ยกเว้นสิ่งนี้มันเป็นทางออกที่ดีที่สุด + 1
ลึก 3015

1
คุณบันทึกวันของฉันแล้ว
stackmalux

อันนี้ใช้ได้ดีที่สุดและในกรณีที่ใช้ทศนิยมด้วย ฉันใช้คำตอบอื่น ๆ ข้างต้นมันหยุดทำงานเมื่ออนุญาตให้ใช้ทศนิยม มีวิธีที่เราสามารถย้ายคำตอบนี้ขึ้นเพื่อให้คนสามารถใช้ส่วนใหญ่นี้
Subhan Ahmed

31

รหัสนี้ใช้งานได้ดีสำหรับฉัน คุณกรุณาตรวจสอบ:

<input type="number" name="test" min="0" oninput="validity.valid||(value='');">

2
วิธีนี้ใช้งานได้ แต่การล้างอินพุตทั้งหมดหลังจากที่คุณลองพิมพ์-ไม่ใช่ความคิดที่ดีจริงๆ
extempl

9
@extempl ฟังดูเหมือนเป็นการลงโทษที่ยุติธรรมต่อผู้ใช้ที่พยายามป้อนค่าลบในฟิลด์ที่สามัญสำนึกบ่งชี้ว่าไม่มีเชิงลบ
KhoPhi

3
<input type="number" name="test" min="0" oninput="validity.valid||(value=value.replace(/\D+/g, ''))">- สิ่งนี้จะลบสัญลักษณ์ที่ไม่ใช่ตัวเลขทั้งหมด
Oleh Melnyk

@Rexford ฉันเห็นด้วย แต่ฉันได้ตั้งไว้min="0"ดังนั้นจึงไม่มี nagatives หากคุณต้องการค่าลบให้ลบแอตทริบิวต์นี้
Chinmay235

1
ฉันลองสิ่งนี้ แต่ก็ป้องกันไม่ให้ตัวเลขที่มีจุดทศนิยมป้อน
klent

21

วิธีง่าย ๆ :

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


ดีและง่าย ... แต่ก็ยังสามารถวางจำนวนลบได้
Ralf

10

ฉันต้องการอนุญาตตัวเลขทศนิยมและไม่ล้างอินพุตทั้งหมดหากมีการป้อนค่าลบ วิธีนี้ใช้ได้ดีใน Chrome อย่างน้อย:

<input type="number" min="0" onkeypress="return event.charCode != 45">

จะเพิ่มหมายเลข ascii ได้อย่างไรที่นี่ สำหรับเช่น กับ 45 ฉันวนาเพิ่ม 46 ด้วย สามารถทำได้อย่างไร?
Pradeep Singh

3
@PradeepSingh "return [45, 46] .indexOf (event.charCode) == -1"
ykay พูดว่า Reinstate Monica

โปรดคิดนอกกรอบ คุณแน่ใจจริงๆหรือkeypressเป็นวิธีเดียวที่สามารถป้อนจำนวนลบเข้า ...
Roko C. Buljan

6

คำตอบ @Manwal นั้นดี แต่ฉันชอบโค้ดที่มีโค้ดน้อยกว่าเพื่อให้อ่านง่ายขึ้น นอกจากนี้ฉันชอบใช้ onclick / onkeypress ใน html แทน

โซลูชันที่แนะนำของฉันทำเช่นเดียวกัน: เพิ่ม

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

ไปยังอินพุต html และ

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

เป็นฟังก์ชั่นจาวาสคริปต์

อย่างที่บอกไปแล้วมันก็ทำเช่นเดียวกัน เป็นเพียงการตั้งค่าส่วนตัวในการแก้ปัญหา


5

เพียงสำหรับการอ้างอิง: ด้วย jQuery คุณสามารถเขียนทับค่าลบบน focusout ด้วยรหัสต่อไปนี้:

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

สิ่งนี้ไม่ได้แทนที่การตรวจสอบความถูกต้องฝั่งเซิร์ฟเวอร์!


มันจะทำงานได้ดีถ้าผู้ใช้โฟกัสออกจากช่องป้อนข้อมูลอย่างไรก็ตามหากพวกเขากด Enter ทันทีขณะที่ยังอยู่ในสนาม พวกเขายังสามารถป้อนจำนวนลบ
NemyaNation

3

นี่คือวิธีแก้ปัญหาเชิงมุม 2:

สร้างคลาส 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();
    }
  }
}

เพิ่ม OnlyNumber ให้กับประกาศใน app.module.ts และใช้เช่นนี้ทุกที่ในแอปของคุณ

<input OnlyNumber="true">

มีวิธีอนุญาตให้วางสำหรับสิ่งนี้หรือไม่ นอกจากนี้ฉันได้เปลี่ยน regex เป็น: /^-?answer=10 ด้วยซ้ำเพื่อให้ตัวเลขเป็นลบ แต่ดูเหมือนจะไม่ทำงานใช่ไหม
Dave Nottage

2
oninput="this.value=(this.value   < Number(this.min) || this.value   > Number(this.max))  ? '' : this.value;"

2
ในขณะที่ข้อมูลโค้ดนี้อาจแก้ไขคำถามรวมถึงคำอธิบายช่วยปรับปรุงคุณภาพของโพสต์ของคุณ จำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตและคนเหล่านั้นอาจไม่ทราบสาเหตุของการแนะนำรหัสของคุณ
Sudheesh Singanamalla

แม้ว่านี่อาจเป็นคำตอบที่ถูกต้อง แต่ก็ไม่มีรายละเอียดเพียงพอ โปรดอธิบายว่าทำไมจึงใช้งานได้ เมื่อใช้ Stack Overflow ให้พิจารณาว่านี่เป็นฐานความรู้ที่มีชีวิตคำตอบที่ไม่แบ่งปันความรู้นั้นมีประโยชน์น้อยกว่ามาก
Marc LaFleur

2

เพียงเพิ่มวิธีอื่นในการทำเช่นนี้(โดยใช้ Angular)หากคุณไม่ต้องการลบ HTML ด้วยรหัสเพิ่มเติม:

คุณต้องสมัครสมาชิกกับ valueChanges ของเขตข้อมูลและตั้งค่าเป็นค่าสัมบูรณ์ (ดูแลไม่ให้ส่งเหตุการณ์ใหม่เนื่องจากจะทำให้เกิด valueChange อื่นดังนั้นการโทรซ้ำและเรียกใช้ข้อผิดพลาดเกินขนาดสูงสุด)

รหัส HTML

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

TypeScript CODE (ภายในคอมโพเนนต์ของคุณ)

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'];
}

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


1

คำตอบนี้ไม่เป็นประโยชน์ เพราะมันใช้งานได้เฉพาะเมื่อคุณใช้ปุ่มขึ้น / ลง แต่ถ้าคุณพิมพ์ -11 มันจะไม่ทำงาน ดังนั้นนี่คือการแก้ไขเล็ก ๆ ที่ฉันใช้

อันนี้สำหรับจำนวนเต็ม

  $(".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();
    }
   });

อันนี้เมื่อคุณมีตัวเลขราคา

        $(".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();
    }
   });

0

วิธีการแก้ปัญหานี้ช่วยให้การทำงานของแป้นพิมพ์ทั้งหมดรวมถึงการคัดลอกวางด้วยแป้นพิมพ์ มันป้องกันการวางตัวเลขติดลบด้วยเมาส์ มันทำงานได้กับเบราว์เซอร์ทั้งหมดและการสาธิตบนcodepenใช้ bootstrap และ jQuery สิ่งนี้ควรใช้กับการตั้งค่าและคีย์บอร์ดที่ไม่ใช่ภาษาอังกฤษ หากเบราว์เซอร์ไม่สนับสนุนการจับการวางเหตุการณ์ (IE) มันจะลบเครื่องหมายลบหลังจากโฟกัสออก วิธีการแก้ปัญหานี้ทำงานเป็นเบราว์เซอร์ดั้งเดิมควรมี min = 0 type = number

มาร์กอัป:

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

จาวาสคริ

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

0

นี่เป็นวิธีการแก้ปัญหาที่ทำงานได้ดีที่สุดของฉันสำหรับเขตข้อมูลจำนวนที่อนุญาตเฉพาะตัวเลข

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.