Autocomplete content in contenteditable div at the caret position
The following demo shows how to use autocomplete content in contenteditable div at the caret position
by jarosciak
HTML
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<div id="textentry" contenteditable="true">
</div>
Try to type: ActionScript, AppleScript or ColdFusion<br>
Use: TAB to use the suggestion
</body>
</html>
CSS
div#textentry {
width: 650px;
height: 100px;
max-height: 100px;
border: 2px solid #cccccc;
padding: 5px;
background-color: #ffffff;
font-size: 16px;
color: #000000;
}
span#hint {
color: #000000;
}
JavaScript
document.getElementById('textentry').focus();
var availableTags = [
"ActionScript",
"ActionCrypt",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Perl",
"PHP",
"Python",
"Ruby",
"Scala",
"Scheme"
];
$("#textentry").keyup(function(e) {
var code = e.keyCode || e.which;
textEntryContent = document.getElementById("textentry").innerText;
lastWord = getLastWord(textEntryContent);
console.log(lastWord);
// WIRE INTO DB or ARRAY for Suggestions
availableTags.forEach(function(element) {
if (lastWord.length>=3) {
if (element.toLowerCase().startsWith(lastWord.toLowerCase()) === true) {
pasteHtmlAtCaret("<span id='hint'>" + element.substr(lastWord.length, element.length));
}
}
if ((e.which == '32') || (e.which == '8')) {
replaceSelectionWithHtml(" ");
}
});
});
$("#textentry").keydown(function(e) {
var code = e.keyCode || e.which;
if (code == '9') {
e.preventDefault();
placeCaretAtEnd(document.getElementById("textentry"));
pasteHtmlAtCaret (' ');
return false;
}
});
function pasteHtmlAtCaret(html) {
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
// Range.createContextualFragment() would be useful here but is
// only relatively recently standardized and is not supported in
// some browsers (IE9, for one)
var el = document.createElement("div");
el.innerHTML = html;
var frag = document.createDocumentFragment(),
node, lastNode;
while ((node = el.firstChild)) {
lastNode = frag.appendChild(node);
}
var firstNode = frag.firstChild;
range.insertNode(frag);
...