限制文本输入值的正确方法(例如,仅限数字)

时间:2016-05-25 11:18:47

标签: angular

是否可以实施input,只允许在内部输入数字,而无需手动处理event.target.value

在React中,可以定义value属性,然后输入更改将基本绑定到该值(如果没有value更改,则无法修改它)。见example。它没有任何努力就可以正常工作。

在Angular 2中,可以定义[value],但它最初只会设置值,之后input不会阻止修改。

我正在玩ngModel[value] / (input),请参阅example

但在两种实施方式中都存在一个基本问题:

  1. 键入10时(模型值为10;输入值为10) - 正确
  2. 当你输入10d之后(模型值为10 - 未修改,所有非数字都被删除;输入值为10d) - 不正确,因为模型值与之前相同
  3. 键入10d3时 - (模型值为103;输入值为103) - 正确
  4. 如何在不手动处理event.target.value的情况下完成这个简单(从第一眼看)组件?...

    更新我不是在寻找原生HTML5 input[number]元素。这里输入的数字仅用于示例 - 当我需要限制输入文本时,可能会有更多任务。

    此外,input[number]是1)不限制我输入10ddd和2)(不太重要)包含我不需要的箭头。

    这里的问题是阻止用户输入超出限制值的内容,而不是允许输入任何并验证之后

16 个答案:

答案 0 :(得分:35)

在component.ts中添加此功能

_keyUp(event: any) {
    const pattern = /[0-9\+\-\ ]/;
    let inputChar = String.fromCharCode(event.charCode);

    if (!pattern.test(inputChar)) {
      // invalid character, prevent input
      event.preventDefault();
    }
}

在模板中使用以下

<input(keyup)="_keyUp($event)">

这将在angular2捕获事件之前捕获输入。

答案 1 :(得分:16)

输入掩码插件可以最好地完成此操作。它非常灵活,你可以提供你喜欢的任何正则表达式来限制输入。它也不需要JQuery。

第1步:安装插件:

npm install --save inputmask

Step2:创建一个包含输入掩码的指令:

import {Directive, ElementRef, Input} from '@angular/core';
import * as Inputmask from 'inputmask';


@Directive({
  selector: '[app-restrict-input]',
})
export class RestrictInputDirective {

  // map of some of the regex strings I'm using (TODO: add your own)
  private regexMap = {
    integer: '^[0-9]*$',
    float: '^[+-]?([0-9]*[.])?[0-9]+$',
    words: '([A-z]*\\s)*',
    point25: '^\-?[0-9]*(?:\\.25|\\.50|\\.75|)$'
  };

  constructor(private el: ElementRef) {}

  @Input('app-restrict-input')
  public set defineInputType(type: string) {
    Inputmask({regex: this.regexMap[type], placeholder: ''})
      .mask(this.el.nativeElement);
  }

}

第3步:

<input type="text" app-restrict-input="integer">

查看他们的github docs了解详情。

答案 2 :(得分:16)

经过大量的研究,我最终创建了一个满足要求的功能。 我创建的函数限制所有特殊字符,只允许字母和数字..并且该函数适用于复制粘贴和键入两者。 希望它有效:)

import scrapy
from scrapy.item import Field, Item
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from uomscrapbot.items import UomscrapbotItem

class uomsitelinks(scrapy.Spider):
name = "uom"
allowed_domains = ["uom.ac"]
start_urls = [
"http://www.uom.ac.mu/"]

def parse(self, response):
   # print response.xpath('//body//li/a/@href').extract()
    item = UomscrapbotItem()
    item['url'] = response.xpath('//body//li/a/@href').extract()
    return item

你如何使用 -
1)在ts文件的类组件中添加上述方法 2)在输入事件上调用方法inputValidator($ event)..

答案 3 :(得分:7)

经过测试的答案由我:

<强> form.html

<input type="text" (keypress)="restrictNumeric($event)">

<强> form.component.ts:

public restrictNumeric(e) {
  let input;
  if (e.metaKey || e.ctrlKey) {
    return true;
  }
  if (e.which === 32) {
   return false;
  }
  if (e.which === 0) {
   return true;
  }
  if (e.which < 33) {
    return true;
  }
  input = String.fromCharCode(e.which);
  return !!/[\d\s]/.test(input);
 }

答案 4 :(得分:6)

您可以使用类型编号为

