Pesquisa de site

typescript - Permitir apenas números positivos com apenas um decimal no Angular 6


Sou novo no Stack Overflow, então, por favor, me perdoem se eu estiver errado em algum lugar. Estou preso com um problema no Angular 6, tenho alguns campos de entrada do tipo número e texto e quero impedir que os usuários insiram qualquer caractere além de '.' (ponto) e que apenas entrem números positivos com um único ponto, por exemplo, '1.22' e não '1..2.' ou '-1.12' ou '-111'.

Eu tentei (keyup), (keypress) e (keydown), mas cada um deles funciona de forma realmente confusa para mim. Por favor, aconselhe se existe alguma diretiva ou alguma solução. em HTML

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

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

}

Resposta #1

Aqui está, solução completa funcionando para você:

1) Diretiva

@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 em HTML

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

Stackblitz aqui para referência

Resposta #2

Finalmente, depois de muitas sessões de brainstorming, encontrei uma solução que funciona para mim. Gostaria de agradecer a todos por me ajudarem, vocês são salvadores.

Eu usei o código de @yanky_cranky e modifiquei um pouco e funcionou para os tipos de entrada de número e texto. Aqui está o código.

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

Diretiva :

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