Replacing HTML Text with Parsed Query String Objects - javascript

I am parsing the following query string:
/?alt_name=test&test=brand&old=Superman&new=Batman
and get this Object {alt_name: "Giggitty", test: "brand", old: "Supco", new: "Batman"}.
How would I go about creating a script that if the test=brand replace inner html instances of the word Superman(old) with the word Batman(new)?
Any help is greatly appriciated.
Edit. HTML would help although a super simple example will suffice.
<html>
<body>
<div>
<p>Superman and some other text</p>
</div>
</body>
</html>
Basically I just want every instance of the word Superman, or whatever the parsed value for old, to be replaced with whatever the parsed value for new is, in this case Batman.

You could do something like this if you want to match exactly "Superman" and not something that contains it.
HTML
<div>
<p>Superman and some other text</p>
</div>
<div>
<p>More Superman and some other text</p>
</div>
<div>
<p>Something Supermanish and some other text</p>
</div>
Javascript
function walkTheDOM(node, func) {
func(node);
node = node.firstChild;
while (node) {
walkTheDOM(node, func);
node = node.nextSibling;
}
}
function escapeRegex(string) {
return string.replace(/[\[\](){}?*+\^$\\.|]/g, "\\$&");
}
function replaceText(node, searchText, replaceText) {
var textNodes = [],
length,
i;
function filterTextNodes(currentNode) {
if (currentNode.nodeType === 3) {
textNodes.push(currentNode);
}
}
walkTheDOM(node, filterTextNodes);
i = 0;
length = textNodes.length;
while (searchText && i < length) {
textNodes[i].nodeValue = textNodes[i].nodeValue.replace(new RegExp("\\b" + escapeRegex(searchText) + "\\b"), replaceText);
i += 1;
}
}
var query = {
alt_name: "Giggitty",
test: "brand",
old: "Superman",
new: "Batman"
};
if (query.test === "brand") {
replaceText(document, query.old, query.new);
}
On jsfiddle

Related

Transform text inside parentheses to uppercase

