Text replace javascript jquery - javascript

First of all Hello to everyone, and sorry for my English.
I would still take advantage of the expertise and availability of this community.
Yesterday i see a post(this) about string sostitution.
For simplicity, we remove the tables and try to look at the following code
<div id="find">
<div>(this match)</div>
<div>(this match)</div>
<div>some text1
<div></div>
<div>(this match)</div>
<div>some text2</div>
<div>some text3</div>
</div>
</div>
in this case if we want to find items that contain the word "match" and replace this word with "some other text" string, we can use one of these code snippet i found by reading other posts on this topic
$(document).ready(function(){
var elements = $('div');
for(var i = 0; i < elements.length; i++) {
var current = elements[i];
if(current.children.length === 0) {
var x=current.textContent
if (x.indexOf('match') > 0) {current.textContent='some other text'}
}
}
})
$(document).ready(function(){
$("#find div:contains('match'):not(:has(*))").each(function () {
var str=$(this).text('some other text')
})
})
$(document).ready(function(){
$("div").each(function(){
var str=''
var div = $(this).clone();
div.find("*").remove();
str=div.text();
if (str.indexOf('match') > 0) {
$(this).text('some other text')
}
})
})
However, if you edit the html in this way all snippets are wrong
<div id="find">(this match)
<div>(this match)
<div>(this match)</div>
</div>
<div>(this match)<div>aaaa</div></div>
<div>some text1
<div></div>
<div>(this match)</div>
<div>some text2</div>
<div>some text3</div>
</div>
</div>
I have found a solution to this problem but I think it's inelegant and overly verbose
$(document).ready(function(){
var len =$('#find div').length
for(i=1;i<len;i++){
$('div:eq('+i+')').contents().addClass('passed').filter(function () {
return $(this).text()==='(this match)' && $.trim(this.nodeValue).length
}).replaceWith('some other text');
}
for(i=0;i<len;i++){
var classx=$('div:eq('+i+')').attr('class')
if(classx===undefined){
var xx=$('div:eq('+i+')').contents()[0].nodeValue
if (xx.indexOf('match') > 0) {
$('div:eq('+i+')').contents()[0].nodeValue='some other text'
}
}
}
})
Please could someone direct me to a more efficient and elegant way to achieve the same result?
As always, thank you all in advance, any advice will be welcomed with pleasure.

I think what you want is here. If I understand what you want to do, a more "elegant" way of doing for the first snippet it could be:
$(document).ready(function(){
$('#find div').each(function () {
$(this).html($(this).html().replace('match', 'some other text'));
});
});
As for the second, this seems to work (as a caveat, it also works on the first snippet):
function findAllText (idToStartWith) {
$('#' + idToStartWith).html($('#' + idToStartWith).html().replace('match', 'some other text'));
while ($('#' + idToStartWith).text().indexOf('match') > 0) {
$('#' + idToStartWith).find('*').each(function () {
$(this).html($(this).html().replace('match', 'some other text'));
});
}
}

Related

How to select middle nodes with specific text using jQuery :contains selector?

I want to get html elements containing specific text, and I used :contains selector. However, I'm not getting the nodes that I target.
In this example I'm trying to get all elements that has the 'today?' text, even if it's splited with other inline elements like <a>, <span>, <sup>, etc.
So I expect the result: DIV.some-class, P.another-class
//let results = $(':contains(today?):not(:has(*))')
let results = $(":contains('today?')").not("script")
results.each(function() {
console.log(`${this.tagName}${this.className ? '.' + this.className : ''}`)
})
/**
prints HTML, BODY, DIV.content, DIV.some-class, P.another-class
*/
console.log()
let results2 = $(":contains('today?')").not("script").children().filter(function() {
return ($(this).text().indexOf("today?") > -1)
}).get()
results2.forEach(r => {
console.log(`${r.tagName}${r.className ? '.' + r.className : ''}`)
})
/**
prints BODY, DIV.content, DIV.some-class, P.another-class
*/
console.log()
let results3 = $(":contains('today?')").not("script").filter(function() {
return (
$(this).clone() //clone the element
.children() //select all the children
.remove() //remove all the children
.end() //again go back to selected element
.filter(":contains('today?')").length > 0)
}).get();
results3.forEach(r => {
console.log(`${r.tagName}${r.className ? '.' + r.className : ''}`)
})
/**
prints P.another-class
*/
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='content'>
<div class='some-class'>
Hello world! How are you<a> doing today</a>?
</div>
<div class='some-other-class'>
Bye world!
</div>
<p class='another-class'>
Any <b>plans</b> for today?
</p>
</div>
You can use children() and contains a selector. Here's a working solution:
var elements = $('.content').children().filter(":contains('today?')");
var result = $.map(elements, function (el) {
return `${el.tagName}${el.className ? '.' + el.className : ''}`;
});
console.log(result.join(', '));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='content'>
<div class='some-class'>
Hello world! How are you<a> doing today</a>?
</div>
<div class='some-other-class'>
Bye world!
</div>
<p class='another-class'>
Any <b>plans</b> for today?
</p>
</div>