的HTML5输入

它的声明中不接受任何字符

<input type="number" [(model)]='myvar' min=0 max=100 step=5 />

以下是角度为2 [(model)]

的用法示例

http://www.webpackbin.com/VJNUNF0M-

答案 5 :(得分:3)

一些答案​​对我没有用,所以我从一些答案中得到了最好的一点(谢谢你们)并创建了一个Angular 5指令,它可以为你完成工作(以及更多)。它可能并不完美,但它提供了灵活性。

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

@Directive({
selector: '[appInputMask]'
})
export class InputMaskDirective {
@Input('appInputMask') inputType: string;

showMsg = false;
pattern: RegExp;

private regexMap = { // add your own
integer: /^[0-9 ]*$/g,
float: /^[+-]?([0-9]*[.])?[0-9]+$/g,
words: /([A-z]*\\s)*/g,
point25: /^\-?[0-9]*(?:\\.25|\\.50|\\.75|)$/g,
badBoys: /^[^{}*+£$%\\^-_]+$/g
};

constructor(public el: ElementRef, public renderer: Renderer2) { };

@HostListener('keypress', ['$event']) onInput(e) {
this.pattern = this.regexMap[this.inputType]
const inputChar = e.key;
this.pattern.lastIndex = 0; // dont know why but had to add this

if (this.pattern.test(inputChar)) {
   // success
  this.renderer.setStyle(this.el.nativeElement, 'color', 'green'); 
  this.badBoyAlert('black');
} else {

  this.badBoyAlert('black');
   //do something her to indicate invalid character
  this.renderer.setStyle(this.el.nativeElement, 'color', 'red');
  e.preventDefault();

}

  }
  badBoyAlert(color: string) {
    setTimeout(() => {
      this.showMsg = true;
      this.renderer.setStyle(this.el.nativeElement, 'color', color);
    }, 2000)
  }

  }

HTML     <input class="form-control" appInputMask="badBoys">

答案 6 :(得分:2)

<input type="number" onkeypress="return event.charCode >= 48 && event.charCode <= 57" ondragstart="return false;" ondrop="return false;"> 
  

输入字段只接受数字,但它只是临时修复。

答案 7 :(得分:1)

<input>字段中的HTML中写道:(keypress)="onlyNumberKey($event)"

并在ts文件中写:

onlyNumberKey(event) {
    return (event.charCode == 8 || event.charCode == 0) ? null : event.charCode >= 48 && event.charCode <= 57;
}

答案 8 :(得分:1)

我认为这可以解决您的问题。我创建了一个指令,用于过滤用户的输入并限制您想要的数字或文本。

此解决方案适用于Ionic-3和Angular-4用户。

import { Directive, HostListener, Input } from '@angular/core';
import { Platform } from 'ionic-angular';

/**
 * Generated class for the AlphabateInputDirective directive.
 *
 * See https://angular.io/api/core/Directive for more info on Angular
 * Directives.
 */
@Directive({
  selector: '[keyboard-input-handler]' // Attribute selector
})
export class IonicKeyboardInputHandler {

  @Input("type") inputType: string;

  isNumeric: boolean = true;
  str: string = "";
  arr: any = [];  

  constructor(
    public platForm: Platform
  ) {
    console.log('Hello IonicKeyboardInputHandler Directive');
  }


  @HostListener('keyup', ['$event']) onInputStart(e) {   

    this.str = e.target.value + '';

    this.arr = this.str.split('');

    this.isNumeric = this.inputType == "number" ? true : false; 

    if(e.target.value.split('.').length === 2){
      return false;
    }    

    if(this.isNumeric){
      e.target.value = parseInt(this.arr.filter( c => isFinite(c)).join(''));
    }      
    else
      e.target.value = this.arr.filter( c => !isFinite(c)).join('');        

    return true;

  }


}

答案 9 :(得分:0)

我认为自定义ControlValueAccessor是最佳选择。

未经测试但据我记得,这应该有效:

<input [(ngModel)]="value" pattern="[0-9]">

<击>

答案 10 :(得分:0)

Anoher one

<form [formGroup]="myForm" novalidate>
    <input type="text" class="form-control" id="data" name="data"
           formControlName="input3" #item (input)="change(item.value)">
</form>
{{myForm.value |json}}

