I'm trying to create a comments section that lets users @someone. When the user types @random and then space, I want it to be highlighted. So I've created something that searches and replaces the string, but I then when the html is replaced, it places the cursor at the beginning. Any way to solve this? Any other way of doing something like this?
$('#textarea').keyup(function() {
txt = this.innerText.split(" ")
new_txt = this.innerText
for (var i = txt.length - 1; i >= 0; i--) {
if (txt[i].startsWith('@') == false) {
delete txt[i]
}
}
txt = txt.sort().join(" ").trim().split(" ")
console.log(txt)
if (txt.length > 0 && txt[0] != "") {
for (var i = 0; i < txt.length; i++) {
new_txt = new_txt.replace(txt[i], '<mark>' + txt[i] + '</mark>')
}
$('#my_console_log').text(new_txt)
this.innerHTML = new_txt
}
});
pre {
border: solid black 1px;
}
mark {
background: blue;
color: red;
}
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<title>Test page</title>
<form>
<pre id='textarea' contentEditable='true'></pre>
<div id="my_console_log"></div>
</form>
Here is a simple plugin available which can be useful to you, Download the plugin and edit the file jquery.hashtags.js and remove the condition for #. You can also change the style as per your requirement.
(function($) {
$.fn.hashtags = function() {
$(this).wrap('<div class="jqueryHashtags"><div class="highlighter"></div></div>').unwrap().before('<div class="highlighter"></div>').wrap('<div class="typehead"></div></div>');
$(this).addClass("theSelector");
autosize($(this));
$(this).on("keyup", function() {
var str = $(this).val();
$(this).parent().parent().find(".highlighter").css("width",$(this).css("width"));
str = str.replace(/\n/g, '<br>');
if(!str.match(/(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?#([a-zA-Z0-9]+)/g) && !str.match(/(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?@([a-zA-Z0-9]+)/g) && !str.match(/(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?#([\u0600-\u06FF]+)/g) && !str.match(/(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?@([\u0600-\u06FF]+)/g)) {
// Remove below condition for hashtag.
if(!str.match(/#(([_a-zA-Z0-9]+)|([\u0600-\u06FF]+)|([ㄱ-ㅎㅏ-ㅣ가-힣]+)|([ぁ-んァ-ン]+)|([一-龯]+))#/g)) { //arabic support, CJK support
str = str.replace(/#(([_a-zA-Z0-9]+)|([\u0600-\u06FF]+)|([ㄱ-ㅎㅏ-ㅣ가-힣]+)|([ぁ-んァ-ン]+)|([一-龯]+))/g,'<span class="hashtag">#$1</span>');
}else{
str = str.replace(/#(([_a-zA-Z0-9]+)|([\u0600-\u06FF]+)|([ㄱ-ㅎㅏ-ㅣ가-힣]+)|([ぁ-んァ-ン]+)|([一-龯]+))#(([_a-zA-Z0-9]+)|([\u0600-\u06FF]+)|([ㄱ-ㅎㅏ-ㅣ가-힣]+)|([ぁ-んァ-ン]+)|([一-龯]+))/g,'<span class="hashtag">#$1</span>');
}
// Keep this condition.
if(!str.match(/@(([a-zA-Z0-9]+)|([\u0600-\u06FF]+)|([ㄱ-ㅎㅏ-ㅣ가-힣]+)|([ぁ-んァ-ン]+)|([一-龯]+))@/g)) {
str = str.replace(/@(([a-zA-Z0-9]+)|([\u0600-\u06FF]+)|([ㄱ-ㅎㅏ-ㅣ가-힣]+)|([ぁ-んァ-ン]+)|([一-龯]+))/g,'<span class="hashtag">@$1</span>');
}else{
str = str.replace(/@(([a-zA-Z0-9]+)|([\u0600-\u06FF]+)|([ㄱ-ㅎㅏ-ㅣ가-힣]+)|([ぁ-んァ-ン]+)|([一-龯]+))@(([a-zA-Z0-9]+)|([\u0600-\u06FF]+)|([ㄱ-ㅎㅏ-ㅣ가-힣]+)|([ぁ-んァ-ン]+)|([一-龯]+))/g,'<span class="hashtag">@$1</span>');
}
}
$(this).parent().parent().find(".highlighter").html(str);
});
$(this).parent().prev().on('click', function() {
$(this).parent().find(".theSelector").focus();
});
};
})(jQuery);