Programing

Angular2-숫자 만 허용하는 입력 필드

lottogame 2021. 1. 9. 09:16
반응형

Angular2-숫자 만 허용하는 입력 필드


Angular 2에서 알파벳 문자가 아닌 숫자 만 받아들이도록 입력 필드 (텍스트 상자)를 마스크하려면 어떻게해야합니까?

다음 HTML 입력이 있습니다.

<input 
  type="text" 
  *ngSwitchDefault 
  class="form-control" 
  (change)="onInputChange()" 
  [(ngModel)]="config.Value" 
  (focus)="handleFocus($event)" 
  (blur)="handleBlur($event)"
/>

위의 입력은 간단한 텍스트 필드 또는 숫자 필드 (예 : 연도 표시)로 사용할 수있는 일반 텍스트 입력입니다.

Angular 2를 사용하여 동일한 입력 컨트롤을 사용하고 숫자 만 허용하도록이 필드에 일종의 필터 / 마스크를 적용하려면 어떻게해야합니까?

이것을 달성 할 수있는 다른 방법은 무엇입니까?

참고 : 입력 번호 유형을 사용하지 않고 텍스트 상자 만 사용하여이 작업을 수행해야합니다.


angular2 지시문을 사용할 수 있습니다. 플 런커

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

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

  constructor(private el: ElementRef) { }

  @Input() OnlyNumber: boolean;

  @HostListener('keydown', ['$event']) onKeyDown(event) {
    let e = <KeyboardEvent> event;
    if (this.OnlyNumber) {
      if ([46, 8, 9, 27, 13, 110, 190].indexOf(e.keyCode) !== -1 ||
        // Allow: Ctrl+A
        (e.keyCode === 65 && (e.ctrlKey || e.metaKey)) ||
        // Allow: Ctrl+C
        (e.keyCode === 67 && (e.ctrlKey || e.metaKey)) ||
        // Allow: Ctrl+V
        (e.keyCode === 86 && (e.ctrlKey || e.metaKey)) ||
        // Allow: Ctrl+X
        (e.keyCode === 88 && (e.ctrlKey || e.metaKey)) ||
        // Allow: home, end, left, right
        (e.keyCode >= 35 && e.keyCode <= 39)) {
          // let it happen, don't do anything
          return;
        }
        // Ensure that it is a number and stop the keypress
        if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
            e.preventDefault();
        }
      }
  }
}

입력에 속성으로 지시문 이름을 작성해야합니다.

<input OnlyNumber="true" />

모듈의 선언 배열에 지시문을 작성하는 것을 잊지 마십시오.

정규식을 사용하면 여전히 기능 키가 필요합니다.

export class OnlyNumber {

  regexStr = '^[0-9]*$';
  constructor(private el: ElementRef) { }

  @Input() OnlyNumber: boolean;

  @HostListener('keydown', ['$event']) onKeyDown(event) {
    let e = <KeyboardEvent> event;
    if (this.OnlyNumber) {
        if ([46, 8, 9, 27, 13, 110, 190].indexOf(e.keyCode) !== -1 ||
        // Allow: Ctrl+A
        (e.keyCode == 65 && e.ctrlKey === true) ||
        // Allow: Ctrl+C
        (e.keyCode == 67 && e.ctrlKey === true) ||
        // Allow: Ctrl+V
        (e.keyCode == 86 && e.ctrlKey === true) ||
        // Allow: Ctrl+X
        (e.keyCode == 88 && e.ctrlKey === true) ||
        // Allow: home, end, left, right
        (e.keyCode >= 35 && e.keyCode <= 39)) {
          // let it happen, don't do anything
          return;
        }
      let ch = String.fromCharCode(e.keyCode);
      let regEx =  new RegExp(this.regexStr);    
      if(regEx.test(ch))
        return;
      else
         e.preventDefault();
      }
  }
}

지시어를 원하지 않는 경우

https://stackblitz.com/edit/numeric-only

component.html에서

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

component.ts에서

export class AppComponent {

