I'm creating dynamic input field it will accept all type values. I need to restrict only numbers to be enter.
template:
<tr *ngFor="let item of rowData">
<ng-container *ngFor="let hitem of columnDefs" >
<td *ngIf="!hitem.dropdown; else selectDrop">
<span *ngIf="hitem.edit;else content">
<div *ngIf="editing">
<input [required]="required" [name]="item[hitem.field]" [(ngModel)]="item[hitem.field]" />
</div>
<div *ngIf="!editing">
{{item[hitem.field]}}
</div>
</span>
<ng-template #content>content here... {{item[hitem.field]}} </ng-template>
</td>
<ng-template #selectDrop>
<td>
<select [(ngModel)]="item[hitem.field]">
<option *ngFor="let item of aplAry">{{item}}</option>
</select>
</td>
</ng-template>
</ng-container>
</tr>
data:
mainHead = [{name:'', colspan:1}, {name:'Deatils', colspan:2}]
columnDefs = [
{headerName: 'Make', field: 'make', edit:true },
{headerName: 'Model', field: 'model', dropdown: true },
{headerName: 'Price', field: 'price', edit:true}
];
aplAry = ['Celica','Mondeo','Boxter'];
rowData = [
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxter', price: 72000 }
];
Stackblitz example
Here's a simpler approach using a directive.
export class NumbersOnlyDirective {
@Input('field') field;
constructor(private ngControl: NgControl) { }
@HostListener('input', ['$event']) onInput(event): void {
if (this.field === 'price') {
const value = event.target.value;
this.ngControl.control.setValue(parseFloat(value) || 0);
if (value.slice(-1) === '.' && !value.slice(0, -1).includes('.')) {
event.target.value = value;
}
}
}
}
This directive will only allow decimal numbers to be entered. parseFloat
removes the alphabets and other special characters. I have used || 0
as a fallback in case the field is emptied but if you don't want anything to display, simply use || ''
instead. The if
condition ensures that only one decimal point can be entered unlike when you use type="number"
(type="number"
will also change the ngModel
to a string). The condition is placed after we update the control
value so that if the last entered value is a .
, the ngModel
value will not include the .
while the view will contain it.
Then use this directive in your template like below and pass the field
value so that the this logic will only apply to the price
field.
<input [required]="required" numbersOnly [field]="hitem.field" [name]="item[hitem.field]" [(ngModel)]="item[hitem.field]" />
Here is a working example on StackBlitz.
You can create a custom directive for only number
.
Stackblitz Demo
app.component.html
<input type="text" appOnlynumber/>
onlynumber.directive.ts
import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[appOnlynumber]'
})
export class OnlynumberDirective {
private navigationKeys = [
'Backspace',
'Delete',
'Tab',
'Escape',
'Enter',
'Home',
'End',
'ArrowLeft',
'ArrowRight',
'Clear',
'Copy',
'Paste'
];
inputElement: HTMLElement;
constructor(public el: ElementRef) {
this.inputElement = el.nativeElement;
}
@HostListener('keydown', ['$event'])
onKeyDown(e: KeyboardEvent) {
if (
this.navigationKeys.indexOf(e.key) > -1 || // Allow: navigation keys: backspace, delete, arrows etc.
(e.key === 'a' && e.ctrlKey === true) || // Allow: Ctrl+A
(e.key === 'c' && e.ctrlKey === true) || // Allow: Ctrl+C
(e.key === 'v' && e.ctrlKey === true) || // Allow: Ctrl+V
(e.key === 'x' && e.ctrlKey === true) || // Allow: Ctrl+X
(e.key === 'a' && e.metaKey === true) || // Allow: Cmd+A (Mac)
(e.key === 'c' && e.metaKey === true) || // Allow: Cmd+C (Mac)
(e.key === 'v' && e.metaKey === true) || // Allow: Cmd+V (Mac)
(e.key === 'x' && e.metaKey === true) // Allow: Cmd+X (Mac)
) {
// 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();
}
}
@HostListener('paste', ['$event'])
onPaste(event: ClipboardEvent) {
event.preventDefault();
const pastedInput: string = event.clipboardData
.getData('text/plain')
.replace(/\D/g, ''); // get a digit-only string
document.execCommand('insertText', false, pastedInput);
}
@HostListener('drop', ['$event'])
onDrop(event: DragEvent) {
event.preventDefault();
const textData = event.dataTransfer.getData('text').replace(/\D/g, '');
this.inputElement.focus();
document.execCommand('insertText', false, textData);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With