web-dev-qa-db-fra.com

Limiter le champ de saisie à deux décimales - Angular 5

Le code est comme suit

<input type="number" class="form-control" value="" name="cost_price" #name="ngModel" [(ngModel)]="item.cost_price" placeholder="Cost Price"  />

L'utilisateur ne devrait pas pouvoir taper plus de 2 décimales.

Par exemple, si l'utilisateur veut entrer 21.256. Il ne devrait être autorisé qu'à entrer 21.25

Comment y parvenir avec angular 5?

7
prajeesh

Commencez par créer Directive pour limiter les deux décimales dans TypeScript de la manière suivante:

import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
  selector: '[appTwoDigitDecimaNumber]'
})
export class TwoDigitDecimaNumberDirective {
  private regex: RegExp = new RegExp(/^\d*\.?\d{0,2}$/g);
  private specialKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home', '-', 'ArrowLeft', 'ArrowRight', 'Del', 'Delete'];
  constructor(private el: ElementRef) {
  }
  @HostListener('keydown', ['$event'])
  onKeyDown(event: KeyboardEvent) {
    console.log(this.el.nativeElement.value);
    // Allow Backspace, tab, end, and home keys
    if (this.specialKeys.indexOf(event.key) !== -1) {
      return;
    }
    let current: string = this.el.nativeElement.value;
    const position = this.el.nativeElement.selectionStart;
    const next: string = [current.slice(0, position), event.key == 'Decimal' ? '.' : event.key, current.slice(position)].join('');
    if (next && !String(next).match(this.regex)) {
      event.preventDefault();
    }
  }
}

Injecter la directive dans votre app.module.ts. Dans votre code HTML, utilisez cette directive comme ceci:

<input type="textbox" [(ngModel)]="InputValue" appTwoDigitDecimaNumber>

Voici un exemple pratique dans Angular 4/5/6: validation du nombre limite de deux décimales)

J'espère que ceci vous aidera!!!!

29
Sanoj_V

Les solutions @Sanoj_v et user3803848 fonctionnent très bien, mais il y a un autre bogue dans IE. Lorsque l'utilisateur utilise le signe de point du clavier numérique, un événement de clé 'Decimal' est émis et la directive ne fonctionne pas correctement.

Correction pour cela:

    const next: string = [current.slice(0, position), event.key === 'Decimal' ? '.' : event.key, current.slice(position)].join('');

Juste au cas où, j'ai ajouté '.' et ',' char to regex, qui vérifie la saisie de l'utilisateur.

Au-dessous de toute la directive

@Directive({
  selector: '[appTwoDigitDecimalNumber]',
})
export class TwoDigitDecimaNumberDirective {
  private regex: RegExp = new RegExp(/^\d+[.,]?\d{0,2}$/g);// user can put . or , char.
// input also cannot start from , or .
  private specialKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home', '-', 'ArrowLeft', 'ArrowRight', 'Del', 'Delete'];

  constructor(private el: ElementRef) {
  }

  @HostListener('keydown', ['$event'])
  onKeyDown(event: KeyboardEvent) {
    if (this.specialKeys.includes(event.key)) {
      return;
    }
    const current: string = this.el.nativeElement.value;
    const position = this.el.nativeElement.selectionStart;
    const next: string = [current.slice(0, position), event.key == 'Decimal' ? '.' : event.key, current.slice(position)].join('');
    if (next && !String(next).match(this.regex)) {
      event.preventDefault();
    }
  }
}

Rappelez-vous qu'il est toujours possible de coller des données erronées en entrée. C'est pourquoi, vous avez probablement besoin d'une validation supplémentaire, peut-être sur un événement d'entrée pour empêcher le collage de données erronées.

3
Kamil Naja

La réponse fournie par @Sanoj_V peut être améliorée:

1) vous ne pouvez pas utiliser les touches de direction pour modifier le numéro, vous pouvez simplement ajouter des chiffres à la fin ou vous devez cliquer à l'endroit où vous souhaitez modifier le numéro.

2) une fois que vous avez inséré deux décimales, vous ne pouvez utiliser que le retour arrière. Vous pouvez donc supprimer la dernière décimale ou cliquer quelque part pour supprimer un chiffre, mais vous ne pouvez rien ajouter, vous ne pouvez donc pas modifier un chiffre en le remplaçant.

Pour résoudre ce problème, il suffit de remplacer: private specialKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home', '-'];

par: private specialKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home', '-', 'ArrowLeft', 'ArrowRight'];

Puis remplacez: let next: string = current.concat(event.key);

par: const next: string = [current.slice(0, position), event.key, current.slice(position)].join('');

puis ajoutez cette ligne juste au-dessus: const position = this.el.nativeElement.selectionStart;

Merci @Sanoj_V pour cette directive, j'ai passé toute la journée à essayer de comprendre comment traiter les entrées de devises.

3
user3803848

Le moyen le plus simple d'y parvenir serait de se lier à l'événement "keypress" et de valider avec une expression regex, que cette entrée soit valide ou non.

<input type="number" ... placeholder="Cost Price"  (keypress)="validateNumber($event)" />

Et puis le validateNumber serait quelque chose comme:

validateNumber(e: any) {
    let input = String.fromCharCode(e.charCode);
    const reg = /^\d*(?:[.,]\d{1,2})?$/;

    if (!reg.test(input)) {
      e.preventDefault();
    }
}
1
pau

J'utilise ng2-currency-mask , c'est très utile. cela vous aidera.

0
ihist

En dessous du codage, la zone de texte permet aux champs numériques comportant deux décimales (plus de deux décimales donneront un avertissement), sans utilisation de regex:

abc.component.html:

<div >
                                <input class="" type="text" [(ngModel)]="" value="" (keyup)="" [disabled]="" (keypress)="numberOnly($event)">
                                <span class="d-block ml-2">NumericBox(two decimal places)</span>
                            </div>

abc.component.ts:

public dotCount: nombre = 0;

numberOnly(event): boolean {          
    const charCode = (event.which) ? event.which : event.keyCode;      
    if (charCode == 46) {
        this.dotCount += 1;
        this.checkNumberOnly = (event.target.value);
        var numericCheck = (event.target.value).toString();
        if (numericCheck.includes('.')) {
            this.dotCount += 1;
        }
        if (this.dotCount > 1) {   
            this.dotCount = 0;
            return false;
        }
    }
    if (charCode > 31 && (charCode < 45 || charCode > 57 || charCode==47)) {
        return false;
    }
    this.checkNumberOnly = (event.target.value);
    if (this.checkNumberOnly != null) {
        var numeric = (event.target.value).toString();
        if (numeric.includes('.')) {
            var checkNumeric = numeric.split('.');
            if (checkNumeric.length > 2) {
                return false;
            }
            this.checkString = checkNumeric[1].split('');
            if (this.checkString.length > 1) {
                this.toastrService.warning("Invalid value", "Warning");
                return false;
            }
        }

    }
    this.dotCount = 0;
    this.cdr.detectChanges();
    return true;

}
0
Brijesh Ray

Peut-être devriez-vous également regarder la validation du formulaire dans le guide angulaire . Cela peut être utile en fonction de votre type de formulaire.

0
Johan Rin