  numberOnly(event): boolean {
    const charCode = (event.which) ? event.which : event.keyCode;
    if (charCode > 31 && (charCode < 48 || charCode > 57)) {
      return false;
    }
    return true;

  }
}

저는 @omeralper가 제공 한 답변을 기반으로하고 싶습니다. 제 생각에는 견고한 솔루션을위한 좋은 토대를 제공했습니다.

제가 제안하는 것은 최신 웹 표준을 갖춘 단순화 된 최신 버전입니다. event.keycode는 웹 표준에서 제거되었으며 향후 브라우저 업데이트에서 더 이상 지원하지 않을 수 있습니다. 참조 https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode를

또한 방법

String.fromCharCode(e.keyCode);

다른 키보드 구성으로 인해 특정 키 코드가 다른 문자를 생성하기 때문에 사용자가 누르는 키와 관련된 keyCode가 사용자의 키보드에서 식별되는 예상 문자에 매핑된다는 것을 보장하지 않습니다. 이를 사용하면 식별하기 어려운 버그가 발생하고 특정 사용자의 기능을 쉽게 손상시킬 수 있습니다. 오히려 event.key의 사용을 제안하고 있습니다. https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key 여기 문서를 참조하십시오.

또한 결과 출력이 유효한 10 진수 여야합니다. 즉, 숫자 1, 11.2, 5000.2341234는 허용되어야하지만 1.1.2 값은 허용되지 않아야합니다.

내 솔루션에서는 특히 사람들이 관련 필드에 원하지 않는 텍스트를 붙여 넣을 때 버그에 대한 창이 열리기 때문에 잘라 내기, 복사 및 붙여 넣기 기능을 제외하고 있습니다. 이를 위해서는 키업 처리기에서 정리 프로세스가 필요했습니다. 이 스레드의 범위가 아닙니다.

여기 제가 제안하는 해결책이 있습니다.

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

@Directive({
    selector: '[myNumberOnly]'
})
export class NumberOnlyDirective {
    // 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();
        }
    }
}