change(value:string)
  {
    let lastchar = value.substr(value.length - 1);
    if (!(new RegExp('[0-9]').test(lastchar)))
    {
      value=value.substr(0,value.length-1);
      this.myForm.controls["input3"].setValue(value);

    }
  }

如果您使用驱动模板

  <input type="text" class="form-control" id="data" name="data"
       [(ngModel)]="data" #item (input)="change(item)">
   {{data}}

change(item:any)
  {
    let value=item.value;
    let lastchar = value.substr(value.length - 1);
    if (!(new RegExp('[0-9]').test(lastchar)))
    {
      value=value.substr(0,value.length-1);
      item.value=this.data=value;
    }
  }

更新作为@BikashBishwokarma评论,如果您在中间插入一个字符,则无效。我们可以像

那样更改功能
  change(item:any)
  {
    let value=item.value;
    let pos=item.selectionStart;
    if (!(new RegExp('^[0-9]+$').test(value)))
    {
      item.value=this.data=value.replace(/[^0-9]+/g, '');
      item.selectionStart = item.selectionEnd = pos-1;
    }
  }

请参阅如何维护光标位置

答案 11 :(得分:0)

在html中:

 <input (keypress)="onlyNumber(event)"/>

在组件中:

onlyNumber(evt) {
    evt = (evt) ? evt : window.event;
    var charCode = (evt.which) ? evt.which : evt.keyCode;
    if (charCode > 31 && (charCode < 48 || charCode > 57)) {
        return false;
    }
    return true;
}

答案 12 :(得分:0)

以下是使用NgModel的有效解决方案

添加变量

datetime.time(your_date_time)

在html中添加

 public Phone:string;

在Ts文件中

      <input class="input-width" [(ngModel)]="Phone" (keyup)="keyUpEvent($event)" 
      type="text" class="form-control" placeholder="Enter Mobile Number">

答案 13 :(得分:0)

要捕获有关模型更改的所有事件, 可以考虑使用

<input (ngModelChange)="inputFilter($event)"/>

它将检测复制/粘贴,抠像以及任何更改模型值的条件。

然后:

inputFilter(event: any) {
    const pattern = /[0-9\+\-\ ]/;
    let inputChar = String.fromCharCode(event.charCode);

    if (!pattern.test(inputChar)) {
      // invalid character, prevent input
      event.preventDefault();
    }
}

答案 14 :(得分:0)

我用这个:


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

@Directive({
    selector: '[ngModel][onlyNumber]',
    host: {
        "(input)": 'onInputChange($event)'
    }
})
export class OnlyNumberDirective {

    @Input() onlyNumber: boolean;
    @Output() ngModelChange: EventEmitter<any> = new EventEmitter()

    constructor(public el: ElementRef) {
    }

    public onInputChange($event){
        if ($event.target.value == '-') {
            return;
        }

        if ($event.target.value && $event.target.value.endsWith('.')) {
            return;
        }

        $event.target.value = this.parseNumber($event.target.value);
        $event.target.dispatchEvent(new Event('input'));
    }

    @HostListener('blur', ['$event'])
    public onBlur(event: Event) {
        if (!this.onlyNumber) {
            return;
        }

        this.el.nativeElement.value = this.parseNumber(this.el.nativeElement.value);
        this.el.nativeElement.dispatchEvent(new Event('input'));
    }

    private parseNumber(input: any): any {
        let trimmed = input.replace(/[^0-9\.-]+/g, '');
        let parsedNumber = parseFloat(trimmed);

        return !isNaN(parsedNumber) ? parsedNumber : '';
    }

}

且使用情况如下

<input onlyNumbers="true" ... />

答案 15 :(得分:0)

这是迄今为止我能够解决的最佳解决方案(甚至适用于 Angular 10):

HTML:

  <input type="text" (input)="inputValidator($event)">

TS 文件:

  public inputValidator(event: any) {
        const pattern = /^[0-9]*$/;   
        if (!pattern.test(event.target.value)) {//enter only numeric
          event.target.value = event.target.value.replace(/[^0-9]/g, "");
        }
        if(event.target.value == 0){  //avoid 0
          event.target.value = event.target.value.replace(event.target.value,"");
        }
        if(event.target.value > 100000){//to block user enter more than 1000000
          event.target.value = event.target.value.replace(event.target.value,event.target.value.slice(0,6));
        }
      }