I want to implement highlight feature of Notepad++ in HTML, where notepad++ highlights selected words if found in the file. I have been able to mimic a bit only where the highlight happens only on a mouse click in the same div.
I want to change it so the highlight happens in div2 when text is selected in div1 and is found in div2, else div2 is same as div1. Also it should work except any mouse click and with multi words.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>highlight matching text</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style>
.found {
color: red;
}
</style>
<script>
function replaceText() {
$("#div1").find(".found").removeClass("found");
var searchword = $("#searchtxt").val();
var custfilter = new RegExp(searchword, "ig");
var repstr = "<span class='found'>" + searchword + "</span>";
if (searchword != "") {
$('#div1').each(function() {
$(this).html($(this).html().replace(custfilter, repstr));
})
}
}
</script>
</head>
<body>
<input type="text" id="searchtxt" placeholder="keyword" />
<input type="button" value="search" onClick="replaceText();" id="highlightButton" />
<p id="div1">I'm here but not here. Not here also. But I'm here too.</p>
<p id="div2"> </p>
</body>
</html>
Try this:
const div1 = document.getElementById("div1"),
div2 = document.getElementById("div2"),
isParent = (obj, parent) => !obj || obj === parent ? obj : isParent(obj.parentNode, parent);
/*
isParent is a short version of:
function isParent(obj, parent)
{
if (!obj || obj === parent)
{
return obj;
}
else
{
return isParent(obj.parentNode, parent);
}
}
*/
div1.addEventListener("click", e =>
{
const sel = document.getSelection();
/*
sel.anchorNode: element the selection started at
sel.focusNode: element the selection ended at
we only accept selection of div1 text
check if both of these elements are children of div1, otherwise exit
*/
if (!isParent(sel.anchorNode, div1) || !isParent(sel.focusNode, div1))
return;
const text = sel.toString() //get selected text
.trim() //trim trailing white spaces
//make it html friendly
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
//make it regex friendly
.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
if (text === "")
return;
div2.innerHTML = div2.innerHTML
//remove old highlightings
.replace(/<mark>([^<]*)?<\/mark>/g, "$1")
// convert selected text into regex,
// search and enclose found strings with <mark></mark>
.replace(new RegExp("(" + text + ")", "gi"), '<mark>$1</mark>'); //add new highlighting
});
/*
second paragraph marks
*/
p:first-child + p mark {
background-color: lightgreen;
}
#div1, #div2
{
border: 1px solid black;
padding: 1em;
}
#div2
{
background-color: #E0E0E0;
margin-top: -1px;
}
<div id="div1">
<p>I'm here but not here. Not here also. But I'm here too. <span>blah</span></p>
</div>
<div id="div2">
<p>But I'm here too. <span>blah</span> <span>blah</span></p>
<p>And also here.</p>
<p>Third paragraph, has "And also here."</p>
</div>
Related
javascript select & highlight text in one of the blocks and highlight the text same time in textarea and div
<div id="preview"></div>
when you select the text in textarea
my goal is when you select text in textarea or div block
show the highlighted text in both books at the same time
here is what need to look
here is my code
function showPreview()
{
var value = $('textarea').val().trim();
value = value.replace("<", "<");
value = value.replace(">", ">");
$('#preview').html(value);
}
::-moz-selection { /* Code for Firefox */
color: red;
background: yellow;
}
::selection {
color: red;
background: yellow;
}
#preview { width:410px;
border: solid 1px #999; padding:5px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea rows="10" cols="50" onInput="showPreview();">
product noun
Save Word
To save this word, you'll need to log in.
Log In
prod·uct | \ ˈprä-(ˌ)dəkt \
Definition of product
1: the number or expression resulting from the multiplication together of two or more numbers or expressions
2a(1): something produced
especially : COMMODITY sense 1
(2): something (such as a service) that is marketed or sold as a commodity
b: something resulting from or necessarily following from a set of conditions
a product of his environment
3: the amount, quantity, or total produced
4: CONJUNCTION sense 5
</textarea>
<br/>
<hr/>
<div id="preview">
</div>
right now highlights only when you select, neet to highlight in both
thank you
let textarea = document.querySelector('textarea');
let target = document.querySelector('#preview');
let plainLine = '\n';
let htmlLine = '<br/>';
let pressed = false;
function textToHtml(text) {
return text.replace(new RegExp(plainLine, 'g'), htmlLine).replace(/\s\s/g, ' ').replace(/^\s/g, ' ');
}
function htmlToText(html) {
html = html.replace(new RegExp(htmlLine, 'g'), plainLine);
return $('<div>').html(html).text();
}
function highlight(text, from, to) {
let mark = text.slice(from, to);
if (mark) mark = `<mark>${mark}</mark>`;
return text.slice(0, from) + mark + text.slice(to);
}
function showPreview() {
let from = textarea.selectionStart;
let to = textarea.selectionEnd;
let content = highlight(textarea.value, from, to);
target.innerHTML = textToHtml(content);
}
$(textarea).on({
mousedown: () => pressed = true,
mouseup: () => pressed = false,
mousemove: () => pressed && showPreview(),
click: () => showPreview(),
blur: () => showPreview()
});
showPreview();
::-moz-selection { /* Code for Firefox */
color: red;
background: yellow;
}
::selection {
color: red;
background: yellow;
}
#preview {
width: 410px;
border: solid 1px #999;
padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea rows="10" cols="50" onInput="showPreview();">
product noun
Save Word
To save this word, you'll need to log in.
Log In
prod·uct | \ ˈprä-(ˌ)dəkt \
Definition of product
1: the number or expression resulting from the multiplication together of two or more numbers or expressions
2a(1): something produced
especially : COMMODITY sense 1
(2): something (such as a service) that is marketed or sold as a commodity
b: something resulting from or necessarily following from a set of conditions
a product of his environment
3: the amount, quantity, or total produced
4: CONJUNCTION sense 5
</textarea>
<br/>
<hr/>
<div id="preview">
</div>
Here is a very basic example:
const preview = document.querySelector("#preview");
function getSelectionText() {
var text = "";
if (window.getSelection) {
text = window.getSelection().toString();
} else if (document.selection && document.selection.type != "Control") {
text = document.selection.createRange().text;
}
return text;
}
document.addEventListener("click", () => {
const selectedText = getSelectionText();
if (selectedText !== "") {
preview.innerHTML = preview.innerHTML.replaceAll(
selectedText,
`<mark>${selectedText}</mark>`
);
}
});
function showPreview() {
let value = document.querySelector("textarea").value.trim();
value = value.replace("<", "<");
value = value.replace(">", ">");
preview.innerHTML = value;
}
::-moz-selection {
/* Code for Firefox */
color: red;
background: yellow;
}
::selection {
color: red;
background: yellow;
}
#preview {
width: 410px;
border: solid 1px #999;
padding: 5px;
}
<textarea rows="10" cols="50" onInput="showPreview();">Lorem ipsum dolor, sit amet consectetur adipisicing elit.</textarea>
<br />
<hr />
<div id="preview"></div>
I am attempting to change the color/bold state of keywords as the user types in a TinyMCE text entry field. Not sure if you need to know TinyMCE to answer this.
Anyway, I have the following defined:
<p class="air-section">
<span class="air-text-entry air-entry" style="display: block; color: #E2E7E9; margin: 5px;" />
</p>
As the user types "This is dangerous ", when the space bar is hit after dangerous the word is looked up and if dangerous is found, ONLY dangerous is set to bold and colored red.
What I have is:
if ($element.hasClass('air-text-entry')) {
let pos = $element.text().lastIndexOf(" ");
if (pos > 0)
pos += 1;
// ?? What to do here
// I've played with:
$element.text().substr(pos).css({'color':'#FFD700', 'font-weight':'bold'})
As you can tell I'm pretty clueless.
Thanks
EDIT
I am currently trying to break the keyword off as a substring and get that to a jQuery object, then change the css of just that text. Not sure if that is doable though.
Here is what I got after some work. Haven't fully tested it, but I think this will work.
let text = $element.text()
text = $element.text().substr(0, pos)
let appliedText = text + "<span class=\'red-text'>" + $element.text().substr(pos) + "</span>";
$element.html(text);
I've not seen TinyMCE, at work so im using notepad on a reception computer.
I've probs got something wrong but this is the first bit:
I need to add something that gets the 'This is dangerous' and wrap it in a span tag, should be able to add the class there.
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<style>
.danger {
color: red;
font: bold;
}
</style>
</head>
<body>
<p class="air-section">
<span class="air-text-entry air-entry danger" style="display: block; color: #E2E7E9; margin: 5px;">This is dangerous</span>
</p>
</body>
<script>
const entry = document.querySelector('.air-entry');
if(entry.textContent.includes('This is dangerous')){
entry.classList.add('danger');
}
</script>
</html>
If you know the words that need to bold and colored then the following code may help you.
I did it before for SQL query writing
Fiddle:
https://jsfiddle.net/qcykvr8j/2/
<textarea name="query_field_one" id="query_field_one" onkeyup="checkName(this)"></textarea>
function checkName(el)
{
if (el.value == "SELECT" ||
el.value == "FROM" ||
el.value == "WHERE" ||
el.value == "LIKE" ||
el.value == "BETWEEN" ||
el.value == "NOT LIKE" ||
el.value == "FALSE" ||
el.value == "NULL" ||
el.value == "TRUE" ||
el.value == "NOT IN")
{
el.style.color='orange'
}
else {
el.style.color='#FFF'
}
}
#query_field_one
{
width: 400px;
height: 150px;
max-width: 400px;
max-height: 150px;
background-color: #444;
color: white;
font-size: 14px;
}
Would this be better?
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<style>
.danger {
color: red;
font: bold;
}
</style>
</head>
<body>
<p class="air-section"> blah blah blah This is dangerous blah blah
</p>
</body>
<script>
const section = document.querySelector('.air-section');
let str = section.innerHTML;
let newstr = str.replace(/This is dangerous/gi, '<span class="air-text-entry air-entry danger" style="display: block; margin: 5px;">This is dangerous</span>');
section.innerHTML = newstr;
</script>
</html>
at this time When text select, The popup show all selected text as in simple format, Like one paragraph. But i want that, the popup should use complete html tag when showing selected text. Like
<li> _ _ _ _</li> <br> <h1> _ _ _ _</h1>etc...
see my code:
const container = document.querySelector('.storypara');
const popupContainer = document.querySelector('.popupContainer');
container.addEventListener('mouseup', (e) => {
const selectedText = window.getSelection().toString();
if (selectedText) {
showPopup(selectedText);
}
});
popupContainer.addEventListener('click', (event) => {
if (event.target.matches('.popupContainer')) {
popupContainer.classList.remove('show');
}
});
function showPopup(selectedText) {
// set the selected text as html inside popup element
document.querySelector('.popup').innerHTML = selectedText;
popupContainer.classList.add('show');
}
body {
margin: 0;
}
.popupContainer {
position: fixed;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.7);
top: 0;
display: none;
align-items: center;
justify-content: center;
color: red;
}
.show {
display: flex;
}
.popup {
background: #fff;
padding: 10px;
border-radius: 3px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
width: 80%;
}
<div class="storypara">
<p><strong>A Bold example Line</strong><br>
Here are some examples of paragraphs. Here are some examples of paragraphs. Here are some examples of paragraphs. Here are some examples of paragraphs. Here are some examples of paragraphs. </p>
<h2>An Unordered HTML List</h2>
<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
<h2>An Ordered HTML List</h2>
<ol>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ol>
<p>Here are some examples of paragraphs. Here are some examples of paragraphs. Here are some examples of paragraphs. Here are some examples of paragraphs. Here are some examples of paragraphs. Here are some examples of paragraphs. </p>
</div>
<div class="popupContainer">
<div class="popup"></div>
</div>
How can i get this plz help me. my main purpose
at this time When text select, The popup show all selected text as in simple format, Like one paragraph. But i want that, the popup should use complete html tag when showing selected text. Like
<li> _ _ _ _</li> <br> <h1> _ _ _ _</h1>etc...
Thanks in advance.
Well, not quite what you want, but a lot closer to what you are asking for. Here it goes:
Update your script to be as follows:
<script>
const container = document.querySelector('.storypara');
const popupContainer = document.querySelector('.popupContainer');
// this method is added
// It gives the text of HTML of selected text :)
function getHTMLOfSelection () {
var range;
if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
return range.htmlText;
}
else if (window.getSelection) {
var selection = window.getSelection();
if (selection.rangeCount > 0) {
range = selection.getRangeAt(0);
var clonedSelection = range.cloneContents();
var div = document.createElement('div');
div.appendChild(clonedSelection);
return div.innerHTML;
}
else {
return '';
}
}
else {
return '';
}
}
container.addEventListener('mouseup', (e) => {
const selectedText = getHTMLOfSelection(); // First get the raw HTML text
if (selectedText) {
//selectedText.split("<").join("<"); // Now replacing the < so that browser don't render it
//selectedText.split(">").join(">"); // Also replacing the > so that browser don't render it
//console.log(selectedText);
showPopup(selectedText); // using the 'xmp' tags around the text, to show the html as it is
}
});
popupContainer.addEventListener('click', (event) => {
if (event.target.matches('.popupContainer')) {
popupContainer.classList.remove('show');
}
});
function showPopup(selectedText) {
// set the selected text as html inside popup element
document.querySelector('.popup').innerHTML = selectedText;
popupContainer.classList.add('show');
}
</script>
I've added a function, which gives you the HTML of the selected text.
This is all you can do to show the HTML to the user. Hope it helps.
Let me know please if it don't work at your end :) Will be happy to help
I get this output while trying to change the color of the string I would like to add in my editor.
The css part is not taken into account. It is added as a simple html. What could be the problem ?
some text <font color="green">ADD THIS VALUE</font> some text and ...
Here are the add functions
function add_str(event) {
event.preventDefault()
var elt = document.getElementById("text_write");
insertAtCursor(elt, "ADD THIS VALUE");
}
function insertAtCursor(myField, myValue) {
myValue = myValue.fontcolor("green");
if (myField.setRangeText) {
myField.setRangeText(myValue)
} else {
document.execCommand('insertText', false, myValue);
}
}
and the html part
<button onmousedown="add_str(event)">
add srting
</button>
<div contenteditable="true" id="text_write" style="height:200px; width:500px; border:2px solid black;">some text some text and ...</div>
Thank you in advance
function add_str(event) {
event.preventDefault()
var coloredstring = "ADD THIS VALUE"
var colorofstring = "green"
var node = document.getElementById("text_write")
var addedstring = '<span style="color:' + colorofstring + '">' + coloredstring + '</span>'
node.innerHTML = node.innerHTML + addedstring
}
<button onmousedown="add_str(event)">
add srting
</button>
<div contenteditable="true" id="text_write" style="height:200px; width:500px; border:2px solid black;">some text some text and ..</div>
font tag no longer works on html5, i did a little hack using a span tag
Here's the code:
function bold() {
var text = document.getElementById("post-body");
var t = text.value.substr(text.selectionStart, text.selectionEnd - text.selectionStart);
var text = '**';
$('#post-body').val(function(_, val) {
return val + text + t + text;
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea name="post-body" id="post-body" rows="20" style="margin-left: 0px; margin-right: 0px; width: 400px;"></textarea>
<div>
<button id="bold" value="**" onclick="bold()">B</button>
</div>
What I am trying to do is similar to how comments on Stack Overflow work: you highlight text in the text box, and click a button. The button then appends and prepends the proper syntax to the text. I am able to apply the proper syntax, but the highlighted text is duplicated.
I know it's because in my code, I have
return val + text + t + text;
where val is all of the text in the textarea, and t is the highlighted text, but I'm not sure how to remove the highlighted text from val and add the new version in the form of t.
Any help would be greatly appreciated.
You can record the text before and after and then return the text before, the selection and the text after.
function bold() {
var text = document.getElementById("post-body");
var t = text.value.substr(text.selectionStart, text.selectionEnd - text.selectionStart);
var before = text.value.slice(0, text.selectionStart);
var after = text.value.slice(text.selectionEnd);
var text = '**';
$('#post-body').val(function(_, val) {
return before + text + t + text + after;
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea name="post-body" id="post-body" rows="20" style="margin-left: 0px; margin-right: 0px; width: 400px;">Select some text here.</textarea>
<div>
<button id="bold" value="**" onclick="bold()">B</button>
</div>