나는 이것이 오래된 질문이라는 것을 알고 있지만 이것은 일반적인 기능이기 때문에 내가 만든 수정 사항을 공유하고 싶습니다.

  • 사용자 지정 소수점 구분 기호 (포인트 또는 쉼표)
  • 정수만 또는 정수 및 소수 지원
  • 양수 또는 양수 및 음수 만 지원
  • 마이너스 부호 (-)가 처음에 있는지 확인
  • 마우스 붙여 넣기 지원 ( https://caniuse.com/#feat=clipboard를 통해 일부 제한 있음 )
  • Mac 명령 키 지원
  • ".33"및 "33"과 같은 문자열을 바꿉니다. 올바른 버전 : 0.33 및 33.0

    import { Directive, ElementRef, HostListener, Input } from '@angular/core';
    
    @Directive({ selector: '[NumbersOnly]' })
    export class NumbersOnly { 
    
        @Input() allowDecimals: boolean = true;
        @Input() allowSign: boolean = false;
        @Input() decimalSeparator: string = '.';
    
        previousValue: string = '';
    
        // --------------------------------------
        //  Regular expressions
        integerUnsigned: string = '^[0-9]*$';
        integerSigned: string = '^-?[0-9]+$';
        decimalUnsigned: string = '^[0-9]+(.[0-9]+)?$';
        decimalSigned: string = '^-?[0-9]+(.[0-9]+)?$';
    
        /**
         * Class constructor
         * @param hostElement
         */
        constructor(private hostElement: ElementRef) { }
    
        /**
         * Event handler for host's change event
         * @param e
         */
        @HostListener('change', ['$event']) onChange(e) {
    
                this.validateValue(this.hostElement.nativeElement.value);
    }
    
    /**
     * Event handler for host's paste event
     * @param e
     */
    @HostListener('paste', ['$event']) onPaste(e) {
    
        // get and validate data from clipboard
        let value = e.clipboardData.getData('text/plain');
        this.validateValue(value);
        e.preventDefault();
    }
    
    /**
     * Event handler for host's keydown event
     * @param event
     */
    @HostListener('keydown', ['$event']) onKeyDown(e: KeyboardEvent) {
    
        let cursorPosition: number = e.target['selectionStart'];
        let originalValue: string = e.target['value'];
        let key: string = this.getName(e);
        let controlOrCommand = (e.ctrlKey === true || e.metaKey === true);
        let signExists = originalValue.includes('-');
        let separatorExists = originalValue.includes(this.decimalSeparator);
    
        // allowed keys apart from numeric characters
        let allowedKeys = [
            'Backspace', 'ArrowLeft', 'ArrowRight', 'Escape', 'Tab'
        ];
    
        // when decimals are allowed, add
        // decimal separator to allowed codes when
        // its position is not close to the the sign (-. and .-)
        let separatorIsCloseToSign = (signExists && cursorPosition <= 1);
        if (this.allowDecimals && !separatorIsCloseToSign && !separatorExists) {
    
            if (this.decimalSeparator == '.')
                allowedKeys.push('.');
            else
                allowedKeys.push(',');
        }
    
        // when minus sign is allowed, add its
        // key to allowed key only when the
        // cursor is in the first position, and
        // first character is different from
        // decimal separator
        let firstCharacterIsSeparator = (originalValue.charAt(0) != this.decimalSeparator);
        if (this.allowSign && !signExists &&
            firstCharacterIsSeparator && cursorPosition == 0) {
    
            allowedKeys.push('-');
        }
    
        // allow some non-numeric characters
        if (allowedKeys.indexOf(key) != -1 ||
            // Allow: Ctrl+A and Command+A
            (key == 'a' && controlOrCommand) ||
            // Allow: Ctrl+C and Command+C
            (key == 'c' && controlOrCommand) ||
            // Allow: Ctrl+V and Command+V
            (key == 'v' && controlOrCommand) ||
            // Allow: Ctrl+X and Command+X
            (key == 'x' && controlOrCommand)) {
            // let it happen, don't do anything
            return;
        }
    
        // save value before keydown event
        this.previousValue = originalValue;
    
        // allow number characters only
        let isNumber = (new RegExp(this.integerUnsigned)).test(key);
        if (isNumber) return; else e.preventDefault();
    }
    
    /**
     * Test whether value is a valid number or not
     * @param value
     */
    validateValue(value: string): void {
    
        // choose the appropiate regular expression
        let regex: string;
        if (!this.allowDecimals && !this.allowSign) regex = this.integerUnsigned;
        if (!this.allowDecimals && this.allowSign) regex = this.integerSigned;
        if (this.allowDecimals && !this.allowSign) regex = this.decimalUnsigned;
        if (this.allowDecimals &&  this.allowSign) regex = this.decimalSigned;
    
        // when a numbers begins with a decimal separator,
        // fix it adding a zero in the beginning
        let firstCharacter = value.charAt(0);
        if (firstCharacter == this.decimalSeparator)
            value = 0 + value;
    
        // when a numbers ends with a decimal separator,
        // fix it adding a zero in the end
        let lastCharacter = value.charAt(value.length-1);
        if (lastCharacter == this.decimalSeparator)
            value = value + 0;
    
        // test number with regular expression, when
        // number is invalid, replace it with a zero
        let valid: boolean = (new RegExp(regex)).test(value);
        this.hostElement.nativeElement['value'] = valid ? value : 0;
    }
    
    /**
     * Get key's name
     * @param e
     */
    getName(e): string {
    
        if (e.key) {
    
            return e.key;
    
        } else {
    
            // for old browsers
            if (e.keyCode && String.fromCharCode) {
    
                switch (e.keyCode) {
                    case   8: return 'Backspace';
                    case   9: return 'Tab';
                    case  27: return 'Escape';
                    case  37: return 'ArrowLeft';
                    case  39: return 'ArrowRight';
                    case 188: return ',';
                    case 190: return '.';
                    case 109: return '-'; // minus in numbpad
                    case 173: return '-'; // minus in alphabet keyboard in firefox
                    case 189: return '-'; // minus in alphabet keyboard in chrome
                    default: return String.fromCharCode(e.keyCode);
                }
            }
        }
    }
    

용법:

 <input NumbersOnly
        [allowDecimals]="true"
        [allowSign]="true"
        type="text">

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


  keyPress(event: any) {
    const pattern = /[0-9\+\-\ ]/;

    let inputChar = String.fromCharCode(event.charCode);
    if (event.keyCode != 8 && !pattern.test(inputChar)) {
      event.preventDefault();
    }
  }

더 간결한 솔루션. 이 지시문을 시도하십시오.

ReactiveForms를 사용하는 경우에도 사용할 수 있습니다.

export class NumberOnlyDirective {
  private el: NgControl;

  constructor(private ngControl: NgControl) {
    this.el = ngControl;
  }

  // Listen for the input event to also handle copy and paste.
  @HostListener('input', ['$event.target.value'])
  onInput(value: string) {
    // Use NgControl patchValue to prevent the issue on validation
    this.el.control.patchValue(value.replace(/[^0-9]/g, ''));
  }
}

다음과 같이 입력에 사용하십시오.

<input matInput formControlName="aNumberField" numberOnly>

텍스트 대신 type = "number"를 사용해야합니다. 최대 및 최소 수를 지정할 수도 있습니다.

<input type="number" name="quantity" min="1" max="5">

당신은 이것을 이렇게 얻을 수 있습니다

<input type="text" pInputText (keypress)="onlyNumberKey($event)" maxlength="3"> 

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

//for Decimal you can use this as

onlyDecimalNumberKey(event) {
    let charCode = (event.which) ? event.which : event.keyCode;
    if (charCode != 46 && charCode > 31
        && (charCode < 48 || charCode > 57))
        return false;
    return true;
}

이것이 당신을 도울 수 있기를 바랍니다.


다음 pattern과 같이 입력에 속성을 사용하십시오 .

<input type="text" pattern="[0-9]+" >

이를 수행하기 위해 다음과 같이 onInput 메서드에 함수를 바인딩했습니다.

(input)="stripText(infoForm.get('uin'))

내 양식 내부의 예는 다음과 같습니다.

<form [formGroup]="infoForm" (submit)="next()" class="ui form">
    <input type="text" formControlName="uin" name="uin" id="uin" (input)="stripText(infoForm.get('uin'))" required/>
</form>

그런 다음 구성 요소에 다음 기능을 추가했습니다.

  stripText(control: FormControl) {
   control.setValue(control.value.replace(/[^0-9]/g, ''));
  }

이 정규식 /[^0-9]/g은 숫자가 아닌 모든 것을 검색하고 사용하여 .replace아무것도 대체 하지 않도록 설정합니다. 따라서 사용자가 숫자가 아닌 문자 (이 경우 0에서 9까지가 아닌 문자)를 입력하려고하면 텍스트 상자에 아무 일도 일어나지 않는 것처럼 나타납니다.


정규식을 사용할 수 있습니다.

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

numericOnly(event): boolean {    
    let patt = /^([0-9])$/;
    let result = patt.test(event.key);
    return result;
}

JeanPaul A.와 rdanielmurphy에게 감사드립니다. 입력 필드를 숫자로만 제한하기위한 고유 한 사용자 지정 지시문을 만들었습니다. 또한 최대 및 최소 입력 속성이 추가되었습니다. 각도 7에서도 작동합니다.

모난

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

@Directive({
  selector: '[appNumberOnly]'
})
export class NumberOnlyDirective {
  // 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) { }

  @Input() maxlength: number;
  @Input() min: number;
  @Input() max: number;

  @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
    const 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
    const next: string = current.concat(event.key);
    if (next && !String(next).match(this.regex) || (this.maxlength && next.length > this.maxlength) ||
      (this.min && +next < this.min) ||
      (this.max && +next >= this.max)) {
      event.preventDefault();
    }
  }

  @HostListener('paste', ['$event']) onPaste(event) {
    // Don't allow pasted text that contains non-numerics
    const pastedText = (event.originalEvent || event).clipboardData.getData('text/plain');

    if (pastedText) {
      const regEx = new RegExp('^[0-9]*$');
      if (!regEx.test(pastedText) || (this.maxlength && pastedText.length > this.maxlength) ||
        (this.min && +pastedText < this.min) ||
        (this.max && +pastedText >= this.max)) {
        event.preventDefault();
      }
    }
  }

}

HTML

<input type="text" class="text-area" [(ngModel)]="itemName" maxlength="3" appNumberOnly />

유효한 휴대폰 번호 패턴 패턴 ( '^ ((\ + 91-?) | 0)? [0-9] {10} $')

텍스트 상자에서 숫자 만 허용하는 패턴 pattern ( '[0-9] *')

특정 번호가있는 번호 만 허용하려면 두드려주세요. 예 : 핀 코드. 패턴 ( '^ [0-9] {5} $')


지시문을 만들고 아래에 hostlistener를 추가하십시오.

@HostListener('input', ['$event'])
    onInput(event: Event) {
        this.elementRef.nativeElement.value = (<HTMLInputElement>event.currentTarget).value.replace(/[^0-9]/g, '');
    }

잘못된 텍스트를 빈 텍스트로 바꿉니다. 이제 모든 키와 키 조합이 IE9까지 모든 브라우저에서 작동합니다.


위의 지시문을 수정하고 min, max, maxlength를 구현했습니다.

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

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

  private regex: RegExp = new RegExp(/[0-9]/g);
  // Allow key codes for special events. Reflect :
  private specialKeys: Array<number> = [46, 8, 9, 27, 13, 110, 190, 35, 36, 37, 39];
  // Backspace, tab, end, home

  @Input() maxlength: number;
  @Input() min: number;
  @Input() max: number;

  constructor(private el: ElementRef) {
  }
    @HostListener('keydown', ['$event'])
    onKeyDown(event: KeyboardEvent) {
    e = <KeyboardEvent>event;

if ((
  (this.specialKeys.indexOf(event.which) > -1) ||
  // to allow backspace, enter, escape, arrows  
  (e.which == 65 && e.ctrlKey == true) ||
  // Allow: Ctrl+C        
  (e.which == 67 && e.ctrlKey == true) ||
  // Allow: Ctrl+X
  (e.which == 88 && e.ctrlKey == true))) {
  return;
} else if (// to allow numbers  
  (e.which >= 48 && e.which <= 57) ||
  // to allow numpad number  
  (event.which >= 96 && event.which <= 105)) { }
else {
      event.preventDefault();
    }
    let current: string = this.el.nativeElement.value;

    let next: string = current.concat(event.key);
    if ((next && !String(next).match(this.regex)) ||
      (this.maxlength && next.length > this.maxlength) ||
      (this.min && +next < this.min) ||
      (this.max && +next >= this.max)) {
      event.preventDefault();
    }

  }
}

