I have following code, idea is to change input value to different language and show it in the input. It works fine, but as soon an you place cursor in the middle of the text for example and type something there cusror jumps to the end again.
So far I have this:
<mat-form-field *ngIf="operationType != 'joint'"
[ngClass]="{'inputBIG uniqueStander':item?.person?.factualAddress?.length > 50, 'inputBIG':!item?.person?.factualAddress?.length > 50}"
class="inputBIG" appearance="outline">
<mat-label>მისამართი</mat-label>
<input autocomplete="off" autocomplete="off" matInput placeholder=""
[(ngModel)]="dataaa" name="address" [maxlength]="maxFactAddress"
(keyup)="iReplaceToGEO('firstAddr')" id="firstAddr">
</mat-form-field>
and typescript as well:
dataaa: any;
public iReplaceToGEO(position?): void {
console.log('position', position);
if (position) {
this.getCaretPosition(position);
}
this.dataaa = replacer(this.dataaa);
if (position) {
this.setCaretPosition(position, this.caretPos, this.caretPos);
}
function replacer(val): string {
val = val
.replace(/a/g, 'ა')
.replace(/b/g, 'ბ')
.replace(/c/g, 'ც')
.replace(/d/g, 'დ')
.replace(/e/g, 'ე')
.replace(/f/g, 'ფ')
.replace(/g/g, 'გ')
.replace(/h/g, 'ჰ')
.replace(/i/g, 'ი')
.replace(/j/g, 'ჯ')
.replace(/k/g, 'კ')
.replace(/l/g, 'ლ')
.replace(/m/g, 'მ')
.replace(/n/g, 'ნ')
.replace(/o/g, 'ო')
.replace(/p/g, 'პ')
.replace(/q/g, 'ქ')
.replace(/r/g, 'რ')
.replace(/s/g, 'ს')
.replace(/t/g, 'ტ')
.replace(/u/g, 'უ')
.replace(/v/g, 'ვ')
.replace(/w/g, 'წ')
.replace(/x/g, 'ხ')
.replace(/y/g, 'ყ')
.replace(/z/g, 'ზ')
.replace(/J/g, 'ჟ')
.replace(/T/g, 'თ')
.replace(/R/g, 'ღ')
.replace(/S/g, 'შ')
.replace(/C/g, 'ჩ')
.replace(/Z/g, 'ძ')
.replace(/W/g, 'ჭ');
return val;
}
}
caretPos: number = 0;
public getCaretPosition(ctrl) {
let arr: any = document.getElementById(ctrl);
console.log('getCaretPosition', arr.selectionStart);
if (arr.selectionStart || arr.selectionStart == '0') {
this.caretPos = arr.selectionStart;
return {
start: arr.selectionStart,
end: arr.selectionEnd,
};
} else {
this.caretPos = 0;
return {
start: 0,
end: 0,
};
}
}
public setCaretPosition(ctrl, start, end) {
let arr: any = document.getElementById(ctrl);
console.log('setCaretPosition', arr.setSelectionRange);
console.log('start', start);
console.log('end', end);
if (arr.setSelectionRange) {
arr.focus();
arr.setSelectionRange(start, end);
} else if (arr.createTextRange) {
var range = arr.createTextRange();
range.collapse(true);
range.moveEnd('character', end);
range.moveStart('character', start);
range.select();
}
this.caretPos = this.caretPos + 1;
}
You can also check stackblitz example: https://stackblitz.com/edit/angular-material-mat-form-fields-kpryeu?file=src%2Fapp%2Fapp.component.html,src%2Fapp%2Fapp.component.ts
It's because yo need "wait" to Angular redraw the value before position the cursor.
I simply a bit your code
public iReplaceToGEO(event:any,name:string): void {
const item=event.target;
const pos = item.selectionStart;
const value = item.value;
this[name]=this.replacer(value);
setTimeout(()=>{
item.selectionStart=item.selectionEnd=pos;
})
}
Where you define your function replacer outside the function:
replacer(val:string): string {
return val
.replace(/a/g, 'ა')
.replace(/b/g, 'ბ')
...
}
You use not using (keyup) else (input) event
<input matInput ...
[(ngModel)]="dataaa"
(input)="iReplaceToGEO($event,'dataaa')" >
Your forked stackblitz
NOTE: If you use Reactive Forms you should use form.get(name).setValue(this.replacer(value))
instead of this[name]=this.replacer(value);
NOTE2: using (input) work also CTRL+V