Get Innerhtml of a nestate span element jquery?

just wants to get the inner html of a nestate span tag..
<span class="select2-selection__rendered" id="select2-SearchByUser-container" title="chowdhury , nayan (nayanchowdhury92#gmail.com)">
<span class="select2-selection__clear">×</span>
mark john
</span>
i need mark john and i try =>
alert($('#select2-SearchByUser-container').html())
i give output/alert something like =>
<span class="select2-selection__clear">×</span>mark john
is there any way that i can get only mark john...help please...
To do what you need you can retrieve the last textNode in the element, like this:
var text = $('#select2-SearchByUser-container').contents().filter(function() {
return this.nodeType == 3 && this.nodeValue.trim();
}).last().text().trim();
console.log(text);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="select2-selection__rendered" id="select2-SearchByUser-container" title="chowdhury , nayan (nayanchowdhury92#gmail.com)">
<span class="select2-selection__clear">×</span> mark john
</span>
Try this :
https://jsfiddle.net/4nwp25Le/
jQuery(document).ready(function() {
var node = $('#select2-SearchByUser-container').contents().filter(function() {
return this.nodeType == 3; // text node
});
alert(node.text());
});
Your html is not good so far, if possible fix that so that you can get different spans for them.
If you don't have control over HTML, can give a try like this
$('#select2-SearchByUser-container').clone().children().remove().end().text()
https://jsfiddle.net/qspoygox/
var el = document.getElementById("select2-SearchByUser-container"),
child = el.firstChild,
texts = [];
while (child) {
if (child.nodeType == 3) {
texts.push(child.data);
}
child = child.nextSibling;
}
var text = texts.join("");
alert(text);
<span class="select2-selection__rendered" id="select2-SearchByUser-container" title="chowdhury , nayan (nayanchowdhury92#gmail.com)">
<span class="select2-selection__clear">×</span>
mark john
</span>

Better way of extracting text from HTML in Javascript