@omeralper의 답변에서. 마침표 ASCII (키 코드 110,190)를 허용하지 않는 약간 변경합니다. 사용 let ch = (e.key); 언어 (예 : 태국어 또는 일본어)를 변경할 때 정규식과 비교하기 위해 해당 언어의 문자를 허용하지 않습니다.

export class OnlyNumber {

  regexStr = '^[0-9]*$';
  constructor(private el: ElementRef) { }

  @Input() OnlyNumber: boolean;

  @HostListener('keydown', ['$event']) onKeyDown(event) {
    let e = <KeyboardEvent> event;
    if (this.OnlyNumber) {
      // console.log(event, this.OnlyNumber);
        if ([46, 8, 9, 27, 13].indexOf(e.keyCode) !== -1) {
          return;
        }
      let ch = (e.key);
      let regEx =  new RegExp(this.regexStr);   
      if(regEx.test(ch))
        return;
      else
         e.preventDefault();
    }
  }
}

이 도움을 바랍니다 :)


이 유효성 검사기를 만들고 구성 요소로 가져올 수 있습니다.
기본적으로 양식 입력 문자열의 유효성을 검사합니다.

  • 점이 없는지 확인
  • 문자열을 숫자로 변환
  • 검사는 정수입니다.
  • 수표가 0보다 큼

