简体   繁体   中英

Angular 2/4 need a Typescript regex to only allow numbers to be entered into input textbox

In my Angular 4 application I have this input box in which I ONLY want numbers... 0-9 to be entered.. otherwise I want it to clear out onkeyup

HTML

<input type="number" (keyup)="numbersOnly($event)"  placeholder="0000000000" formControlName="phone" maxlength="10"/>

Above works to call this function in the component but it is not working to prevent letters.

numbersOnly(val) {
    let y = this.trackerForm.controls['phone'].value
    y.value = y.value.replace(/[^0-9.-]/g, '');

    console.log('y', y);

}
  1. Is .value the wrong approach?
  2. Should I be using event preventdefault?

The console log for 'y' shows correctly.

What do I need to do?

You should probably have a model on the input and pass that into your function with the event. Change the model instead of the event value. Also your solution may not be working because the input probably has the value updated on the (keypress) event.

Since you are using ReactiveForm, you should understand that FormConrtol's value only has a getter .

If you want to change formControl's value, use patchValue or setValue .

let y = this.trackerForm.controls['phone'];
this.trackerForm.controls['phone'].patchValue(y.value.replace(/[^0-9.-]/g, ''));
// OR
this.trackerForm.controls['phone'].setValue(y.value.replace(/[^0-9.-]/g, ''));

Refer demo .

let y = this.trackerForm.controls['phone'].value
                                            ^^^^^
y.value = y.value.replace(/[^0-9.-]/g, '');
   ^^^^

You are already taking the value.

Change it to

let y = this.trackerForm.controls['phone'];
y.value = y.value.replace(/[^0-9.-]/g, '');

You use ngModel instead.

<input type="number" (keyup)="numbersOnly()"  placeholder="0000000000" formControlName="phone" maxlength="10" [(ngModel)]="value"/>


value = "";
numbersOnly() {
    this.value = this.value.replace(/[^0-9.-]/g, '');
}

To access the value of the input field, use ngModel ( documentation )

For form validation, have a look at the built-in tools . If you use these, you can simply use the HTML attribute pattern to achieve a validation of an input field by a regular expression. ( documentation )

Updated code:

<input type="number" name="phoneNumber" placeholder="0000000000" pattern="[0-9.-]*" maxlength="10" [(ngModel)]="phoneNumber" #phoneNumber="ngModel"/>

Please note that you need to define a new field named phoneNumber in your component.

For this kind of things angular has directives that listen to the events coming from components.

If you have your input mapped to a model then the way you assign the value will not be reflected into model. So that should be taken care of as well.

@Directive({
  selector: '[restrict]',
})
export class RestrictDirective {


  constructor(private control: NgControl) {}        

  @HostListener('keyup', ['$event.target'])
  @HostListener('paste', ['$event.target'])
  private onInputEvent(input) {
    if (input.value) {
      let truncated = input.value.replace(PATTERN, ''); //put your pattern here
      // change value only if it contains disallowed characters
      if (truncated !== input.value) {
        this.control.valueAccessor.writeValue(truncated); //write to model
        this.control.viewToModelUpdate(truncated);        //write to view       
      }
    }
  }
}

Then just get to use the directive in the input

<input type="text" restrict/>

For integers the pattern would be

const PATTERN = /[\D]/g;   

Improving Damask's answer. If we are using Reactive Forms, I's necesary the last line: "this.control.control.setValue(truncated); "

<input type="text" [restrict]="'[^0-9]'" />

The directive

@Directive({
  selector: '[restrict]',
})
export class RestrictDirective {

  regexp:any;
  @Input('restrict') 
  set pattern(value)
  {
    this.regexp=new RegExp(value,"g");
  }

  constructor(private control: NgControl) {}        

  @HostListener('input', ['$event.target'])
  @HostListener('paste', ['$event.target'])
  private onInputEvent(input) {
    if (input.value) {
      let truncated = input.value.replace(this.regexp, ''); 
      if (truncated !== input.value) {
        this.control.valueAccessor.writeValue(truncated); //write to model
        this.control.viewToModelUpdate(truncated);        //write to view 
        this.control.control.setValue(truncated);  //send to control

      }
    }
  }
}

create a simple directive something like this

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

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

  constructor() { }

  @HostListener('keypress', ['$event'])
  onInput(event: any) {
    const pattern = /[0-9]/;
    const inputChar = String.fromCharCode(event.which ? event.which : event.keyCode);

    if (!pattern.test(inputChar)) {
      event.preventDefault();
      return false;
    }
    return true;
  }

}

import this in your module

and in HTML

<input type="number" appNumberOnly placeholder="0000000000" formControlName="phone" maxlength="10"/>

Also inside your component.ts, inside formBuilder you can have something like this

 phone: ['', Validators.compose([Validators.maxLength(10), Validators.pattern('[6-9]\\d{9}'), Validators.required])], 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM