How to highlight all links containing keywords from array using JavaScript - javascript

I'm searching a web page for keywords from an array. This code works by replacing text with a tag which highlights the text, but when it finds keywords that are links then it breaks them because it puts a <span> tag within the <a> tag.
I tried to refer to the parent element by changing $this.html() to $this.parent.html() but this didn't work. Here's the JSFiddle: https://jsfiddle.net/uzfsjqyr/1/
I'd appreciate some help, please?
var regex = /(Apples|oranges)/g;
$('*').each(function() {
var $this = $(this);
var text = $this.text();
if (regex.test(text)) {
$this.html(
$this.html().replace(regex, '</a><span style="background: #fa7373;">$1</span>')
);
}
});

You should be selecting all p and a tags in the body instead of using * which will even select the script tag itself. Also, remove the </a> that is closing any anchor tag. To not modify the HTML of anchor tags, you can check that the current element has no children before replacing.
var regex = /(apples|oranges)/g;
$('body a, body p').each(function() {
var $this = $(this);
var text = $this.text();
if (text.match(regex) && $this.children().length===0) {
$this.html(
$this.html().replace(regex, '<span style="background: #fa7373;">$1</span>')
);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>
I bought some apples.
</p>
<p>
I bought some oranges.
</p>
<p>
I bought some pears.
</p>

Remove </a> from your code. This </a> is closing any anchor tag.
var regex = /(apples|oranges)/g;
$('*').each(function() {
var $this = $(this);
var text = $this.text();
if (regex.test(text)) {
$this.html(
$this.html().replace(regex, '<mark>$1</mark>')
);
}
});

Related

Paste MS Word as Text but keep some styling Jquery

My customer wants a UI that he will copy some text from MS Word and paste. After he pastes, my script should delete all the styling and tags of Word, but keep paragraphs (html p tags) and bold styling (html b tag).
I've prepared a UI with html5 contenteditable, there are many editable sections with different kind of content (headers, 1 and 2 column paragraphs etc.)
I've found a script that working well, doing exact the same thing I want. But if I want to use different selector (the script uses #content selector), it does not work. I want to use a class, since many sections with .editable_div class can be added to UI.
Maybe it's because I'm not so good at JS and Jquery. The script is below, how can I make it work with many sections with a class name on the page?
Thanks so much...
Index.html:
<!DOCTYPE html>
<html>
<body>
<div id="src">Source here...</div>
<div id="editor" contenteditable="true">
<p>Place MS-Word text here...</p>
</div>
</body>
</html>
and script:
(function($) {
$.fn.msword_html_filter = function(options) {
var settings = $.extend( {}, options);
function word_filter(editor){
var content = editor.html();
// Word comments like conditional comments etc
content = content.replace(/<!--[\s\S]+?-->/gi, '');
// Remove comments, scripts (e.g., msoShowComment), XML tag, VML content,
// MS Office namespaced tags, and a few other tags
content = content.replace(/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi, '');
// Convert <s> into <strike> for line-though
content = content.replace(/<(\/?)s>/gi, "<$1strike>");
// Replace nbsp entites to char since it's easier to handle
//content = content.replace(/ /gi, "\u00a0");
content = content.replace(/ /gi, ' ');
// Convert <span style="mso-spacerun:yes">___</span> to string of alternating
// breaking/non-breaking spaces of same length
content = content.replace(/<span\s+style\s*=\s*"\s*mso-spacerun\s*:\s*yes\s*;?\s*"\s*>([\s\u00a0]*)<\/span>/gi, function(str, spaces) {
return (spaces.length > 0) ? spaces.replace(/./, " ").slice(Math.floor(spaces.length/2)).split("").join("\u00a0") : '';
});
editor.html(content);
// Parse out list indent level for lists
$('p', editor).each(function(){
var str = $(this).attr('style');
var matches = /mso-list:\w+ \w+([0-9]+)/.exec(str);
if (matches) {
$(this).data('_listLevel', parseInt(matches[1], 10));
}
});
// Parse Lists
var last_level=0;
var pnt = null;
$('p', editor).each(function(){
var cur_level = $(this).data('_listLevel');
if(cur_level != undefined){
var txt = $(this).text();
var list_tag = '<ul></ul>';
if (/^\s*\w+\./.test(txt)) {
var matches = /([0-9])\./.exec(txt);
if (matches) {
var start = parseInt(matches[1], 10);
list_tag = start>1 ? '<ol start="' + start + '"></ol>' : '<ol></ol>';
}else{
list_tag = '<ol></ol>';
}
}
if(cur_level>last_level){
if(last_level==0){
$(this).before(list_tag);
pnt = $(this).prev();
}else{
pnt = $(list_tag).appendTo(pnt);
}
}
if(cur_level<last_level){
for(var i=0; i<last_level-cur_level; i++){
pnt = pnt.parent();
}
}
$('span:first', this).remove();
pnt.append('<li>' + $(this).html() + '</li>')
$(this).remove();
last_level = cur_level;
}else{
last_level = 0;
}
})
$('[style]', editor).removeAttr('style');
$('[align]', editor).removeAttr('align');
$('span', editor).replaceWith(function() {return $(this).contents();});
$('span:empty', editor).remove();
$("[class^='Mso']", editor).removeAttr('class');
$('p:empty', editor).remove();
}
return this.each(function() {
$(this).on('keyup', function(){
$('#src').text($('#editor').html());
var content = $(this).html();
if (/class="?Mso|style="[^"]*\bmso-|style='[^'']*\bmso-|w:WordDocument/i.test( content )) {
word_filter( $(this) );
}
});
});
};
})( jQuery )
$(function(){
$('#editor').msword_html_filter();
$('#src').text($('#editor').html());
})
I found it. Selector is not the problem. $('.editable_div').msword_html_filter(); is normally working.
But if the parent div is contenteditable = true, the script is not working for children divs. I still dont know why. Thanks you all.

Find Text from content then hide

I am trying hide specific Text elements from content by jquery.
HTML:
<div id="name">
Trying hide specific Text elements from content.
</div>
I want this:
<div id="name">
Trying hide <p style="display: none;">specific</p> Text elements from content.
</div>
Or any others simple solution by jquery?
somthing simple like
var nameText = $('#name').text();
var newText = nameText.replace('specific','<p style="display:none">specific</p>');
$('#name').html(newText) // use html() here, not text()
add an id to your p tag and you can hide it by jquery like
$( document ).ready(function() {
$("#p-id").hide();
});
I make function for you
function hideIt(elem, exclude){
var text = elem[0].innerText;
var exculude = exclude;
var match = text.match(exclude);
if(match === null){
console.log('no match founded')
}
else{
for(var i =0 ; i<match.length; i++){
elem[0].innerText = text.replace(match[i],"")
}
}
}
hideIt($('#name'),'specific');
place 1rst param your elem with jquery selector and on 2nd parm the string want to kill
https://jsfiddle.net/xps4553m/5/ for you

find closing anchor tag from the string and add some value

I am trying to find closing anchor tag. And add Icon after the closing tag.The inside value is coming as a string from database.I need to extract the value and append with icon.
For example
<p>This is a paragraph and link testtestdsfasffdtest1fdfdfdfdfd</p>
In the above example I have paragraph tag inside I have two anchor tag.
Actually the result will come as Test added plus icon testdsfasffd & Test1 added plus icon 2 fdfdfdfdfd
First I need to find the closing anchor tag then i need to append the icon from other functions
Current I am trying like this
var string = '<p>This is a paragraph and link testtestdsfasffdtest1fdfdfdfdfd</p>';
I am setting an pattern
var closingAnchor = '</a>';
string.split(closingAnchor);
after this i need to append icon from other function using for loop. I am getting struggle here kindly please help me.
Splitting HTML is normally a bad bad idea. So just do it with the DOM.
var string = '<p>This is a paragraph and link testtestdsfasffdtest1fdfdfdfdfd</p>';
var div = document.createElement("div");
div.innerHTML = string;
var anchors = div.getElementsByTagName("a");
for (var i = 0; i < anchors.length; i++) {
var text = document.createTextNode(' TEXT TO ADD ');
var sibling = anchors[i].nextSibling;
if(sibling) {
anchors[i].parentNode.insertBefore(text, sibling);
} else {
anchors[i].parentNode.appendChild(text);
}
}
console.log(div.innerHTML);
document.getElementById("out").innerHTML = div.innerHTML;
<div id="out"></div>
Here you are: // for regex, <\/a> for </a>, g for search all
var string = '<p>This is a paragraph and link testtestdsfasffdtest1fdfdfdfdfd</p>';
var output = string.replace(/<\/a>/g, '</a>YOUR APPENDEE');
alert(output);
Hope this helps.

jQuery adding auto link to href attribute

HTML:
< p class="link-panel ">http:..www.google.com< /p ><br>
< a target="blank" href="">GO< /a>
jQuery:
var linkVal = new Array();
$('.link-panel').each(function(index){
linkVal[index] = $(this).text();
});
$('a').each(function(){
$(this).attr("href", linkVal);
});
I'm trying to get the text value from the P tag and append it to the href attribute in the link. I can do this for one, but I can't seem to work out how to make this work when there is more than one URL?
Thanks
You can iterate over the anchors and get the text from the previous paragraph
$('a').attr('href', function() {
return $(this).prev('p').text();
});
or iterate over paragraphs and set the href for the following anchor
$('.link-panel').each(function() {
$(this).next('a').attr('href', $(this).text());
});

replacing html tag inside textarea with text

code :
<script src="Scripts/jquery-1.8.2.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
var $this = $("#Test_txtarea");
var txtval = $this.val();
$this.find("img").each(function () {
var imgbytes = $(this).attr("name"); // extract bytes from selected img src
$(this).replaceWith(imgbytes);
});
$("#NewVal").html(txtval);
});
</script>
html
<textarea ID="Test_txtarea" >Hi <img src='test.png' name='test' > kifak <img src='test2.png' name='test1' > Mnih <img src='test3.png' name='test3' ></textarea>
<span id="NewVal" ></span>
what i am trying to do is basically trying to replace each img tag by it's name so the final textarea value will be like this : Hi test kifak test1 Mnih test3
this is the jsfiddle : http://jsfiddle.net/Ga7bJ/2/
the .find("img") always return 0 as length.how can i fix this code ?
Though it is not complete answer or at least not going to be "Copy paste" answer, there is few things you need to do here:
The content of Textarea is VAL of it and not InnerHTML. So, you have to pick that content as value and than create a hidden div and put it as HTML. Once you did it, you can now find the HTML tags in it using find rather easily.
Once you find tag you can find the name using attr() function
Once you have name, than you again go back to val() of textarea, and do regex replace or using HTML you can replace as well I guess, but not sure.
Look at this jsFiddle. What is does is:
It gets the value from your Test_txtarea and sets that as the html of a hidden div.
The hidden div wil render the images within the textarea.
After they have been rendered, I find these images,
- get the source,
- remove all characters after the .
- replace the entire html of the image with the src.
After all that has been done you are left with a div with the value you wanted.
All what is done next is the html from the div is copied to the value of your textarea.
function replaceImageWithSrc(value){
var div = $("#invisible");
div.html(value);
var images = div.find("img");
images.each(function(index){
var src = $(this).attr("src").split(".")[0];
this.outerHTML = src;
});
return div.html();
}
$(document).ready(function () {
var txtArea = $("#Test_txtarea");
var txtval = txtArea.val();
txtval = replaceImageWithSrc(txtval);
txtArea.val(txtval);
});
The following code works for me. Basically, I get the value of the text area and append it to an off-screen div. Now that I have valid markup nesting, I can iterate the child-nodes as normal.
function byId(e){return document.getElementById(e)}
function newEl(t){return document.createElement(t)}
function test()
{
var div = newEl('div');
div.innerHTML = byId('Test_txtarea').value;
var msg = '';
var i, n = div.childNodes.length;
for (i=0; i<n; i++)
{
if (div.childNodes[i].nodeName == "IMG")
msg += div.childNodes[i].name;
else if (div.childNodes[i].nodeName == "#text")
msg += div.childNodes[i].data;
}
byId('NewVal').innerHTML = msg;
}

Categories