프로젝트에서 구현하려면 :

  1. 앱 폴더의 권장 경로 : src / app / validators / number.validator.ts
  2. 구성 요소에서 가져 오기

    import { NumberValidator } from '../../validators/number.validator';

  3. 양식 컨트롤에 추가
    inputNumber: ['', [NumberValidator.isInteger]],
  4. 당신이 잘못된 문자, 바인드 쇼 싶지 않다 경우 (change)="deleteCharIfInvalid()"입력에을 경우 form.get('inputNumber').hasError('isInteger')입니다 true, 삽입 된 마지막 문자를 삭제합니다.
// FILE: src/app/validators/number.validator.ts

import { FormControl } from '@angular/forms';

export interface ValidationResult {
    [key: string]: boolean;
}

export class NumberValidator {

    public static isInteger(control: FormControl): ValidationResult {
        // check if string has a dot
        let hasDot:boolean = control.value.indexOf('.') >= 0 ? true : false;
        // convert string to number
        let number:number = Math.floor(control.value);
        // get result of isInteger()
        let integer:boolean = Number.isInteger(number);
        // validate conditions 
        let valid:boolean = !hasDot && integer && number>0;
        console.log('isInteger > valid', hasDot, number, valid);
        if (!valid) {
            return { isInteger: true };
        }
        return null;
    }        
}

