import { Directive, ElementRef, forwardRef, HostListener, Renderer2, Self } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Directive({
selector: '[foDigitsOnly]',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DigitsOnlyDirective),
multi: true,
},
],
})
export class DigitsOnlyDirective implements ControlValueAccessor {
/** implements ControlValueAccessorInterface */
_onChange: (_: any) => void;
/** implements ControlValueAccessorInterface */
_touched: () => void;
private onlyDigitsRegexp: RegExp = new RegExp(/^-?[0-9]+(\.[0-9]*)?$/g);
private specialKeys: string[] = ['Backspace', 'Delete', 'Enter', 'End', 'Home', 'ArrowRight', 'ArrowLeft'];
constructor(@Self() private _el: ElementRef, private _renderer: Renderer2) {
}
@HostListener('keydown', ['$event'])
public onKeyDown(event: KeyboardEvent): void {
if (
this.specialKeys.indexOf(event.key) !== -1
|| event.ctrlKey === true
|| event.metaKey === true
|| event.key && event.key.toLowerCase() === 'insert'
) {
return;
}
const currentValue: string = this._el.nativeElement.value;
let position: number = this._el.nativeElement.selectionStart;
let nextValue: string = [currentValue.slice(0, position), event.key, currentValue.slice(position)].join('');
if (nextValue && nextValue.match(this.onlyDigitsRegexp)) {
this.updateValue(nextValue);
}
event.preventDefault()
}
@HostListener('paste', ['$event'])
onPaste(event: ClipboardEvent) {
event.preventDefault();
const value = event.clipboardData
.getData('text/plain')
.replace(/\D/g, '');
this.updateValue(value);
}
@HostListener('drop', ['$event'])
onDrop(event: DragEvent) {
event.preventDefault();
const value = event.dataTransfer
.getData('text')
.replace(/\D/g, '');
this.updateValue(value);
this._el.nativeElement.focus();
}
@HostListener('input', ['$event'])
onInput(event: any) {
event.preventDefault();
const value = event.target.value
.replace(/\D/g, '');
this.updateValue(value);
this._el.nativeElement.focus();
}
@HostListener('blur')
onBlur(): void {
this._touched && this._touched();
}
/** Implementation for ControlValueAccessor interface */
writeValue(value: any): void {
this._renderer.setProperty(this._el.nativeElement, 'value', value);
}
/** Implementation for ControlValueAccessor interface */
registerOnChange(fn: (_: any) => void): void {
this._onChange = fn;
}
/** Implementation for ControlValueAccessor interface */
registerOnTouched(fn: () => void): void {
this._touched = fn;
}
private updateValue(value: any): void {
this.writeValue(value);
this._onChange && this._onChange(value);
}
}
Всем здравствуйте. Написала свою кастомную директиву. Ситуация такая: ввожу сначала какое-либо значение, например 1111, потом ставлю курсор между второй и третьей единей, ввожу 2, хочу ввести 22, но при вводе второй двойки курсор перескакивает в самый конец.