2

I am using the contentEditable attribute of Angular 6 for editing the content of the element (in the ngFor)

How I can set focus on a tag element when it's contentEditable attribute is true?

<div class="tag" *ngFor="let tag of tags">
   <span [contentEditable]="underUpdateTagId==tag.id" [textContent]="tag.title 
    (input)="tag.title=$event.target.textContent">
   </span>
   <span *ngIf="underUpdateTagId!=tag.id" class="edit text-info" (click)="beforeEdit(tag)">
         <i class="fas fa-pencil-alt"></i>
   </span>
   <span *ngIf="underUpdateTagId==tag.id" class="update text-success" (click)="editTag(tag)">
         <i class="fas fa-check save"></i>
   </span>
   <span class="delete text-danger" (click)="delete(tag)">
         <i class="fas fa-trash-alt"></i>
   </span>
</div>

The user interface:

enter image description here

Farzaneh Torkpichlou
  • 2,306
  • 3
  • 14
  • 18

1 Answers1

3

We can use ViewChildren to get a hold of all the spans, by placing a template reference, pick up the span that is selected and set the focus to the element.

So I suggest adding template reference and in your beforeEdit() pass the index of the tag (we get it from ngFor), so we can refer to it when we want to place the focus on the field:

<!-- add template reference in below span tag --->
<span [contentEditable]="underUpdateTagId==tag.id" ... #spans>
<!-- pass index as from ngFor iteration to beforeEdit() -->
<span *ngIf="underUpdateTagId!=tag.id" class="edit text-info" (click)="beforeEdit(tag, i)">
<!-- more code --->

In the component we refer to spans, the template reference. And when clicked upon specify that the span with the index passed should be focused:

@ViewChildren("spans") spans: QueryList<ElementRef>;
underUpdateTagId = null;

beforeEdit(tag, index) {
  this.underUpdateTagId = tag.id;
  // wait a tick
  setTimeout(() => {
    this.spans.toArray()[index].nativeElement.focus();
  });
}

STACKBLITZ

PS, this sets the focus in the beginning, you might want it at the end, maybe this question can help you with it if that is the case: Use JavaScript to place cursor at end of text in text input element

AT82
  • 71,416
  • 24
  • 140
  • 167