I'm trying to scrape text from an HTML string by using container.innerText || container.textContent where container is the element from which I want to extract text.
Usually, the text I want to extract is located in <p> tags. So for the HTML below as an example:
<div id="container">
<p>This is the first sentence.</p>
<p>This is the second sentence.</p>
</div>
Using
var container = document.getElementById("container");
var text = container.innerText || container.textContent; // the text I want
will return This is the first sentence.This is the second sentence. without a space between the first period and the start of the second sentence.
My overall goal is to parse text using the Stanford CoreNLP, but its parser cannot detect that these are 2 sentences because they are not separated by a space. Is there a better way of extracting text from HTML such that the sentences are separated by a space character?
The HTML I'm parsing will have the text I want mostly in <p> tags, but the HTML may also contain <img>, <a>, and other tags embeeded between <p> tags.
As a dirty hack, try using this:
container.innerHTML.replace(/<.*?>/g," ").replace(/ +/g," ");
This will replace all tags with a space, then collapse multiple spaces into a single one.
Note that if there is a > inside an attribute value, this will mess you up. Avoiding this problem will require more elaborate parsing, such as looping through all text nodes and putting them together.
Longer but more robust method:
function recurse(result, node) {
var c = node.childNodes, l = c.length, i;
for( i=0; i<l; i++) {
if( c[i].nodeType == 3) result += c.nodeValue + " ";
if( c[i].nodeType == 1) result = recurse(result, c[i]);
}
return result;
}
recurse(container);
Assuming I haven't made a stupid mistake, this will perform a depth-first search for text nodes, appending their contents to the result as it goes.
jQuery has the method text() that does what you want. Will this work for you?
I'm not sure if it fits for everything that's in your container but it works in my example. It will also take the text of a <a>-tag and appends it to the text.
Update 20.12.2020
If you're not using jQuery. You could implement the text method with vanilla js like this:
const nodes = Array.from(document.querySelectorAll("#container"));
const text = nodes
.filter((node) => !!node.textContent)
.map((node) => node.textContent)
.join(" ");
Using querySelectorAll("#container") to get every node in the container. Using Array.from so we can work with Array methods like filter, map & join.
Finally, generate the text by filtering out elements with-out textContent. Then use map to get each text and use join to add a space separator between the text.
$(function() {
var textToParse = $('#container').text();
$('#output').html(textToParse);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<p>This is the first sentence.</p>
<p>This is the second sentence.</p>
<img src="http://placehold.it/200x200" alt="Nice picture"></img>
<p>Third sentence.</p>
</div>
<h2>output:</h2>
<div id="output"></div>
You can use the following function to extract and process the text as shown. It basically goes through all the children nodes of the target element and the child nodes of the child nodes and so on ... adding spaces at appropriate points:
function getInnerText( sel ) {
var txt = '';
$( sel ).contents().each(function() {
var children = $(this).children();
txt += ' ' + this.nodeType === 3 ? this.nodeValue : children.length ? getInnerText( this ) : $(this).text();
});
return txt;
}
function getInnerText( sel ) {
var txt = '';
$( sel ).contents().each(function() {
var children = $(this).children();
txt += ' ' + this.nodeType === 3 ?
this.nodeValue : children.length ?
getInnerText( this ) : $(this).text();
});
return txt;
}
alert( getInnerText( '#container' ) );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="container">
Some other sentence
<p>This is the first sentence.</p>
<p>This is the second sentence.</p>
</div>
You may use jQuery to traverse down the elements.
Here is the code :
$(document).ready(function()
{
var children = $("#container").find("*");
var text = "";
while (children.html() != undefined)
{
text += children.html()+"\n";
children = children.next();
}
alert(text);
});
Here is the fiddle : http://jsfiddle.net/69wezyc5/

Smart text replacing with jQuery

I need to replace some part of text, e.g. mustache var {{myvar}}, on already loaded page.
Example html:
<html>
<head>
<title>{{MYTITLE}}</title>
</head>
<body>
<p><strong><ul><li>text {{TEXT}}</li></ul></strong></p>
{{ANOTHER}}
</body>
</html>
What's the problem? Use $(html).html(myrenderscript($(html).html()))!
It's ugly, slow and brokes <script> tags.
What do you want?
I want to get closest tag with {{}} and than render and replace.
Your researches?
Firstly, i tried: $('html :contains("{{")). But it returns <title>, <p>, <strong> .... But i need <title> and <li>.
Than i tried to filter them:
$('html :contains("{{")').filter(function (i) {
return $(this).find(':contains("{{")').length === 0
});
...but it WONT return {{ANOTHER}}. And that is my dead end. Your suggestions?
Using http://benalman.com/projects/jquery-replacetext-plugin/ you could do the following:
$('html *').replaceText(/{{([^}]+)}}/, function(fullMatch, key) {
return key;
}, true);
See http://jsfiddle.net/4nvNy/
If all you want to do is replace that text - then surely the following works (or have I mis-understood)
usage is as follows: CONTAINER (body) - replaceTExt (search term (I have built the function to always include {{}} around the term), (replace - this will remove the {{}} as well)
$('body').replaceText("MYTITLE","WHATEVER YOU WANT IT REPLACING WITH");
$.fn.replaceText = function(search, replace, text_only) {
return this.each(function(){
var v1, v2, rem = [];
$(this).find("*").andSelf().contents().each(function(){
if(this.nodeType === 3) {
v1 = this.nodeValue;
v2 = v1.replace("{{" + search + "}}", replace );
if(v1!=v2) {
if(!text_only && /<.*>/.test(v2)) {
$(this).before( v2 );
rem.push(this);
}
else this.nodeValue = v2;
}
}
});
if(rem.length) $(rem).remove();
});
};
You could avoid jQuery altogether if you wanted to with something like this:
<body>
<p><strong>
<ul>
<li>text {{TEXT}}</li>
</ul>
</strong></p>
{{ANOTHER}}
<hr/>
<div id="showResult"></div>
<script>
var body = document.getElementsByTagName('body')[0].innerHTML;
var startIdx = 0, endIdx = 0, replaceArray = [];
var scriptPos = body.indexOf('<script');
while (startIdx != 1) {
startIdx = body.indexOf('{{', endIdx) + 2;
if(startIdx > scriptPos){
break;
}
endIdx = body.indexOf('}}', startIdx);
var keyText = body.substring(startIdx, endIdx);
replaceArray.push({"keyText": keyText, 'startIdx': startIdx, 'endIdx': endIdx});
}
document.getElementById("showResult").innerHTML = JSON.stringify(replaceArray);
</script>
</body>
You can then do what you want with the replaceArray.

How to get child element by ID in JavaScript?

I have following html:
<div id="note">
<textarea id="textid" class="textclass">Text</textarea>
</div>
How can I get textarea element? I can't use document.getElementById("textid") for it
I'm doing it like this now:
var note = document.getElementById("note");
var notetext = note.querySelector('#textid');
but it doesn't work in IE(8)
How else I can do it? jQuery is ok
Thanks
If jQuery is okay, you can use find(). It's basically equivalent to the way you are doing it right now.
$('#note').find('#textid');
You can also use jQuery selectors to basically achieve the same thing:
$('#note #textid');
Using these methods to get something that already has an ID is kind of strange, but I'm supplying these assuming it's not really how you plan on using it.
On a side note, you should know ID's should be unique in your webpage. If you plan on having multiple elements with the same "ID" consider using a specific class name.
Update 2020.03.10
It's a breeze to use native JS for this:
document.querySelector('#note #textid');
If you want to first find #note then #textid you have to check the first querySelector result. If it fails to match, chaining is no longer possible :(
var parent = document.querySelector('#note');
var child = parent ? parent.querySelector('#textid') : null;
Here is a pure JavaScript solution (without jQuery)
var _Utils = function ()
{
this.findChildById = function (element, childID, isSearchInnerDescendant) // isSearchInnerDescendant <= true for search in inner childern
{
var retElement = null;
var lstChildren = isSearchInnerDescendant ? Utils.getAllDescendant(element) : element.childNodes;
for (var i = 0; i < lstChildren.length; i++)
{
if (lstChildren[i].id == childID)
{
retElement = lstChildren[i];
break;
}
}
return retElement;
}
this.getAllDescendant = function (element, lstChildrenNodes)
{
lstChildrenNodes = lstChildrenNodes ? lstChildrenNodes : [];
var lstChildren = element.childNodes;
for (var i = 0; i < lstChildren.length; i++)
{
if (lstChildren[i].nodeType == 1) // 1 is 'ELEMENT_NODE'
{
lstChildrenNodes.push(lstChildren[i]);
lstChildrenNodes = Utils.getAllDescendant(lstChildren[i], lstChildrenNodes);
}
}
return lstChildrenNodes;
}
}
var Utils = new _Utils;
Example of use:
var myDiv = document.createElement("div");
myDiv.innerHTML = "<table id='tableToolbar'>" +
"<tr>" +
"<td>" +
"<div id='divIdToSearch'>" +
"</div>" +
"</td>" +
"</tr>" +
"</table>";
var divToSearch = Utils.findChildById(myDiv, "divIdToSearch", true);
(Dwell in atom)
<div id="note">
<textarea id="textid" class="textclass">Text</textarea>
</div>
<script type="text/javascript">
var note = document.getElementById('textid').value;
alert(note);
</script>
Using jQuery
$('#note textarea');
or just
$('#textid');
$(selectedDOM).find();
function looking for all dom objects inside the selected DOM.
i.e.
<div id="mainDiv">
<p>Paragraph 1</p>
<p>Paragraph 2</p>
<div id="innerDiv">
link
<p>Paragraph 3</p>
</div>
</div>
here if you write;
$("#mainDiv").find("p");
you will get tree p elements together. On the other side,
$("#mainDiv").children("p");
Function searching in the just children DOMs of the selected DOM object. So, by this code you will get just paragraph 1 and paragraph 2. It is so beneficial to prevent browser doing unnecessary progress.

Categories

Resources