붙여 넣은 콘텐츠 삭제 지원 :

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

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

    DIGITS_REGEXP =  new RegExp(/\D/g);
    constructor(private el: ElementRef) { 

        // Sanatize clipboard by removing any non-numeric input after pasting
        this.el.nativeElement.onpaste = (e:any) => {
            e.preventDefault();
            let text;
            let clp = (e.originalEvent || e).clipboardData;
            if (clp === undefined || clp === null) {
                text = (<any>window).clipboardData.getData('text') || '';
                if (text !== '') {
                    text = text.replace(this.DIGITS_REGEXP, '');
                    if (window.getSelection) {
                        let newNode = document.createElement('span');
                        newNode.innerHTML = text;
                        window.getSelection().getRangeAt(0).insertNode(newNode);
                    } else {
                        (<any>window).selection.createRange().pasteHTML(text);
                    }
                }
            } else {
                text = clp.getData('text/plain') || '';
                if (text !== '') {
                    text = text.replace(this.DIGITS_REGEXP, '');
                    document.execCommand('insertText', false, text);
                }
            }
        };
    }

  @HostListener('keydown', ['$event']) onKeyDown(event) {
    let e = <KeyboardEvent> event;
    if ([46, 8, 9, 27, 13, 110, 190].indexOf(e.keyCode) !== -1 ||
      // Allow: Ctrl+A
      (e.keyCode === 65 && (e.ctrlKey || e.metaKey)) ||
      // Allow: Ctrl+C
      (e.keyCode === 67 && (e.ctrlKey || e.metaKey)) ||
      // Allow: Ctrl+V
      (e.keyCode === 86 && (e.ctrlKey || e.metaKey)) ||
      // Allow: Ctrl+X
      (e.keyCode === 88 && (e.ctrlKey || e.metaKey)) ||
      // Allow: home, end, left, right
      (e.keyCode >= 35 && e.keyCode <= 39)) {
        // let it happen, don't do anything
        return;
      }
      // Ensure that it is a number and stop the keypress
      if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
          e.preventDefault();
      }
    }

}

간단한 지시문 keydown 이벤트에서 키의 길이가 1이고 키가 숫자가 아닌지 확인하고 preventDefault()해당 문자를 렌더링하지 않습니다.

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

@Directive({
    selector: '[numbersOnly]'
})
export class NumbersOnlyDirective {
    @HostListener('keydown', ['$event'])
    keyDownEvent(event: KeyboardEvent) {
        if (event.key.length === 1 && (event.which < 48 || event.which > 57)) {
            event.preventDefault();
        }
    }

}

HTML :

<input type="text" [(ngModel)]="numModel" numbersOnly />

