web-dev-qa-db-ja.com

Angular2-数字のみを受け入れる入力フィールド

Angular2では、アルファベットではなく数字のみを受け入れるように入力フィールド(テキストボックス)をマスクするにはどうすればよいですか?

次のHTML入力があります。

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

上記の入力は、単純なテキストフィールドまたは数値フィールドとして使用できる汎用テキスト入力です(たとえば、年を表示するため)。

Angle2を使用して、同じ入力コントロールを使用して、このフィールドに何らかの種類のフィルター/マスクを適用して、数字のみを受け入れるようにするにはどうすればよいですか?これを達成する方法は何ですか?

注:入力番号タイプを使用せず、テキストボックスのみを使用してこれを達成する必要があります。

52

Angular2ディレクティブを使用できます。 Plunkr

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

ディレクティブが必要ない場合

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

component.html

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

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

  }
}
45
rashidnk

私は、@ omeralperによって与えられた答えに基づいて構築したいと思います。これは、私の意見では、堅実なソリューションの優れた基盤を提供しました。

私が提案しているのは、最新のWeb標準を備えた簡素化された最新バージョンです。 event.keycodeはWeb標準から削除されており、今後のブラウザ更新ではサポートされなくなる可能性があることに注意することが重要です。 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();
        }
    }
}
26
JeanPaul A.

私はこれが古い質問であることを知っていますが、これは一般的な機能なので、私が行った変更を共有したいと思います。

  • カスタム小数点区切り文字(ポイントまたはコンマ)
  • 整数のみまたは整数と小数のサポート
  • 正数のみまたは正数と負数のサポート
  • マイナス記号(-)が先頭にあることを検証する
  • マウスの貼り付けのサポート(ただし、いくつかの制限があります 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">
20
Elvis Fernandez
<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();
    }
  }
13
ketan pradhan

より簡潔なソリューション。このディレクティブを試してください。

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>
10
Ben Gulapa

テキストの代わりにtype = "number"を使用する必要があります。最大数と最小数を指定することもできます

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

このように達成できます

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

これがあなたのお役に立てば幸いです。

8
Pardeep Jain

以下のような入力にはpattern属性を使用します。

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

これを実現するために、次のように関数を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以外の文字)を入力しようとすると、テキストボックスには何も起こらないように見えます。

4
Christopher

正規表現を使用できます:

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

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

JeanPaul A.とrdanielmurphyに感謝します。入力フィールドを数字のみに制限する独自のカスタムディレクティブを作成しました。 maxおよびmin入力属性も追加されました。 angular 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 />
3
leox

有効な携帯電話番号のパターンpattern( '^((\ + 91-?)| 0)?[0-9] {10} $')

テキストボックスからの数字のみを受け入れるパターンpattern( '[0-9] *')

特定の番号を持つ番号のみを受け入れるためのパターン(例:ピンコード)。パターン( '^ [0-9] {5} $')

3
Satish Deokar

上記のディレクティブにいくつか変更を加え、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();
    }

  }
}
2
Karan Mistry

ディレクティブを作成して、hostlistenerを追加するだけです。

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

無効なテキストを空に置き換えます。 IE9までは、すべてのキーとキーの組み合わせがすべてのブラウザーで機能するようになりました。

2
Gaurav Joshi

貼り付けられたコンテンツのサニタイズのサポート:

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

}
1
mad_fox

@omeralperの回答から。ピリオドアスキー(キーコード110,190)を受け入れない少し変更します。 let let =(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();
    }
  }
}

このヘルプを願っています:)

1

このバリデータを作成して、コンポーネントにインポートできます。
基本的にフォーム入力文字列を検証します。

  • ドットがないことを確認してください
  • 文字列を数値に変換します
  • チェックは整数です
  • チェックがゼロより大きい

プロジェクトに実装するには:

  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;
    }        
}
1
guillefd

簡単なもの:シンプルなディレクティブ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" />
1
Lahar Shah

書くだけでは簡単ではないだろう

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

}

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

      }
    }

ディレクティブもそれを行うための最良の方法です

0
user8199162

コピー/貼り付けの処理について多くのコメントを見ました。

@omeralperの回答から便乗するには、onlyNumberディレクティブにpasteイベントハンドラーを追加して、コピー/貼り付けを処理できます。

 @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');
0
rdanielmurphy

fromCharCodeは、テンキーの「1」を押すと「a」を返すため、このメソッドは避ける必要があります

(管理者:通常どおりコメントできませんでした)

0
fdsfdsfdsfds

PrimengとAngular 6以上を使用する場合、p-inputMaskコンポーネントがあります。アルファタイピングと負の値を防ぎます https://www.primefaces.org/primeng/#/inputmask

0
dotista2008

ControlValueAccessorを使用しないのはなぜですか?

https://stackblitz.com/edit/angular-wwo9kt

「入力」イベントをリッスンできます。キーコードを確認する必要はありません。 ControlValueAccessorを使用すると、モデルが正しく更新されたことを確認できます。

export class OnlyNumberDirective implements ControlValueAccessor {

private onChange: (val: string) => void;
private onTouched: () => void;

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

@HostListener('input', ['$event'])
onInputChange() {
    this.updateTextInput(this.elementRef.nativeElement.value);
}

private updateTextInput(value) {
    const filteredValue = value.replace(/[^0-9]*/g, '');
    this.renderer.setProperty(this.elementRef.nativeElement, 'value', filteredValue);
    this.onChange(filteredValue);
}

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

writeValue(value: string): void {
    if (value) {
        this.updateTextInput(value);
    }
}
}
0
spierala

次のようにテキストにタイプ番号を使用するだけです。

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

以下は、数字のみを入力し、テキストではなく数字のみを貼り付けることができるangularコードです。

<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とjavascriptを使用してこのタスクを実行しました。 「貼り付け」および「キーアップ」は、貼り付けをトリガーしてフィールドに入力するために使用されます。

0
ajay hariyal