JSFiddle - React, Tailwind, and code Playground
HTML
<script src="http://rangy.googlecode.com/svn/trunk/currentrelease/rangy-core.js"></script>
<div id="testDiv" contentEditable="true">
Hey <input id="user-tag-1" class="ut ut-full-name" carpos="9" type="button" data-sbxm="1" data-token-entity="@105007387119845225544" oid="105007387119845225544" tabindex="-1" value="Michael Stefanko"/>, this might just work.
</div>
<div id="navigation">
<button id="set-before">Set Caret Before Tag</button>
<button id="set-after">Set Caret After Tag</button>
<button id="set-beginning">Set Caret At Beginning</button>
<button id="set-end">Set Caret At End</button>
<button id="add-tag">Add Tag</button>
</div>
<div id="caretPosition">
<span id="ctitle">Current Position:</span>
<span id="cpos"></span>
</div>
<div id="staging"></div>
CSS
#testDiv {
height: 100px;
width: 500px;
border: 1px solid #C8C8C8;
padding: 10px;
background: #FFFFFF;
}
#caretPosition {
float:left;
margin-top:10px;
font-weight: bold;
font-size: 20px;
}
#navigation {
float:left;
width: 200px;
}
button {
margin-top: 10px;
padding: 5px;
display:block;
}
.ut {
background: none repeat scroll 0 0 #EEEEEE;
border: 1px solid #DDDDDD;
border-radius: 2px 2px 2px 2px;
color: #427FED;
display: inline-block;
font: 13px/1.4 Roboto,arial,sans-serif;
margin: 0 1px;
padding: 0 1px;
vertical-align: baseline;
white-space: nowrap;
}
JavaScript
$('#testDiv').on('click', function(){
$('#cpos').html(getCaretPosition($('#testDiv')[0]));
});
var tags = [
"example.com"
,"akamai.com"
,"2charts.com"
,"gmail.com"
,"jquery.com"
,"yahoo.com"
,"ymail.com"
,"hotmail.com"
];
var startTyping = "Start Typing";
function placeCaretAtEnd(el) {
el.focus();
if (typeof window.getSelection != "undefined"
&& typeof document.createRange != "undefined") {
var range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.body.createTextRange != "undefined") {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(false);
textRange.select();
}
}
function split( val ) {
return val.split( /@/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$("#testDiv")
.bind("keydown", function (event) {
if (event.keyCode === $.ui.keyCode.TAB && $(this).data("autocomplete").menu.active) {
event.preventDefault();
}
})
.autocomplete({
minLength: 0,
source: function (request, response) {
var query = request.term,
position = getCaretPosition($('#testDiv')[0]),
regex = new RegExp("(^|\\s)(['@'][\\w-]*)$"),
results = [];
query = query.substring(0, position);
var result = regex.exec(query);
if(result && result[2]){
result = result[2].trim().toLowerCase().substring(1);
results = $.ui.autocomplete.filter(tags, result);
}
response(results);
},
focus: function () {
return false;
},
select: function (event, ui) {
if (ui.item.value...