제한 사항 : 다른 문자를 허용하는 방식으로 마우스를 사용하여 붙여 넣을 수 있습니다. 모델을 지시문에 대한 입력으로 전달하고 ngOnChage해당 모델에 대한 값을 숫자로만 전달할 수 없도록하려면 다음을 수행하십시오 .

아래와 같이 :

편집 : 모델의 변경을 감지하고 입력 값을 업데이트하는 코드 추가

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

@Directive({
    selector: '[numbersOnly]'
})
export class NumbersOnlyDirective implements OnChanges {

    @Input() numbersOnly: any;

    constructor(private el: ElementRef) {}

    @HostListener('keydown', ['$event'])
    keyDownEvent(event: KeyboardEvent) {
        // Add other conditions if need to allow ctr+c || ctr+v
        if (event.key.length === 1 && (event.which < 48 || event.which > 57)) {
            event.preventDefault();
        }
    }

    ngOnChanges(changes) {
        if (changes.numbersOnly) {
            this.el.nativeElement.value = this.el.nativeElement.value.replace(/[^0-9]/g, '');
        }
    }

}

HTML :

<input type="text" [(ngModel)]="numModel" [numbersOnly]="numModel" />

fromCharCode는 숫자 키패드 '1'을 누르면 'a'를 반환하므로이 메 토이 드는 피해야합니다.

(관리자 : 평상시처럼 댓글을 달 수 없습니다)


복사 / 붙여 넣기 처리에 대한 댓글을 많이 보았습니다.

