I want to be able to let the user wile typing in the text area if he typed a hash-tag followed by one or more character as he type the text get highlighted till he hits space.
The thing is i want to achieve something like Facebook's new hash-tag feature, I've done the logic the coding but still not able to achieve it visually.
The approach i tried is by using Jquery as follows:
<textarea id="txtArea">Here is my #Hash</textarea>
$("#txtArea").onkeyup(function(){
var result = $("#txtArea").match(/ #[\w]+/g);
//result = '#Hash'
});
But i couldn't plete & i don't know where to go from here so any solution, advice, plugin that i could use i'll be very grateful.
I want to be able to let the user wile typing in the text area if he typed a hash-tag followed by one or more character as he type the text get highlighted till he hits space.
The thing is i want to achieve something like Facebook's new hash-tag feature, I've done the logic the coding but still not able to achieve it visually.
The approach i tried is by using Jquery as follows:
<textarea id="txtArea">Here is my #Hash</textarea>
$("#txtArea").onkeyup(function(){
var result = $("#txtArea").match(/ #[\w]+/g);
//result = '#Hash'
});
But i couldn't plete & i don't know where to go from here so any solution, advice, plugin that i could use i'll be very grateful.
Share Improve this question edited Aug 4, 2013 at 21:39 tereško 58.5k25 gold badges100 silver badges150 bronze badges asked Jun 22, 2013 at 21:28 Ibrahim AhmedIbrahim Ahmed 2,3454 gold badges23 silver badges35 bronze badges1 Answer
Reset to default 6I don't believe there is any way to highlight words (other than one single highlight) within a basic textarea
as it does not accept markup, you could turn the textarea
into a small Rich Text editor, but that seems a little overplicated. I would probably go for similar approach to the editor here on SO, and have a preview window below so that you can see what is being marked. You could use something like this, of course you may want to change how it works a little to suit your exact needs. It should at least give you some ideas.
CSS
#preview {
height: 2em;
width: 12em;
border-style: solid;
border-width: 1px;
}
.hashSymbol {
color: #f90;
}
HTML
<textarea id="userInput"></textarea>
<div id="preview"></div>
Javascript
/*jslint maxerr: 50, indent: 4, browser: true */
(function () {
"use strict";
function walkTheDOM(node, func) {
func(node);
node = node.firstChild;
while (node) {
walkTheDOM(node, func);
node = node.nextSibling;
}
}
function getTextNodes(element) {
var nodes = [];
walkTheDOM(element, function (node) {
if (node.nodeType === 3) {
nodes.push(node);
}
});
return nodes;
}
function escapeRegex(string) {
return string.replace(/[\[\](){}?*+\^$\\.|]/g, "\\$&");
}
function highlight(element, string, classname) {
var nodes = getTextNodes(element),
length = nodes.length,
stringLength = string.length,
rx = new RegExp("\\B" + escapeRegex(string)),
i = 0,
index,
text,
newContent,
span,
node;
while (i < length) {
node = nodes[i];
newContent = document.createDocumentFragment();
text = node.nodeValue;
index = text.search(rx);
while (index !== -1) {
newContent.appendChild(document.createTextNode(text.slice(0, index)));
text = text.slice(index + stringLength);
span = document.createElement("span");
span.className = classname;
span.appendChild(document.createTextNode(string));
newContent.appendChild(span);
index = text.search(rx);
}
newContent.appendChild(document.createTextNode(text));
node.parentNode.replaceChild(newContent, node);
i += 1;
}
}
function addEvent(elem, event, fn) {
if (typeof elem === "string") {
elem = document.getElementById(elem);
}
function listenHandler(e) {
var ret = fn.apply(null, arguments);
if (ret === false) {
e.stopPropagation();
e.preventDefault();
}
return ret;
}
function attachHandler() {
window.event.target = window.event.srcElement;
var ret = fn.call(elem, window.event);
if (ret === false) {
window.event.returnValue = false;
window.event.cancelBubble = true;
}
return ret;
}
if (elem.addEventListener) {
elem.addEventListener(event, listenHandler, false);
} else {
elem.attachEvent("on" + event, attachHandler);
}
}
function emptyNode(node) {
while (node.firstChild) {
node.removeChild(node.firstChild);
}
}
function toPreviewHighlight(e, to) {
if (typeof to === "string") {
to = document.getElementById(to);
}
var value = e.target.value,
tags = value.match(/\B#\w+/g) || [],
index = tags.length - 1,
lookup = {},
fragment,
length,
tag;
while (index >= 0) {
tag = tags[index];
if (!tag.length || tag === "#" || tag.charAt(0) !== "#" || lookup[tag]) {
tags.splice(index, 1);
} else {
lookup[tag] = true;
}
index -= 1;
}
fragment = document.createDocumentFragment();
fragment.appendChild(document.createTextNode(value));
index = 0;
length = tags.length;
while (index < length) {
tag = tags[index];
highlight(fragment, tag, "hashSymbol");
index += 1;
}
emptyNode(to);
to.appendChild(fragment);
}
addEvent("userInput", "keyup", function (e) {
toPreviewHighlight(e, "preview");
});
}());
On jsfiddle
This code is slightly modified from other questions and answers here on SO (resusing code is good)
if text contains '@' change color of '@'
How to extract value between # and space in textarea value
Using JavaScript, I want to use XPath to look for the presence of a string, then refresh the page based on that