Búsqueda de sitios web

typescript - Solo permitir números positivos con solo un decimal en Angular 6


Soy nuevo en Stack Overflow, así que por favor perdónenme si me equivoco en algún lugar. Estoy atascado con un problema en Angular 6, tengo algunos campos de entrada de tipo número y texto y quiero evitar que los usuarios ingresen cualquier carácter que no sea '.' (punto) y que solo ingresen números positivos con un único punto, por ejemplo, '1.22' y no '1..2.' o '-1.12' o '-111'.

He intentado (keyup), (keypress) y (keydown) pero cada uno de ellos funciona de manera realmente confusa para mí. Por favor, aconseje si hay alguna directiva o alguna solución. en html

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

en .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;

}

Respuesta #1

Aquí tienes, solución funcional completa para ti:

1) Directiva

@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) Uso en HTML

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

Stackblitz aquí para referencia

Respuesta #2

Finalmente, después de mucho brainstorming, he encontrado una solución que funciona para mí. Me gustaría agradecer a todos por ayudarme, ustedes son mis salvadores.

He usado el código de @yanky_cranky y lo he modificado un poco y funcionó tanto para el tipo de entrada de número como de texto. Aquí está el código.

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

Directiva:

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