@omeralper 응답을 피기 백하려면 복사 / 붙여 넣기를 처리하기 위해 onlyNumber 지시문에 붙여 넣기 이벤트 처리기를 추가 할 수 있습니다.

 @HostListener('paste', ['$event']) onPaste(event) {
  // Don't allow pasted text that contains non-numerics
  var pastedText = (event.originalEvent || event).clipboardData.getData('text/plain');

  if (pastedText) {
    var regEx = new RegExp('^[0-9]*$');
    if (!regEx.test(pastedText)) {
      event.preventDefault();
    }
}

이렇게하면 숫자 인 경우에만 콘텐츠를 복사하여 텍스트 상자에 붙여 넣을 수 있습니다. 이것이 가장 간단한 해결책입니다. 숫자가 아닌 항목을 제거하기 위해 클립 보드의 내용을 변경하는 것은 훨씬 더 복잡하고 가치가 없을 수 있습니다.

IE에서 붙여 넣은 텍스트를 얻으려면 다음을 사용할 수 있습니다.

window.clipboardData.getData('Text');

아래는 텍스트가 아닌 숫자 만 입력하고 붙여 넣을 수있는 각도 코드입니다.

<input id="pId" maxlength="8" minlength="8" type="text" [(ngModel)]="no" formControlName="prefmeno" name="no" class="form-control">

그리고 ngOnIt에 추가 된 ts 파일에.

ngOnInit() {
  setTimeout(() => {
  jQuery('#pId').on('paste keyup', function(e){
    jQuery(this).val(document.getElementById('pId').value.replace(/[^\d]/g, ''));
  });
}, 2000);
}

DOM을로드하기위한 대기 시간에 setTimeout을 사용했습니다. 그리고이 작업을 수행하기 위해 자바 스크립트와 함께 jquery를 사용했습니다. '붙여 넣기'및 '키업'은 붙여 넣기를 트리거하고 필드에 입력하는 데 사용됩니다.


아래와 같이 텍스트에 숫자를 입력하십시오.

<input type="number" class="form-control" matInput name="value" placeholder="xxx" (change)="xxx()" formControlName="value">

primeng 및 Angular 6 이상을 사용하는 경우 p-inputMask 구성 요소가 있습니다. 알파 타이핑과 음수 값을 방지합니다. https://www.primefaces.org/primeng/#/inputmask


쓰기에 충분하지 않을 것입니다

onlyNumbers(event) {
if(isNaN(event.target.value * 1)) {
 console.log("Not a number")
} else {
  console.log("Number")
}

}


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


    //only-digits
    @Directive({
      selector: '[only-digits]'
    })
    export class OnlyDigits {

      constructor(public el: ElementRef) {

        this.el.nativeElement.onkeypress = (evt) => {
          if (evt.which < 48 || evt.which > 57) {
            evt.preventDefault();
          }
        };

      }
    }

지침은 또한이를 수행하는 가장 좋은 방법입니다.


ControlValueAccessor 인터페이스 ( https://angular.io/api/forms/ControlValueAccessor ) 를 구현하는 지시문을 만들 수도 있습니다 .

여기에서 작업 예를 참조하십시오 : https://stackblitz.com/edit/angular-input-field-to-accept-only-numbers

'입력'이벤트를 수신 할 수 있으며 키 코드를 확인할 필요가 없습니다. 복사 및 붙여 넣기를 지원하고 ControlValueAccessor 인터페이스로 인해 Angular Forms API와 잘 통합됩니다.

지령:

@Directive({
    ...
    selector: '[onlyNumber]'
})
export class OnlyNumberDirective implements ControlValueAccessor {
private onChange: (val: string) => void;
...
private value: string;

constructor(
    private elementRef: ElementRef,
    private renderer: Renderer2
) {
}

...

@HostListener('input', ['$event.target.value'])
onInputChange(value: string) {
    const filteredValue: string = filterValue(value);
    this.updateTextInput(filteredValue, this.value !== filteredValue);
}

private updateTextInput(value, propagateChange) {
    this.renderer.setProperty(this.elementRef.nativeElement, 'value', value);
    if (propagateChange) {
        this.onChange(value);
    }
    this.value = value;
}

// ControlValueAccessor Interface
...

registerOnChange(fn: any): void {
    this.onChange = fn;
}

writeValue(value: string): void {
    value = value ? String(value) : '';
    this.updateTextInput(value, false);
}
}


function filterValue(value): string {
    return value.replace(/[^0-9]*/g, '');
}

용법:

<input name="number" type="text" onlyNumber [(ngModel)]="someNumber">

다음과 같은 방법으로 사용자가 숫자 만 입력하도록 제한하려면 지시문을 사용하십시오.

.directive('onlyNumber', function () {
    var regExp = /^[0-9]*$/;
    return {
        require: '?ngModel',
        restrict: 'A',
        priority: 1,
        link: function (scope, elm, attrs, ctrl) {
            ctrl.$validators.onlyNumber= function (modalValue) {
                return ctrl.$isEmpty(modalValue) || regExp.test(modalValue);
            };
        }
    };
    })

In HTML:

<input id="txtRollNumber" type="text" name="rollNumber" placeholder="Enter roll number*" ng-model="rollNumber" class="form-control" maxlength="100" required only-number />

Angular2:

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

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

  constructor(private el: ElementRef) { }

  @Input() OnlyNumber: boolean;

  @HostListener('keydown', ['$event']) onKeyDown(event) {
    let e = <KeyboardEvent> event;
    if (this.OnlyNumber) {
      if ([46, 8, 9, 27, 13, 110, 190].indexOf(e.keyCode) !== -1 ||
        // Allow: Ctrl+A
        (e.keyCode === 65 && (e.ctrlKey || e.metaKey)) ||
        // Allow: Ctrl+C
        (e.keyCode === 67 && (e.ctrlKey || e.metaKey)) ||
        // Allow: Ctrl+V
        (e.keyCode === 86 && (e.ctrlKey || e.metaKey)) ||
        // Allow: Ctrl+X
        (e.keyCode === 88 && (e.ctrlKey || e.metaKey)) ||
        // Allow: home, end, left, right
        (e.keyCode >= 35 && e.keyCode <= 39)) {
          // let it happen, don't do anything
          return;
        }
        // Ensure that it is a number and stop the keypress
        if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
            e.preventDefault();
        }
      }
  }
}

And need to write the directive name in your input as an attribute.

<input OnlyNumber="true" />

Just use HTML5, input type=”number”

ReferenceURL : https://stackoverflow.com/questions/41465542/angular2-input-field-to-accept-only-numbers

반응형