mat.hudak
mat.hudak

Reputation: 3193

Angular - How to set caret position in textarea

I thought this would be an easy thing to do and I realized I have no idea how to do it. I have a dialog with textarea where multiline text can be edited. The idea is, when you open this dialog and there is already some text, set the caret to the text start. So I guess it would be position 0

First I tried to set it in HTML, but it doesn't work

<textarea
  matInput
  #textArea
  id="editExperimentTitleInput"
  [placeholder]="'experiment.title.placeholder' | translate"
  [(ngModel)]="title"
  autocomplete="off"
  spellcheck="false"
  [selectionStart]="0"
  [selectionEnd]="0"
  rows="10"
></textarea>

This doesn't work either

@ViewChild('textArea') _textArea: ElementRef;

ngAfterViewInit(): void {
  const textArea = this._textArea.nativeElement as HTMLTextAreaElement;
  textArea.setSelectionRange(0, 0);
  //textArea.focus() // Throws expresion changed after....
}

What am I missing?

Upvotes: 2

Views: 6323

Answers (1)

Felix
Felix

Reputation: 1566

Focussing elements in Angular is often a difficult thing to implement. Although, it looks like your code is working when using a FormControl instead of ngModel (working stackblitz):

Template:

<textarea #textArea [formControl]="formControl"></textarea>

Component:

@ViewChild('textArea') _textArea: ElementRef;

formControl = new FormControl(this.title);

ngAfterViewInit(): void {
  const textArea = this._textArea.nativeElement as HTMLTextAreaElement;
  textArea.focus()
  textArea.setSelectionRange(0, 0);
}

Module (add ReactiveFormsModule to imports if not present yet):

@NgModule({
  imports: [ BrowserModule, FormsModule, ReactiveFormsModule ]
})

You'll definitely need the focus() cause setSelectionRange only sets the cursor and wont have much use without focus.

Upvotes: 5

Related Questions