Dans Angular2, comment masquer un champ de saisie (zone de texte) tel qu’il accepte uniquement les nombres et non les alphabets?
J'ai l'entrée HTML suivante:
<input type="text" *ngSwitchDefault class="form-control" (change)="onInputChange()" [(ngModel)]="config.Value" focus)="handleFocus($event)" (blur)="handleBlur($event)"/>
L'entrée ci-dessus est une entrée de texte générique qui peut être utilisée soit comme un simple champ de texte, soit comme un champ numérique (par exemple, pour indiquer l'année).
Avec angular2, comment puis-je utiliser le même contrôle d’entrée et appliquer une sorte de filtre/masque sur ce champ, de sorte qu’il accepte uniquement les nombres? Quels sont les différents moyens pour y parvenir?
Remarque: je dois y parvenir en utilisant uniquement la zone de texte et en n'utilisant pas le type de numéro d'entrée.
Vous pouvez utiliser les directives 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();
}
}
}
}
et vous devez écrire le nom de la directive dans votre entrée en tant qu'attribut
<input OnlyNumber="true" />
n'oubliez pas d'écrire votre directive dans le tableau de déclarations de votre module.
En utilisant regex, vous aurez toujours besoin de clés fonctionnelles
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();
}
}
}
Si vous ne voulez pas de directive
https://stackblitz.com/edit/numeric-only
dans composant.html
<input (keypress)="numberOnly($event)" type="text">
dans composant.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;
}
}
Je voudrais développer la réponse donnée par @omeralper, qui, à mon avis, a fourni une bonne base pour une solution solide.
Ce que je propose est une version simplifiée et mise à jour avec les dernières normes Web. Il est important de noter que event.keycode est supprimé des normes Web et que les futures mises à jour du navigateur risquent de ne plus le prendre en charge. Voir https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
En outre, la méthode
String.fromCharCode(e.keyCode);
ne garantit pas que le code de touche correspondant à la touche appuyée par l'utilisateur soit mappé sur la lettre attendue telle qu'identifiée sur le clavier de l'utilisateur, car des configurations de clavier différentes entraîneront des caractères différents pour un code de touche particulier. L'utilisation de cette fonctionnalité introduira des bogues difficiles à identifier et pouvant facilement casser les fonctionnalités de certains utilisateurs. Je propose plutôt l'utilisation de event.key, voir docs ici https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key
De plus, nous voulons seulement que la sortie résultante soit une décimale valide. Cela signifie que les nombres 1, 11.2, 5000.2341234 doivent être acceptés, mais que la valeur 1.1.2 ne doit pas être acceptée.
Notez que dans ma solution, les fonctionnalités de couper, copier et coller sont exclues car elles ouvrent des fenêtres pour détecter les bogues, en particulier lorsque des personnes collent du texte indésirable dans des champs associés. Cela nécessiterait un processus de nettoyage sur un gestionnaire de clés; ce qui n'est pas la portée de ce fil.
Voici la solution que je propose.
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();
}
}
}
Je sais que la question est ancienne, mais comme il s’agit d’une fonction courante, je souhaite partager les modifications que j’ai apportées:
Remplacez les chaînes telles que ".33" et "33." pour les versions correctes: 0.33 et 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);
}
}
}
}
Usage:
<input NumbersOnly
[allowDecimals]="true"
[allowSign]="true"
type="text">
<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();
}
}
Une solution plus concise. Essayez cette directive.
Peut aussi être utilisé si vous utilisez 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, ''));
}
}
Utilisez-le sur vos entrées comme ceci:
<input matInput formControlName="aNumberField" numberOnly>
Vous devez utiliser type = "nombre" à la place du texte. Vous pouvez également spécifier des nombres maximum et minimum
<input type="number" name="quantity" min="1" max="5">
vous pouvez y arriver comme ça
<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;
}
j'espère que cela vous aidera.
Utilisez l'attribut pattern
pour la saisie, comme ci-dessous:
<input type="text" pattern="[0-9]+" >
Pour ce faire, j'ai lié une fonction à la méthode onInput comme ceci:
(input)="stripText(infoForm.get('uin'))
Voici l'exemple dans ma fiche:
<form [formGroup]="infoForm" (submit)="next()" class="ui form">
<input type="text" formControlName="uin" name="uin" id="uin" (input)="stripText(infoForm.get('uin'))" required/>
</form>
Ensuite, j'ai ajouté la fonction suivante à mon composant:
stripText(control: FormControl) {
control.setValue(control.value.replace(/[^0-9]/g, ''));
}
Cette expression rationnelle /[^0-9]/g
recherche tout ce qui n’est pas un nombre et utilise .replace
je l’ai définie pour ne rien remplacer. Ainsi, lorsqu'un utilisateur essaie de saisir un caractère qui n'est pas un nombre (dans ce cas, un caractère différent de zéro à neuf), il semble que rien ne se passe dans la zone de texte.
Vous pouvez utiliser regex:
<input type="text" (keypress)="numericOnly($event)">
numericOnly(event): boolean {
let patt = /^([0-9])$/;
let result = patt.test(event.key);
return result;
}
Merci à JeanPaul A. et à rdanielmurphy. J'avais créé ma propre directive personnalisée pour limiter le champ de saisie au nombre uniquement. Également ajouté les attributs d'entrée max et min. Travaillera dans angular 7 également.
angulaire
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 />
Modèle pour le modèle de numéro de téléphone valide ('^ ((\ + 91 -?) | 0)? [0-9] {10} $')
Modèle permettant d’accepter uniquement les chiffres du modèle de zone de texte ('[0-9] *')
patter pour accepter uniquement le numéro avec un numéro spécifique, par exemple: code PIN. motif ('^ [0-9] {5} $')
J'ai apporté quelques modifications à la directive ci-dessus et implémenté 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();
}
}
}
Créez simplement une directive et ajoutez ci-dessous hostlistener:
@HostListener('input', ['$event'])
onInput(event: Event) {
this.elementRef.nativeElement.value = (<HTMLInputElement>event.currentTarget).value.replace(/[^0-9]/g, '');
}
Remplacer le texte invalide par vide. Toutes les clés et combinaisons de touches fonctionnent désormais sur tous les navigateurs jusqu'à IE9.
Avec le support pour la désinfection du contenu collé:
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();
}
}
}
de la réponse de @omeralper. Je change un peu qui n'acceptera pas les règles ascii (code 110,190). et utilisez let ch = (e.key); pour comparer avec une expression régulière lorsque vous changez de langue (comme le thaï ou le japonais), il n'acceptera pas le caractère de ces langues
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();
}
}
}
espérons que cette aide :)
Vous pouvez créer ce validateur et l'importer dans votre composant.
Valide fondamentalement la chaîne de saisie du formulaire:
Pour l'implémenter dans votre projet:
importer dans votre composant
import { NumberValidator } from '../../validators/number.validator';
inputNumber: ['', [NumberValidator.isInteger]],
(change)="deleteCharIfInvalid()"
à l'entrée, si form.get('inputNumber').hasError('isInteger')
est true
, supprimez le dernier caractère inséré.// 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;
}
}
En voici une simple: directive simple sur l'événement keydown, elle vérifie que la longueur d'une clé est égale à une et que la clé n'est pas un nombre à preventDefault()
et elle ne rend pas ce caractère.
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 />
Limitations: Cela permettra de coller en utilisant une souris de cette façon acceptera les autres caractères. Pour éviter cela, vous pouvez transmettre le modèle en entrée à la directive et à ngOnChage
à cette valeur de modification de modèle en chiffres uniquement:
Comme ci-dessous:
EDIT: Code ajouté pour détecter les changements dans le modèle et mettre à jour la valeur de l'entrée
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" />
Ne serait pas assez simple pour écrire
onlyNumbers(event) {
if(isNaN(event.target.value * 1)) {
console.log("Not a number")
} else {
console.log("Number")
}
}
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();
}
};
}
}
J'ai vu beaucoup de commentaires sur la gestion du copier/coller.
Pour tirer parti de la réponse @omeralper, vous pouvez ajouter un gestionnaire d’événement coller à la directive onlyNumber afin de gérer le copier/coller:
@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();
}
}
Cela permettra uniquement au contenu d'être copié et collé dans la zone de texte UNIQUEMENT s'il s'agit d'un numéro. C'est la solution la plus simple. Changer le contenu du presse-papier pour supprimer les éléments non numériques est beaucoup plus compliqué et pourrait ne pas en valoir la peine.
Pour obtenir du texte collé de IE, vous pouvez utiliser les éléments suivants:
window.clipboardData.getData('Text');
fromCharCode renvoie 'a' lorsque vous appuyez sur le pavé numérique '1', cette méthode doit donc être évitée
(admin: impossible de commenter comme d'habitude)
Si vous utilisez primeng et Angular 6 ou une version ultérieure, il existe le composant p-inputMask. Il empêche le typage alpha ET les valeurs négatives https://www.primefaces.org/primeng/#/inputmask
Pourquoi ne pas utiliser ControlValueAccessor?
https://stackblitz.com/edit/angular-wwo9kt
Vous pouvez écouter l'événement 'input' et il n'est pas nécessaire de vérifier les codes clés. Avec ControlValueAccessor, vous pouvez vous assurer que le modèle est mis à jour correctement.
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);
}
}
}
Utilisez simplement le numéro de type sur votre texte comme ci-dessous:
<input type="number" class="form-control" matInput name="value" placeholder="xxx" (change)="xxx()" formControlName="value">
Ci-dessous, mon code angular qui permet au seul nombre d'entrer et de ne coller que le nombre, pas le texte.
<input id="pId" maxlength="8" minlength="8" type="text" [(ngModel)]="no" formControlName="prefmeno" name="no" class="form-control">
Et dans le fichier ts ajouté dans ngOnIt.
ngOnInit() {
setTimeout(() => {
jQuery('#pId').on('paste keyup', function(e){
jQuery(this).val(document.getElementById('pId').value.replace(/[^\d]/g, ''));
});
}, 2000);
}
J'ai utilisé setTimeout pour le temps d'attente pour charger DOM. Et jquery utilisé avec javascript pour effectuer cette tâche. 'Coller' et 'keyup' sont utilisés pour déclencher coller et entrer dans le champ.