Javascript find and replace works with string but not variable - javascript

Hoping someone can help me it's driving me nuts.
I am using SPServices and Javascript to rewrite some links after a small content migration.
I have some HTML in a variable and I'm trying to find a string which is a specific URL and replace it with a different URL. This works:
newHTML = newHTML.replace("http://urlhere/subsite/page.aspx",newLink);
Also this works:
newHTML = newHTML.replace(new RegExp("http://urlhere/subsite/page.aspx", 'gi'), newLink);
But if I have a variable containing the same string in there it doesn't work:
newHTML = newHTML.replace(new RegExp(oldLink, 'gi'), newLink);
My oldLink variable comes from an SPServices call to another list column containing HTML, which I take the 'a' tags and put them into an array:
function rewriteLinks() {
var urlStart = "http://urlstart";
var linkContainerArray = [];
var theContent = $('.htmlContentDiv').html();
// get a tags
var aTags = ('a',theContent);
//loop through A tags and get oldLink and Text
$(aTags).each(function(){
var ID;
var itemTitle = $(this).text();
var oldLink = $(this).attr('href');
var newLink;
if(itemTitle.length > 2){
//SpService call to get ID of that item using inner text as query to SharePoint list
$().SPServices({
operation: "GetListItems",
async: false,
CAMLViewFields: "<ViewFields><FieldRef Name='Title' /><FieldRef Name='ID' /></ViewFields>",
CAMLQuery: '<Query><Where><Eq><FieldRef Name="Title" /><Value Type="Text"><![CDATA['+itemTitle+']]></Value></Eq></Where></Query>',
listName: 'AGItems',
completefunc: function (xData, Status) {
$(xData.responseXML).SPFilterNode("z:row").each(function() {
ID = $(this).attr("ows_ID");
//Now have oldLink and newID in variables - build newLink from known URL & newID
newLink = urlStart+ID;
});//response xml
}//completefunc
});//spservices
//check for empty links
if((oldLink && newLink != '') && (oldLink && newLink != undefined)){
var linkPair = [oldLink,newLink];
linkContainerArray.push(linkPair);
}
}
});
replaceLinks(linkContainerArray);
}
Then I call a function to find and replace the links (this is where my variable won't work). I've tried escaping in all combinations of the following ways:
function escapeRegExp(stringToGoIntoTheRegex) {
return stringToGoIntoTheRegex.replace(/[\/\\^$*+?.|[\]{}]/g, '\\$&');
}
function htmlEncode(value){
//create a in-memory div, set it's inner text(which jQuery automatically encodes)
//then grab the encoded contents back out. The div never exists on the page.
return $('<div/>').text(value).html();
}
function htmlEscape(str) {
return String(str)
.replace(/"/g, '"')
.replace(/'/g, "'")
.replace(/</g, '<')
.replace(/>/g, '>');
}
function escapeRegExp(stringToGoIntoTheRegex) {
return stringToGoIntoTheRegex.replace(/[\/\\^$*+?.|[\]{}]/g, '\\$&');
}
Also removed full stops and question marks from the HTML & variable to make everything simple and it's still not working.
Also tried encodeURIComponent on the HTML & oldlink variable.. still no luck
If anyone has any help for me with this at all it would be much appreciated or can maybe see what I'm missing?!
Thanks

It does not work because some the characters in the string have a special meaning in a regular expression, like \ and .. So they need to be escaped.
You can use this function:
function escapeRegExp(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
var newHTML = ' my link ';
var oldLink = 'http://someplaintext/pages/GuidelinesaspxiPageId=14495';
var newLink = 'http://urlstart?id=14495';
newHTML = newHTML.replace(new RegExp(escapeRegExp(oldLink), 'gi'), newLink);
console.log(newHTML);
See also this question.

Related

Javascript replace() using html entities not working

I've got the following script, which successfully replaces < and > with the code indicated below. The idea here is that a user would put into the text box if they want "Bold me" to appear bolded on their blog.
$('.blogbody').each(function() {
var string = $(this).html();
$(this).html(string.replace('<', '<span class="bold">'));
});
$('.blogbody').each(function() {
var string = $(this).html();
$(this).html(string.replace('>', '</span>'));
});
The problem comes with other html entities. I'm going to simply my example. I want to replace the [ html entity with a paragraph tag, but none of the lines in this script work. I've tried documenting each code that related to the '[' character.
$('.blogbody').each(function() {
var string = $(this).html();
$(this).html(string.replace('[', '<p>'));
});
$('.blogbody').each(function() {
var string = $(this).html();
$(this).html(string.replace('&lbrack;', '<p>'));
});
$('.blogbody').each(function() {
var string = $(this).html();
$(this).html(string.replace('&lsqb;', '<p>'));
});
$('.blogbody').each(function() {
var string = $(this).html();
$(this).html(string.replace('&lbrack;', '<p>'));
});
Any thoughts on this would be greatly appreciated! Thanks!
The character '[' is not a character entity so it is not encoded. Just pass it directly to replace:
string.replace('[' , '<p>')

Replace HTML Comment along with string variable

In my project I have some html with comments surrounding text so I can find the text between particular comments and replace that text whilst leaving the comments so I can do it again.
I am having trouble getting the regex to work.
Here is an html line I am working on:
<td class="spaced" style="font-family: Garamond,Palatino,sans-serif;font-size: medium;padding-top: 10px;"><!--firstname-->Harrison<!--firstname--> <!--lastname-->Ford<!--lastname--> <span class="spacer"></span></td>
Now, here is the javascript/jquery that I have at the moment:
var thisval = $(this).val(); //gets replacement text from a text box
var thistoken = "firstname";
currentTemplate = $("#gentextCodeArea").text(); //fetch the text
var tokenstring = "<!--" + thistoken + "-->"
var pattern = new RegExp(tokenstring + '\\w+' + tokenstring,'i');
currentTemplate.replace(pattern, tokenstring + thisval + tokenstring);
$("#gentextCodeArea").text(currentTemplate); //put the new text back
I think I'm pretty close, but I don't have the regex right yet.
The regex ought to replace the firstname with whatever is entered in the textbox for $thisval (method is attached to keyup procedure on textbox).
Using plain span tags instead of comments would make things easier, but either way, I would suggest not using regular expressions for this. There can be border cases that may lead to undesired results.
If you stick with comment tags, I would iterate over the child nodes and then make the replacement, like so:
$("#fname").on("input", function () {
var thisval = $(this).val(); //gets replacement text from a text box
var thistoken = "firstname";
var between = false;
$("#gentextCodeArea").contents().each(function () {
if (this.nodeType === 8 && this.nodeValue.trim() === thistoken) {
if (between) return false;
between = true;
} else if (between) {
this.nodeValue = thisval;
thisval = '';
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
New first name: <input id="fname">
<div id="gentextCodeArea">
<!--firstname-->Harrison<!--firstname-->
<!--lastname-->Ford<!--lastname-->
<span class="spacer"></span></div>
What went wrong in your code
By using text() you don't get the comment tags. To get those, you need to use html() instead
replace() does not mutate the variable given in the first argument, but returns the modified string. So you need to assign that back to currentTemplate
It would be better to use [^<]* instead of \w+ for matching the first name, as some first names have non-letters in them (hyphen, space, ...), and it may even be empty.
Here is the corrected version, but I insist that regular expressions are not the best solution for such a task:
$("#fname").on("input", function () {
var thisval = $(this).val(); //gets replacement text from a text box
var thistoken = "firstname";
currentTemplate = $("#gentextCodeArea").html(); //fetch the html
var tokenstring = "<!--" + thistoken + "-->"
var pattern = new RegExp(tokenstring + '[^<]*' + tokenstring,'i');
currentTemplate = currentTemplate.replace(pattern, tokenstring + thisval + tokenstring);
$("#gentextCodeArea").html(currentTemplate); //put the new text back
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
New first name: <input id="fname">
<div id="gentextCodeArea">
<!--firstname-->Harrison<!--firstname-->
<!--lastname-->Ford<!--lastname-->
<span class="spacer"></span></div>
here is a function which will generate an appropriate Regular expression:
function templatePattern(key) {
return new RegExp(`<!--${key}-->(.*?)<!--${key}-->`);
}
the (.*?) means "match as little as possible," so it will stop at the first instance of the closing tag.
Example:
'<!--firstname-->Harrison<!--firstname--> <!--lastname-->Ford<!--lastname-->'
.replace(templatePattern('firstname'), 'Bob')
.replace(templatePattern('lastname'), 'Johnson') // "Bob Johnson"
$(function(){
function onKeyUp(event)
{
if(event.which === 38) // if key press was the up key
{
$('.firstname_placeholder').text($(this).val());
}
}
$('#firstname_input').keyup(onKeyUp);
});
input[type=text]{width:200px}
<input id='firstname_input' type='text' placeholder='type in a name then press the up key'/>
<table>
<tr>
<td ><span class='firstname_placeholder'>Harrison</span> <span class='lastname_placeholder'>Ford</span> <span class="spacer"></span></td>
</tr>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Using Variables in Replace() Method - Javascript

I am trying to replace the contents of the alt="" attribute in the tag.
The replacment text comes from textarea input that is assigned to var alttext
The var oldtext contains tags with placeholders for replacing, like:
<img alt="placeholder" scr="pic.jpg" />
The placeholder needs to be replaced the contents of var alttext.
So far I have tried:
function replacer() {
var alttext = document.myform.alttext.value;
var oldtext = document.myform.oldtext.value;
var replacedtext = oldtext.replace("placeholder", 'alttext' )
document.myform.outputtext.value = replacedtext;
}
But it does not work.
How can the alttext variable contents be used to replace the placeholder?
Thank you very much to everyone!
function replacer() {
var alttext = document.myform.alttext.value;
var oldtext = document.myform.oldtext.value;
var replacedtext = oldtext.replace("placeholder", alttext);
document.myform.outputtext.value = replacedtext;
}
you were trying to replace with quotes around your variable (alttext) making it a string literal

checking text area for ling and changing them into hyperlink

So I have this function here:
function ShowMessage()
{
var themessege = document.getElementById("Form").textarea1.value;
var dat = new Date();
var fileName = document.getElementById("theFile").value;
var image = '<img src="' + fileName + '"/>' + '<br>';
document.getElementById("Form").textarea1.value = "";
document.getElementById("Form").countdown.value = "160";
document.getElementById("theFile").value = "";
if (themessege==null || themessege=="")
{
alert("There is no text to submit, please fill out the text box");
return false;
}
document.getElementById("blog").innerHTML = document.getElementById("blog").innerHTML + image + "Guest post: " + themessege + "<br />" + dat +"<br />";
}
I can get the text from the text area, as well as the image the user uploads. I'm wondering how I can divide the strings in the text area into subsrtings to check if they start with "www" or "htt".
This is what I've written so far:
function linkify(inputText) {
var replaceText, replacePattern1, replacePattern2;
//URLs starting with http://, https://
replacePattern1 =https;
replacedText = inputText.replace(replacePattern1, '<a href= ></a>');
//URLs starting with "www." (without // before it, or it'd re-link the ones done above).
replacePattern2 = www.;
replacedText = replacedText.replace(replacePattern2, <a href="http: ></a>');
var x = getelementbyid("blog");
for(var i = 0;i < x.length;i++){
if(blog.charAt(i) == replacePattern1){
return replacedText;
}
}
else if(blog.charAt(i) == replacePattern2){
return replacedText;
}
}
I know that the charAt(i) only checks for 1 letter....
Most of the answers that I found were on PHP, I'm trying to find a solution using JavaScript.
linkify function is not correctly written. try this one.
function linkify(inputText) {
var regUrl = /(http:[\d]{0,4}\/\/)?[a-zA-Z0-9\-\.]+\.(com|org|net|mil|edu|COM|ORG|NET|MIL|EDU)/;
return inputText.replace(regUrl,'<a href="" />');
}
;
alert(linkify('string containing link www.google.com'));// output: string containing link <a href="" />
Your linkify function is all wrong. All your variables contain references to variables that don't exist! Put quotes around them to make them strings.
What does this replacedText = inputText.replace(replacePattern1, '<a href= ></a>'); do?
Say inputText is 'https://example.com' and assuming you corrected your variables, so that replacePattern1 === 'https'
You find the https and replace it with . What does the final product look like?
replacedText === '<a href= ></a>://example.com';
Same thing happens with the second replace pattern.
Further, there is nothing like getelementbyid. It's document.getElementById. JavaScript is case-sensitive. It returns a single element with an id, so you can't loop through it.
Please, learn JavaScript before you try writing JavaScript code. Here's a good resource to start. Also, read JavaScript: The Good Parts, by Douglas Crockford.
Answering your question, here is the code you should use:
string.replace(/(https?:\/\/[^\s]+)/g, "<a href='$1'>$1</a>")
The https? means either http or https. The [^\s]+ means anything but a whitespace character. The $1 means the entire matched URL.
This is a good reference for Regular Expressions in JavaScript
This will allow for https and http URLs containing letters and numbers and convert the URLs into links.
Demo

How to add a parameter to the URL?

My current URL is: http://something.com/mobiles.php?brand=samsung
Now when a user clicks on a minimum price filter (say 300), I want my URL to become
http://something.com/mobiles.php?brand=samsung&priceMin=300
In other words, I am looking for a javascript function which will add a specified parameter in the current URL and then re-direct the webpage to the new URL.
Note: If no parameters are set then the function should add ? instead of &
i.e. if the current URL is http://something.com/mobiles.php then page should be re-directed to http://something.com/mobiles.php?priceMin=300
instead of http://something.com/mobiles.php&priceMin=300
try something like this, it should consider also cases when you already have that param in url:
function addOrUpdateUrlParam(name, value)
{
var href = window.location.href;
var regex = new RegExp("[&\\?]" + name + "=");
if(regex.test(href))
{
regex = new RegExp("([&\\?])" + name + "=\\d+");
window.location.href = href.replace(regex, "$1" + name + "=" + value);
}
else
{
if(href.indexOf("?") > -1)
window.location.href = href + "&" + name + "=" + value;
else
window.location.href = href + "?" + name + "=" + value;
}
}
then you invoke it like in your case:
addOrUpdateUrlParam('priceMin', 300);
Actually this is totally trivial, because the javascript location object already deals with this. Just encapsulate this one-liner into a function to re-use it with links etc:
<script>
function addParam(v) {
window.location.search += '&' + v;
}
</script>
add priceMin=300
There is no need to check for ? as this is already the search part and you only need to add the param.
If you don't want to even make use of a function you can write as so:
add priceMin=300
Keep in mind that this does exactly what you've asked for: To add that specific parameter. It can already be part of the search part because you can have the same parameter more than once in an URI. You might want to normalize that within your application, but that's another field. I would centralize URL-normalization into a function of it's own.
Edit:
In discussion about the accepted answer above it became clear, that the following conditions should be met to get a working function:
if the parameter already exists, it should be changed.
if the parameter already exists multiple times, only the changed copy should survive.
if the parameter already exists, but have no value, the value should be set.
As search already provides the search string, the only thing left to achieve is to parse that query-info part into the name and value pairs, change or add the missing name and value and then add it back to search:
<script>
function setParam(name, value) {
var l = window.location;
/* build params */
var params = {};
var x = /(?:\??)([^=&?]+)=?([^&?]*)/g;
var s = l.search;
for(var r = x.exec(s); r; r = x.exec(s))
{
r[1] = decodeURIComponent(r[1]);
if (!r[2]) r[2] = '%%';
params[r[1]] = r[2];
}
/* set param */
params[name] = encodeURIComponent(value);
/* build search */
var search = [];
for(var i in params)
{
var p = encodeURIComponent(i);
var v = params[i];
if (v != '%%') p += '=' + v;
search.push(p);
}
search = search.join('&');
/* execute search */
l.search = search;
}
</script>
add priceMin=300
This at least is a bit more robust as it can deal with URLs like these:
test.html?a?b&c&test=foo&priceMin=300
Or even:
test.html?a?b&c&test=foo&pri%63eMin=300
Additionally, the added name and value are always properly encoded. Where this might fail is if a parameter name results in an illegal property js label.
if(location.search === "") {
location.href = location.href + "?priceMin=300";
} else {
location.href = location.href + "&priceMin=300";
}
In case location.search === "", then there is no ? part.
So add ?newpart so that it becomes .php?newpart.
Otherwise there is a ? part already.
So add &newpart so that it becomes .php?existingpart&newpart.
Thanks to hakre, you can also simply set it like:
location.search += "&newpart";
It will automatically add ? if necessary (if not apparent, it will make it ?&newpart this way, but that should not matter).
I rewrite the correct answer in PHP:
function addOrUpdateUrlParam($name, $value){
$href = $_SERVER['REQUEST_URI'];
$regex = '/[&\\?]' . $name . "=/";
if(preg_match($regex, $href)){
$regex = '([&\\?])'.$name.'=\\d+';
$link = preg_replace($regex, "$1" . $name . "=" . $value, $href);
}else{
if(strpos($href, '?')!=false){
$link = $href . "&" . $name . "=" . $value;
}else{
$link = $href . "?" . $name . "=" . $value;
}
}
return $link;
}
I hope that help's someone...
There is an more elegant solution available, no need to write your own function.
This will add/update and take care of any ? or & you might need.
var params = new URLSearchParams(window.location.search);
params.set("name", "value");
window.location.search = params.toString();
var applyMinPrice = function(minPrice) {
var existingParams = (location.href.indexOf('?') !== -1),
separator = existingParams ? '&' : '?',
newParams = separator + 'priceMin=' + minPrice;
location.href += newParams;
}
If you're having the user fill out a textfield with a minimum price, why not let the form submit as a GET-request with a blank action? IIRC, that should do just what you want, without any javascript.
<FORM action="" method="get">
<P>
<LABEL for="brand">Brand: </LABEL>
<INPUT type="text" id="brand"><BR>
<LABEL for="priceMin">Minimum Price: </LABEL>
<INPUT type="text" id="priceMin"><BR>
</P>
use var urlString = window.location to get the url
check if the url already contains a '?' with urlString.indexOf('?'), -1 means it doesnt exist.
set window.location to redirect
this is like 101 of javascript. try some search engines!
<html>
<body>
..
..
..
<?php
$priceMinValue= addslashes ( $_GET['priceMin']);
if (!empty($priceMin)) {
$link = "currentpage.php?priceMin=". $priceMinValue;
die("<script>location.href = '".$link. "'</script>");
}
?>
</body>
</html>

Categories