What have others done for a 4 digit pin? I am looking to make a 4 digit pin in Angular 2/4 but there seems to be no easy way to do it, that I have found out yet.
Phones do have a soft keyboard
that can show only numbers. The best way (only way) to show a number keyboard on both android and ios is with the following html tag:
<input
type="number"
pattern="[0-9]*"
inputmode="numeric"
style="-webkit-text-security: disc;"></input>
Now that gives me a keyboard that has decimals, dashes, commas, among other things. I need to make sure only numbers are put in the box. The best way I can think of is catch key press events and remove invalid characters as they are typed. There are 3 different ways I have tried and all have flaws: First is catch the keyup event:
The Html:
<input
(keyup)="checkPin($event)"
type="number"
pattern="[0-9]*"
inputmode="numeric"
style="-webkit-text-security: disc;"></input>
The Typescript:
checkPin($event: KeyboardEvent) {
console.log($event)
let value = (<HTMLInputElement>event.target).value;
if ($event.target) {
if (value == "") {
value = value.slice(0, 0);
}
if (value.length > 4) {
value = value.slice(0, 4)
}
(<HTMLInputElement>event.target).value = value.replace(/\D/g, '');
}
}
I do not like this because code because as the key is pushed it can be seen in the box then disappears.
The second approach is to catch the keypress
event:
The HTML:
<input
(keypress)="keyPress($event)"
type="number"
pattern="[0-9]*"
inputmode="numeric"
style="-webkit-text-security: disc;"></input>
The Type Script
keyPress(event: any) {
const pattern = /[0-9]/;
const inputChar = String.fromCharCode(event.charCode);
let lIsTooLong: boolean = event.target.value.length > 3
if (!pattern.test(inputChar) || lIsTooLong) {
// invalid character, prevent input
event.preventDefault();
}
}
This works very well, but it does not work on android when the period or comma is pushed, the period is still put into the input box.
I tried using input
:
The HTML:
<input
#myInput
[(ngModel)]="input"
(input)="myInput.value = format(input)"
type="number"
pattern="[0-9]*"
inputmode="numeric"
style="-webkit-text-security: disc;"></input>
The Type Script:
format(valString) {
console.log(valString);
if (!valString) {
return '';
}
let val = valString.toString();
if (val.length > 4) {
val = val.slice(0, 4)
}
return val.replace(/\D+/g, '')
}
This last way seemed promising but when more than two .
were entered the code actually broke and stopped calling the format function. I did a console log and the value valString
was and empty string, but the text in the box was 123423.........
UPDATE :
There is an easier way. Using what you originaly used, keyup event:
HTML :
<input type="number" style="border:1px solid black" (keydown)="onKeyPress($event)" >
Typescript :
onKeyPress(event){
if (!(event.keyCode >= 48 && event.keyCode <= 57)){
event.preventDefault()
}
}
The input could be processed thru (input) event where you remove anything not numeric with a regexp. But this method will need two-way binding mechanism. Example:
HTML :
<input type="number" [(ngModel)]="input" #myInput style="border:1px solid black" (input)="myInput.value = format(input)">
Typescript :
format(valString) {
if (!valString) {
return '';
}
let val = valString.toString();
return val.replace(/\D+/g, '');
}
What you're trying to do is best done using a custom directive
The following steps should help you solve your problem:
Generate a new custom directive: ng generate directive numberInput
Then in the generated directive class add this:
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[appnumberInput]'
})
export class NumberInputDirective {
constructor(private el: ElementRef) { }
@Input() digitOnly: 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();
}
}
@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);
}
}
}
Then within your template add:
<input type="text" name="pin" id="pin" placeholder="000" maxlength="4" inputmode="numeric" pattern="[0-9]*" digitOnly>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.