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,
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;
}