Issue
I have a textarea and a dropdown. When I select a value in the dropdown
the particular value will appear or get inserted or added to the text area . So after typing dear if a user selects
a dropdown value called name it should appear as a dear name in the text area. I have done it but there is a bug
The dropdown value gets patched based on the maximum postion the cursor went instead
of the current cursor position. say for example you type three words and you place the cursor
near the first word and select a dropdown value the value gets patched on the en of third word(maximum position) instead
of the current cursor position
I want the dropdown value to be patched on current cursor position
HTML:
<textarea [(ngModel)]='textValue' rows="10" cols="70">
</textarea>
<div>
<mat-form-field class="input-style">
<mat-select (change)="changeValue($event)">
<mat-option *ngFor="let li of list4" [value]="li">
{{li}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
Ts:
changeValue(ev) {
this.textValue += ` ${ev.value}`; }
Kindly help if you guys know
Stackblitz: https://stackblitz.com/edit/angular-mat-form-field-rjr5tu?file=app%2Fform-field-prefix-suffix-example.html
Solution
you need take account the "selectionStart" and selectionEnd of the textArea. For this, create a template reference variable and pass to the function
<!--see the #text-->
<textarea #text [(ngModel)]='textValue' rows="10" cols="70">
</textarea>
...
<!--pass the "variable" to the function changeValue-->
<mat-select (change)="changeValue($event,text)">
...
</mat-select>
Then your function changeValue
changeValue(ev,textArea:any) {
const posInitial=textArea.selectionStart;
const posFinal=textArea.selectionEnd;
this.textValue = this.textValue.substr(0,posInitial)+
ev.value+
this.textValue.substr(posFinal);
}
NOTE: If you don’t want pass the "text" to the function you can also use ViewChild
@ViewChild("text") textArea:ElementRef
And to get the positions using
const posInitial=this.textArea.nativeElement.selectionStart;
const posFinal=this.textArea.nativeElement.selectionEnd;
See that in this case you use this.textArea.ElementRef