Angular 2 Cursor jump at the end of textbox when changing data

一笑奈何 提交于 2019-12-03 12:36:33

That comes from the fact DefaultValueAccessor writes blindly the element value, if there is a focus or not, selection or not. I had to do deal with such a behavior myself as I was using a form that was auto-saving and I had to override DefaultValueAccessor and create one that was only writing value if it was different (I don't think that would work for you, see below) :

export const DEFAULT_VALUE_ACCESSOR: any = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => DefaultValueAccessor),
    multi: true
};

@Directive({
    selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]",
    host: {"(input)": "onChange($event.target.value)", "(blur)": "onTouched()"},
    providers: [DEFAULT_VALUE_ACCESSOR]
})
export class DefaultValueAccessor implements ControlValueAccessor {
    onChange = (_: any) => {
    };
    onTouched = () => {
    };

    constructor(private _renderer: Renderer, private _elementRef: ElementRef) {
    }

    writeValue(value: any): void {
        const normalizedValue = value == null ? "" : value;
        // line bellow is the only line I added to the original one
        if ((this._elementRef.nativeElement as HTMLInputElement).value !== normalizedValue) 
            this._renderer.setElementProperty(this._elementRef.nativeElement, "value", normalizedValue);
    }

    registerOnChange(fn: (_: any) => void): void {
        this.onChange = fn;
    }

    registerOnTouched(fn: () => void): void {
        this.onTouched = fn;
    }

    setDisabledState(isDisabled: boolean): void {
        this._renderer.setElementProperty(this._elementRef.nativeElement, "disabled", isDisabled);
    }
}

For your case, you might need to deal with input selection :

let start=this.el.nativeElement.selectionStart;
let end = this.el.nativeElement.selectionEnd;
this.model.valueAccessor.writeValue(newVal);
this.el.nativeElement.setSelectionRange(start,end);

Note that it might not be accurate as you are modifying the input...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!