1

I have a contenteditable that I am using for a chat application. When I tag a user, I find the current caretPosition and add a span to that location which is like this;

<span class=\"highlight\" contenteditable=\"false\">${userName}</span> 

When I replace the tag with this span however, I lose focus of the contenteditable and the caret position is lost. I've tried looking at these answers,

Answer 1 Answer 2

but in both cases focus is lost, and if I set el.focus() before the setCursorPosition function, the caret just goes to the beginning of the contenteditable. my code;

getCaretPositionInnerHTML() {
   var target = document.createTextNode("\u0001");
   document.getSelection().getRangeAt(0).insertNode(target);
   var position = this.contenteditable.nativeElement.innerHTML.indexOf("\u0001");
   target.parentNode.removeChild(target);
   return position;
}

saveMention(event, user): void { //lose focus after this
   event.stopPropagation();
   let tempString = this.contenteditable.nativeElement.innerHTML;
   let index = this.getCaretPositionInnerHTML();
   let replacement = this.getSpanFromUserFn(user);// returns the span in question
   let currentWordLength = this.getCurrentWord(tempString, index);// replace the current word with my span
   let newString = tempString.substring(0, index - currentWordLength.length) + replacement + tempString.substring(index + 1);
   this.contenteditable.nativeElement.innerHTML = newString;
}

ngOnChanges(changes: SimpleChanges) {
if (this.caretPosition) {
  console.log(changes);
  this.selection.removeAllRanges();
  let range = this.setCursorPosition(this.element.nativeElement, document.createRange(), {  pos: this.caretPosition, done: false});
  this.element.nativeElement.focus();
  range.collapse(true);
  this.sel.addRange(range);
}

//find the child node and relative position and set it on range
setCursorPosition(parent, range, stat) {
if (stat.done) return range;
if (parent.childNodes.length == 0) {
if (parent.textContent.length >= stat.pos) {
  range.setStart(parent, stat.pos);
  stat.done = true;
} else {
  stat.pos = stat.pos - parent.textContent.length;
}
} else {
for (var i = 0; i < parent.childNodes.length && !stat.done; i++) {
  this.currentNode = parent.childNodes[i];
  this.setCursorPosition(this.currentNode, range, stat);
}
}
return range;
}
Steve Chacko
  • 95
  • 11

0 Answers0