【问题标题】:Only allow positive numbers with only one decimal in Angular 6在Angular 6中只允许只有一位小数的正数
【发布时间】:2019-07-22 17:38:45
【问题描述】:

我是堆栈溢出的新手,所以如果我在任何地方错了,请原谅我。我在 Angular 6 中遇到了问题,我几乎没有输入数字和文本类型的字段,我想阻止用户输入除“。”之外的任何字符。 (点)并且仅输入带有单个点的正数,例如。 “1.22”而不是“1..2”。或“-1.12”或“-111”。

我尝试过 (keyup)、(keypress) 和 (keydown),但它们中的每一个都让我感到困惑。请告知是否有任何指令或任何解决方案。 在html中

 <input type="number"(keyup)="numberOnlyWithDecimal($event,xyz)" name="weight [(ngModel)]="xyz" min="0" step="0.1">

在.ts中

public textlength=0;


numberOnlyWithDecimal(event, text): boolean {

var regex = /^\d+(\.\d+)?$/;
const charCode = (event.which) ? event.which : event.keyCode;
var text2 = text + ''
var test = text2.split(".")
if (text2) {  
  this.textlength = test.length-1 ;
}
if(text == null && charCode == 46){
  return false;
}

if (charCode != 46 && charCode > 31 && (charCode < 48 || charCode > 57)) {
  return false;
}
if (!regex.test(charCode)) {
  return false
}
if (charCode === 46 && this.textlength ===1 ) {
  return false
}
return true;

}

【问题讨论】:

  • 鼠标右键单击并选择“粘贴”将绕过任何限制用户何时可以按下键的尝试。
  • 实际上粘贴不是我正在工作的项目中的问题。我只希望用户只能输入最多一个点的正值。

标签: angular typescript


【解决方案1】:

给你,为你提供完整的工作解决方案:

1) 指令


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

  private regex: RegExp = new RegExp(/^-?[0-9]+(\.[0-9]*){0,1}$/g);
  private specialKeys: Array<string> = ['Backspace', 'Tab'];

  constructor(private el: ElementRef) {
  }
  @HostListener('keydown', ['$event'])
  onKeyDown(event: KeyboardEvent) {
    if (this.specialKeys.indexOf(event.key) !== -1) {
      return;
    }
    const current: string = this.el.nativeElement.value;
    const next: string = current.concat(event.key);
    if (next && !String(next).match(this.regex)) {
      event.preventDefault();
    }
  }
}

2) html中的用法

<input type="text" name="weight" appNumbersOnly [(ngModel)]="xyz"  />

Stackblitz这里供参考

【讨论】:

  • @yanky_carnky 感谢您的解决方案。它在 stackblitz 中工作得非常好,但出于某种原因,在我的项目中,我可以输入两个连续的小数。这是 HTML 代码&lt;input type="number" appNumbersOnly name="weight" [(ngModel)]="anthropometry.body_measurements.weight.measure (ngModelChange)="onParamsChange($event)" min="0" step="0.1"&gt;
  • 你能分享你的stackblitz吗
  • 固定(y)请检查,现在您无需将地址类型作为数字改为文本
  • 是的,我现在可以看到它与 type="text" 一起工作,但是由于输入中的上下按钮,该项目需要有一个类型号。有没有办法在 type="number" 中实现这一点?
  • @ShubhamDubey 使用 css 隐藏它
【解决方案2】:

最后,经过大量的头脑风暴,我找到了一个可行的解决方案。我要感谢所有帮助我的人,你们是救世主。

我使用了@yanky_craky 代码并对其进行了一些修改,它适用于数字和文本输入类型。这是代码。

<input type="number" name="weight" appNumbersOnly [(ngModel)]="xyz"/>

指令:

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

@Directive({
    selector: '[appNumbersOnly]'
  })



export class NumbersOnlyDirective {
    public text;

    private regex: RegExp = new RegExp(/^-?[0-9]+(\.[0-9]*){0,1}$/g);
    private specialKeys: Array<string> = ['Backspace', 'Tab'];

    constructor(private el: ElementRef) {
    }
    @HostListener('keypress', ['$event'])
    onKeyDown(event: KeyboardEvent) {
      if (this.specialKeys.indexOf(event.key) !== -1) {
        return;
      }
      const current: string = this.el.nativeElement.value;
      const next: string = current.concat(event.key);

      if(next.includes('.')){
        if(this.text == next){
          event.preventDefault();
        }
        this.text= next;
      }
      if ((next && !String(next).match(this.regex))) {  
        event.preventDefault();
      }
    }
  }

【讨论】:

    【解决方案3】:

    您可以创建自定义指令

    import { Directive, ElementRef, HostListener, Input } from '@angular/core';
    @Directive({
      selector: '[appTwoDigitDecimaNumber]'
    })
    
    export class TwoDigitDecimaNumberDirective {
      private regex: RegExp = new RegExp(/^\d*\.?\d{0,2}$/g);
      private specialKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home', '-'];
    
      @Input('appTwoDigitDecimaNumber') decimal:any;
    
      constructor(private el: ElementRef) {
      }
      @HostListener('keydown', ['$event'])
    
      onKeyDown(event: KeyboardEvent) {
        // Allow Backspace, tab, end, and home keys
        if(this.decimal){  
          if (this.specialKeys.indexOf(event.key) !== -1) {
            return;
          }
          let current: string = this.el.nativeElement.value;
          let next: string = current.concat(event.key);
          if (next && !String(next).match(this.regex)) {
            event.preventDefault();
          }
        }else{
          const charCode = (event.which) ? event.which : event.keyCode;
          if (charCode > 31 && (charCode < 48 || charCode > 105)) {
            event.preventDefault();
          }
          return;
        }
      }
    

    用法

    <input type="text" [appTwoDigitDecimaNumber]="true">
    

    希望对你有很大帮助。

    注意:您可以在任何您想使用的number 类型字段中使用它,如果您不想使用,请添加[appTwoDigitDecimaNumber]="true",然后添加[appTwoDigitDecimaNumber]="false"。 因为我以动态形式使用这些指令,所以我将其设置为基于truefalse。 你也可以在Dynamic form使用它

    【讨论】:

    • 非常感谢您的帮助,但输入接受多个小数和负数,甚至我可以输入多个减号,而用户不得输入任何负值或减号以及没有多个点。
    • 你只需要在这里更改正则表达式模式
    • 抱歉,我对正则表达式模式了解不多。
    猜你喜欢
    • 2022-01-22
    • 2017-08-30
    • 1970-01-01
    • 2017-03-02
    • 2015-01-20
    • 1970-01-01
    • 1970-01-01
    • 2016-06-30
    相关资源
    最近更新 更多