What I'm am trying to do is get the html text inside parentheses and transform it to uppercase. I want the output to be:
Cat (IVA)
Dog (MANGO) etc.
What am I doing wrong?
// Transform text inside parentheses to upper case
let petName = $(".petName").text();
let regExp = /\(([^)]+)\)/;
for (var i = 0; i < petName.length; i++) {
let regExp = /\(([^)]+)\)/;
regExp.replace(petName[i].toUpperCase())
}
html
<div>
<h1 class="petName">Cat (Iva)</h1>
</div>
<div>
<h1 class="petName">Dog (Mango)</h1>
</div>
<div>
<h1 class="petName">Puppy (Mara)</h1>
</div>
Multiple things wrong here:
String objects are immutable in JS. regExp.replace(…) does not change the original, it only returns the altered result.`
You are not selecting any elements to begin with. The selector .petName h1 matches h1 elements that are descendants of an element with the class petName
you can not directly call a function while replacing, you need to do this via a callback function, that gets the match(es) passed to it.
let $petNames = $("h1.petName")
$petNames.each(function() {
$(this).text( $(this).text().replace(/\(([^)]+)\)/, function(match) {
return match.toUpperCase()
} ) )
})
This should do it. :)
$(".petName").each(function(i, el) {
const text = el.innerText;
const strToReplace = text.match(/(\(.*\))/)[0];
el.innerText = text.replace(strToReplace, strToReplace.toUpperCase());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<h1 class="petName">Cat (Iva)</h1>
</div>
<div>
<h1 class="petName">Dog (Mango)</h1>
</div>
<div>
<h1 class="petName">Puppy (Mara)</h1>
</div>

How to get all elements that can display text on the page?

I want to write a script to replace all text meeting a condition with something else.
However, I don't want it to replace text in elements such as script, style, etc. which are not shown/rendered.
What is the best way to distinguish these elements?
//Example of idea:
var elements = document.getElementsByTagName("*");
var element;
var text;
for(var i=0; i<elements.length; i++){
element = elements[i];
//Need to detect only text that is displayed.
text = element.textContent;
if(checkText(text)){element.textContent = somethingElse;}//Abstract idea
}
You could try this
$(':contains("targetText")').text("newText");
This is the purpose of TreeWalkers and the document.createTreeWalker method:
function getTextNodes (root) {
var tw = document.createTreeWalker(root || document.body, NodeFilter.SHOW_TEXT, {
acceptNode: function(node) {
return /^(STYLE|SCRIPT)$/.test(node.parentElement.tagName) ||
/^\s*$/.test(node.data) ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT
}
})
var result = []
while (tw.nextNode()) result.push(tw.currentNode)
return result
}
var textNodes = getTextNodes()
// Text nodes before
console.log(
textNodes.map(function (n) { return n.data })
)
// Example text data transformation
textNodes.forEach(function (n) {
n.data = n.data.toUpperCase()
})
// Text nodes after
console.log(
textNodes.map(function (n) { return n.data })
)
<p>Lorem ipsum dot dolor sit amet...</p>
<span>More example text!</span>
<style>
.omitted style { }
</style>
<script>
'omitted script'
</script>
You can also use jQuery's star selector (*) and say :not(script) to the tags you want to ignore.
The following will replace any element that has the content "Test" with "Replaced", while ignoring any <script> and <style> tags.
$("body *:not(script):not(style)").each(function() {
if ($(this).text() == "Test") {
$(this).text("Replaced");
}
});
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.js"></script>
<div class="content">
<h1>Hello World</h1>
<p>Lorem ipsum...</p>
<p>Test</p>
<ul>
<li>Hello</li>
<li>World</li>
<li>Test</li>
</ul>
</div>

jQuery replace all occurrences of a string in an html page

I'm working on a project where I need to replace all occurrences of a string with another string. However, I only want to replace the string if it is text. For example, I want to turn this...
<div id="container">
<h1>Hi</h1>
<h2 class="Hi">Test</h2>
Hi
</div>
into...
<div id="container">
<h1>Hello</h1>
<h2 class="Hi">Test</h2>
Hello
</div>
In that example all of the "Hi"s were turned into "Hello"s except for the "Hi" as the h2 class.
I have tried...
$("#container").html( $("#container").html().replace( /Hi/g, "Hello" ) )
... but that replaces all occurrences of "Hi" in the html as well
This:
$("#container").contents().each(function () {
if (this.nodeType === 3) this.nodeValue = $.trim($(this).text()).replace(/Hi/g, "Hello")
if (this.nodeType === 1) $(this).html( $(this).html().replace(/Hi/g, "Hello") )
})
Produces this:
<div id="container">
<h1>Hello</h1>
<h2 class="Hi">Test</h2>
Hello
</div>
jsFiddle example
Nice results with:
function str_replace_all(string, str_find, str_replace){
try{
return string.replace( new RegExp(str_find, "gi"), str_replace ) ;
} catch(ex){return string;}}
and easier to remember...
replacedstr = str.replace(/needtoreplace/gi, 'replacewith');
needtoreplace should not rounded by '
//Get all text nodes in a given container
//Source: http://stackoverflow.com/a/4399718/560114
function getTextNodesIn(node, includeWhitespaceNodes) {
var textNodes = [], nonWhitespaceMatcher = /\S/;
function getTextNodes(node) {
if (node.nodeType == 3) {
if (includeWhitespaceNodes || nonWhitespaceMatcher.test(node.nodeValue)) {
textNodes.push(node);
}
} else {
for (var i = 0, len = node.childNodes.length; i < len; ++i) {
getTextNodes(node.childNodes[i]);
}
}
}
getTextNodes(node);
return textNodes;
}
var textNodes = getTextNodesIn( $("#container")[0], false );
var i = textNodes.length;
var node;
while (i--) {
node = textNodes[i];
node.textContent = node.textContent.replace(/Hi/g, "Hello");
}
Note that this will also match words where "Hi" is only part of the word, e.g. "Hill". To match the whole word only, use /\bHi\b/g
here you go => http://jsfiddle.net/c3w6X/1/
var children='';
$('#container').children().each(function(){
$(this).html($(this).html().replace(/Hi/g,"Hello")); //change the text of the children
children=children+$(this)[0].outerHTML; //copy the changed child
});
var theText=$('#container').clone().children().remove().end().text(); //get the text outside of the child in the root of the element
$('#container').html(''); //empty the container
$('#container').append(children+theText.replace(/Hi/g,"Hello")); //add the changed text of the root and the changed children to the already emptied element

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 get text between two closed tags

I'm looking for a jQuery solution
<pre><marker id="markerStart"></marker>
aaaaa
<span style='font-family:monospace;background-color:#a0a0a0;'>bbb</span>bb
cc<marker id="markerEnd"></marker>ccc
</pre>
How get text between <marker> tags? Should be the following result:
aaaaabbbbbcc
Example 2 (markerEnd inside SPAN tag):
<pre><marker id="markerStart"></marker>
aaaaa
<span style='font-family:monospace;background-color:#a0a0a0;'>b<marker id="markerEnd"></marker>bb</span>bb
ccccc
</pre>
expected result: aaaaab
Thanks.
You can get all elements between two nodes like this:
$('marker:first').nextUntil('marker').text()
However, since you need to include text nodes, you need to write
var contents = $('pre').contents(),
start = contents.filter('marker:first'),
end = start.nextAll('marker:first'),
startIndex = contents.index(start),
endIndex = contents.index(end);
alert(contents.filter(function(i) {
return i > startIndex && i < endIndex;
}).text());
http://jsfiddle.net/SLaks/2jEps/
Here you go:
function textBetween(id1, id2) {
var node = document.getElementById(id1).nextSibling,
text = '';
while ( node && node.id !== id2 ) {
text += node.textContent.trim();
node = node.nextSibling;
}
return text;
}
Call this to get your text:
textBetween('markerStart', 'markerEnd')
Live demo: http://jsfiddle.net/simevidas/yxVxy/4/

Categories

Resources