I have a spell check solution that uses a content editable div
and inserts span
tags around words that are misspelled. Every time the inner html of the div
is updated, the cursor moves to the beginning of the div
.
I know I can move the cursor to the end of the div
if the user adds new words to the end of the sentence (code below).
Old Text: This is a spell checker|
New Text: This is a spell checker soluuution|
var range = document.createRange();
range.selectNodeContents(element[0]);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
However, I am unable to retain the cursor position if the user adds words in the middle of a sentence.
Old Text: This is a spell checker
New Text: This is a new spell checker|
In the above case, the cursor goes to the end of the div
when it should be after "new".
How do I retain the cursor position? Since I am updating the html and adding nodes, saving the range before the update and adding it to the selection object isn't working.
Thanks in advance.
As far as I know, changing the content of the div will always have problem.
So here is the solution that I came with. Please type error word such as helloo, dudeee
This should ideally work for textarea as well.
Solution details:
// some mock logic to identify spelling error
const errorWords = ["helloo", "dudeee"];
// Find words from string like ' Helloo world .. '
// Perhaps you could find a better library you that does this logic.
const getWords = (data) =>{
console.log("Input: ", data);
const allWords = data.split(/\b/);
console.log("Output: ", allWords)
return allWords;
}
// Simple mock logic to identify errors. Now works only for
// two words [ 'helloo', 'dudeee']
const containsSpellingError = word => {
const found = errorWords.indexOf(word) !== -1;
console.log("spell check:", word, found);
return found;
}
const processSpellCheck = text => {
const allWords = getWords(text);
console.log("Words in the string: ", allWords);
const newContent = allWords.map((word, index) => {
var text = word;
if(containsSpellingError(word.toLowerCase())) {
console.log("Error word found", word);
text = $("<span />")
.addClass("spell-error")
.text(word);
}
return text;
});
return newContent;
}
function initalizeSpellcheck(editorRef) {
var editorSize = editorRef.getBoundingClientRect();
var spellcheckContainer = $("<div />", {})
.addClass("spell-check")
.prop("spellcheck", "false");
var spellcheckSpan = $("<span />")
.addClass("spell-check-text-content")
.css({
width: editorSize.width,
height: editorSize.height,
position: "absolute",
zIndex: -1
});
var text = $(editorRef).text();
var newContent = processSpellCheck(text);
spellcheckSpan.append(newContent);
spellcheckContainer.append(spellcheckSpan);
spellcheckContainer.insertBefore(editorRef);
$(editorRef).on("input.spellcheck", function(event) {
var newText = $(event.target).text();
var newContent = processSpellCheck(newText);
$(".spell-check .spell-check-text-content").text("");
$(".spell-check .spell-check-text-content").append(newContent);
});
}
$(document).ready(function() {
var editor = document.querySelector("#editor");
initalizeSpellcheck(editor);
});
#editor {
border: 1px solid black;
height: 200px;
}
.spell-check {
color: transparent;
}
.spell-error {
border-bottom: 3px solid orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="editor" contenteditable="true" spellcheck="false">
dudeee
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With