有什么方法可以防止输入type =“ number”变为负值?


Answers:


658

使用如下min属性

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


222
这将阻止使用箭头按钮/微调器输入负数。但是,用户仍然可以手动输入负数,并使该字段的值读为负数,从而绕过min属性。
ecbrodie 2015年

52
@demaniak号,这样做,怎么回答得到这么多upvotes当它一半回答的问题是一个谜
GOTO

1
@Abraham如果数据以表格中的-ve值加载,则不会将其标记为红色。
卡米尼

2
这不起作用,用户仍然可以手动输入一个负数。
Altef

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对应数字键0到9;
  • 47,<58对应于数字行上的0到9;8是Backspace。

因此,该脚本可防止在输入中输入无效的键。


20
赞成,但我认为这将有助于弄清楚正在检查哪些键码:> 95,<106对应于数字键0至9;> 47,<58对应于数字行上的0到9;8是Backspace。因此,此脚本阻止输入任何密钥,但不能输入。这很彻底,但是我认为对于本机支持数字输入的浏览器来说可能会过大,后者已经过滤掉字母键(“ e”这样的字符可能具有数字含义)。防止189(破折号)和109(减号)就足够了。然后与结合min="0"
休·吉尼

1
@Manwal限制使用键盘复制和粘贴数字。并允许我使用鼠标复制粘贴负数。
Beniton

1
@Beniton感谢给出这个用例。您能给我一点关于您正在做的事情的想法吗,我总是可以帮助您的。请提供一些可运行的代码或小提琴。您可以在代码中进行表单提交级别验证。虽然我总是在后端检查如果我不允许负数。
Manwal '16

1
基本上只复制粘贴到该字段中即可。这不是真正的特殊情况,也不是什么。与其通过键码进行验证,不如通过onChange或focusOut并构建一些验证函数来捕获任何负数,可能更好。
ulisesrmzroche 2016年

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
一旦使用pattern和noformvalidate并使用angular,这将是真正的最佳解决方案,因为如果不在范围内,则不会更新模型。我的案子:<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
这可行,但是在尝试键入后清空整个输入-并不是一个好主意。
2002年

9
@extempl对于试图在常识表明没有否定字词的字段中输入否定字词的用户来说,这似乎是一种公平的惩罚。
KhoPhi

3
<input type="number" name="test" min="0" oninput="validity.valid||(value=value.replace(/\D+/g, ''))">-这将删除所有非数字的符号
奥莱梅尔尼克

@Rexford我同意,但是我已经设置min="0"好了,所以没有否定词。如果要为负值,则删除此属性。
Chinmay235 '18

1
我尝试过此操作,但它也阻止输入带小数点的数字。
肯特

21

简单方法:

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


不错,很容易...但是,仍然可以粘贴负数。
拉尔夫

10

我想允许使用十进制数字,如果输入了负数,则不清除整个输入。至少在chrome中效果良好:

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

如何在此处添加更多的ASCII码。例如 与45我想加入46也。怎么做?
Pradeep Singh '18

3
@PradeepSingh“返回[45,46] .indexOf(event.charCode)== -1”
ykay说恢复莫妮卡

请开箱即用。您真的确定a keypress是唯一可以在输入中输入负数的方法吗?
Roko C. Buljan

6

@Manwal的答案很好,但是我喜欢用更少的代码行来提高可读性。我也喜欢在HTML中使用onclick / onkeypress用法。

我建议的解决方案执行相同的操作:添加

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

作为javascript函数。

就像说的那样。解决问题只是个人喜好。


5

仅供参考:使用jQuery,您可以使用以下代码覆盖对焦点的负值:

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

有没有办法允许粘贴呢?我也将正则表达式更改为:/^-?[0-9]+(\.[0-9]*){0,1}$/g以允许使用负数,但这似乎不起作用?
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

如果您不想用更多代码弄脏HTML,只需添加另一种方式(使用Angular)即可

您只需要订阅valueChanges字段并将Value设置为绝对值(请注意不要发出新事件,因为这将导致另一个valueChange从而导致递归调用并触发“超出最大大小”错误)

HTML代码

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

TypeScript代码(在组件内部)

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上的演示使用引导程序和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>

Java脚本

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

对于仅允许数字的QTY字段,这是最适合我的解决方案。

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.