Is there a way to remove %20 from dynamically created breadcrumbs? - javascript

So, I was messing around with this Dynamic Breadcrumbs write-up, and came across an issue where if the directory name has a space in it, then %20 gets added to the actual visible breadcrumb. Would this be removed using the decodeURI() function or is there a better way?
Here's the js:
var crumbsep = " • ";
var precrumb = "<span class=\"crumb\">";
var postcrumb = "</span>";
var sectionsep = "/";
var rootpath = "/"; // Use "/" for root of domain.
var rootname = "Home";
var ucfirst = 1; // if set to 1, makes "directory" default to "Directory"
var objurl = new Object;
// Grab the page's url and break it up into directory pieces
var pageurl = (new String(document.location));
var protocol = pageurl.substring(0, pageurl.indexOf("//") + 2);
pageurl = pageurl.replace(protocol, ""); // remove protocol from pageurl
var rooturl = pageurl.substring(0, pageurl.indexOf(rootpath) + rootpath.length); // find rooturl
if (rooturl.charAt(rooturl.length - 1) == "/") //remove trailing slash
{
rooturl = rooturl.substring(0, rooturl.length - 1);
}
pageurl = pageurl.replace(rooturl, ""); // remove rooturl from pageurl
if (pageurl.charAt(0) == '/') // remove beginning slash
{
pageurl = pageurl.substring(1, pageurl.length);
}
var page_ar = pageurl.split(sectionsep);
var currenturl = protocol + rooturl;
var allbread = precrumb + "" + rootname + "" + postcrumb; // start with root
for (i=0; i < page_ar.length-1; i++)
{
var displayname = "";
currenturl += "/" + page_ar[i];
if (objurl[page_ar[i]])
{
displayname = objurl[page_ar[i]];
}
else
{
if (ucfirst == 1)
{
displayname = page_ar[i].charAt(0).toUpperCase() + page_ar[i].substring(1);
}
else
{
displayname = page_ar[i];
}
}
if ( i < page_ar.length -2 )
{
allbread += precrumb + crumbsep + "" + displayname + "" + postcrumb;
}
else
{
allbread += crumbsep + displayname;
}
}
document.write(allbread);
If decodeURI() was to be used, where exactly would it go? Also, more unrelated, would there be an option you could add to the code above that would make the actual page inside of the directory be included in the breadcrumbs as the last item instead of the last directory? Not real important but thought I would ask as well. Thanks for any input!

Yes, decodeURI will do the trick. You can add the line displayname = decodeURI(displayname); right before the if that reads if ( i < page_ar.length -2 ):
...
displayname = decodeURI(displayname);
if ( i < page_ar.length -2 )
...
Note that since displayname and currenturl end up being directly embedded in a raw HTML string, any special HTML characters should be escaped first, otherwise you're open to some XSS attacks (imagine some malicious individual posting a link to your site like yoursite.com/valid/page/%3Cscript%3Ealert%28%22Oh%20no%2C%20not%20XSS%21%22%29%3C%2Fscript%3E). One of the simplest ways to do so is covered by this answer, though it requires jQuery.
If you want the current page included in the breadcrumbs, I believe it is sufficient to change the loop to go from 0 to page_ar.length instead of page_ar.length - 1:
...
for (i=0; i < page_ar.length; i++)
...

You should use decodeURIComponent(), not decodeURI() for this. It's a little hard to see what you're trying to do, but here's some simpler code that will give you an array of the 'directories' in the current URI, decoded:
var dirs = location.pathname.split('/');
for (var i=0,len=dirs.length;i<len;++i){
dirs[i] = decodeURIComponent(dirs[i]);
}

Related

URL parameters are reordered when using anchor links with Inheriting UTMS

I am using a javascript on my site, which always inherits the UTM parameters to the links on the site.
However, this is not working, when the links are anchor links to a section of the site and the link the visitor used to visit the page contains the "gclid" parameter from google.
For example:
A visitor uses this link to visit a site:
domain.com?utm_source=test&utm_medium=test&utm_campaign=test&gclid=12345
The button link on the site with the anchor link will look like the following:
domain.com&gclid=12345?utm_source=test&utm_medium=test&utm_campaign=test#anchor
For some reason the "&gclid" part changes its position.
I've tested it with a link without an anchor and in this case the "gclid" parameter doesn't get inherited and the link works.
Of course, the second domain isn't working anymore and leads to a 404 error.
Does someone have an idea what could be the cause for this?
This is the javascript I am using to inherit the UTMs:
(function() {
var utmInheritingDomain = "grundl-institut.de"
utmRegExp = /(\&|\?)utm_[A-Za-z]+=[A-Za-z0-9]+/gi,
links = document.getElementsByTagName("a"),
utms = [
"utm_medium={{URL - utm_medium}}",
"utm_source={{URL - utm_source}}",
"utm_campaign={{URL - utm_campaign}}"
];
for (var index = 0; index < links.length; index += 1) {
var tempLink = links[index].href,
tempParts;
if (tempLink.indexOf(utmInheritingDomain) > 0) {
tempLink = tempLink.replace(utmRegExp, "");
tempParts = tempLink.split("#");
if (tempParts[0].indexOf("?") < 0) {
tempParts[0] += "?" + utms.join("&");
} else {
tempParts[0] += "&" + utms.join("&");
}
tempLink = tempParts.join("#");
}
links[index].href = tempLink;
}
}());
EDIT: It seems like the following script don`t causes this problem:
<script>
(function() {
var domainsToDecorate = [
'domain.com',
],
queryParams = [
'utm_medium',
'utm_source',
'utm_campaign',
]
var links = document.querySelectorAll('a');
for (var linkIndex = 0; linkIndex < links.length; linkIndex++) {
for (var domainIndex = 0; domainIndex < domainsToDecorate.length; domainIndex++) {
if (links[linkIndex].href.indexOf(domainsToDecorate[domainIndex]) > -1 && links[linkIndex].href.indexOf("#") === -1) {
links[linkIndex].href = decorateUrl(links[linkIndex].href);
}
}
}
function decorateUrl(urlToDecorate) {
urlToDecorate = (urlToDecorate.indexOf('?') === -1) ? urlToDecorate + '?' : urlToDecorate + '&';
var collectedQueryParams = [];
for (var queryIndex = 0; queryIndex < queryParams.length; queryIndex++) {
if (getQueryParam(queryParams[queryIndex])) {
collectedQueryParams.push(queryParams[queryIndex] + '=' + getQueryParam(queryParams[queryIndex]))
}
}
return urlToDecorate + collectedQueryParams.join('&');
}
// borrowed from https://stackoverflow.com/questions/831030/
// a function that retrieves the value of a query parameter
function getQueryParam(name) {
if (name = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(window.location.search))
return decodeURIComponent(name[1]);
}
})();
</script>
You really should not change URLs with regexp and string manipulation.
Here is the recommended way
const url = new URL(location.href); // change to tempLink
utms = [
"utm_medium=med",
"utm_source=src",
"utm_campaign=camp"
];
utms.forEach(utm => url.searchParams.set(...utm.split("=")))
console.log(url.toString())

Adding URL Parameters to a link within a document jquery

I'm having trouble, grabbing the parameters from a link and appending them to the end of the link. I can change the text of an element but not the attribute. See my not working example.
$(document).ready(function() {
var urlParams = window.location.search;
if (urlParams) {
// remove leading '?' if present
var cleanUrlParams = (urlParams[0]=='?') ? urlParams.substring(1, urlParams.length) : urlParams;
// remove leading and trailing '&' if present
var cleanUrlParams = (cleanUrlParams[0]=='&') ? cleanUrlParams.substring(1, cleanUrlParams.length) : cleanUrlParams;
var cleanUrlParams = (cleanUrlParams[cleanUrlParams.length - 1]=='&') ? cleanUrlParams.substring(0, cleanUrlParams.length - 1) : cleanUrlParams;
// include only the url params with values
var includeUrlParams = "";
var urlParamPairs = cleanUrlParams.split("&");
for (var i = 0; i < urlParamPairs.length; i++) {
var splitUrlParamPair = urlParamPairs[i].split("=");
if ((splitUrlParamPair.length == 2) && (splitUrlParamPair[1].length > 0)) {
if (includeUrlParams.length > 0) {
includeUrlParams = includeUrlParams + "&";
}
includeUrlParams = includeUrlParams + urlParamPairs[i];
}
}
// if there are url parameters then append them to something in the DOM
if (includeUrlParams.length > 0) {
$(".editMyUrlParams").attr("href" + includeUrlParams);
}
}
});
And then calling it like this
<a class="editMyUrlParams" href="http://thisisawebsite.com/">This is a link</a>
This is where I go wrong I think. If I change the following to text - it works
if (includeUrlParams.length > 0) {
$(".editMyUrlParams").text("There are the params: " + includeUrlParams);
}
So I know I'm missing something where I can append the attributes to the end of the href and get a result like this
<a class="editMyUrlParams" href="http://thisisawebsite.com/?param1=this1&param2=this2">This is a link</a>
Thanks in advance for any help
Use the jQuery .attr() method:
$(".editMyUrlParams").attr('href', $(".editMyUrlParams").attr('href') + stringToAppend);
Or better:
var $elements = $(".editMyUrlParams");
var oldHrefValue = $elements.attr('href');
var newHrefValue = oldHrefValue + stringToAppend;
$elements.attr('href', newHrefValue);

Check IFRAME URL and reload if found - Javascript

I'm trying to get the page name of the iframe page (that is on the same server) and if it's not the following name(s): 'index1.php' or 'indexTOM.php' then don't do anything if it is that page name then reload the iframe. Here is now I have it set but it doesn't work for some reason the resultNfo is always true and the iframe never reloads?
//Check URL of IFRAME
var currentUrl = document.getElementById("frmcontent").contentWindow.location.href;
var word = 'index1.php';
var regex = new RegExp( '\\b' + word + '\\b' );
var resultNfo = regex.test( currentUrl );
if (resultNfo = true){ document.getElementById("frmcontent").contentDocument.location.reload(true); }
var word = 'indexTOM.php';
var regex = new RegExp( '\\b' + word + '\\b' );
var resultNfo = regex.test( currentUrl );
if (resultNfo = true){ document.getElementById("frmcontent").contentDocument.location.reload(true); }
alert('URL is: '+currentUrl+'\n'+resultNfo);
Why don't you just do resultNfo = currentUrl.indexOf('indexTOM.php') !== -1 ?
You also have a lot of problems here, you should use a for loop really
Not tested demo
var urls = ['indexTOM.php', 'index1.php'],
frame = document.getElementById('frmcontent').contentDocument;
for( var i = 0; i < urls.length; i++ ) {
var url = urls[i];
if( frame.location.href.indexOf(url) !== -1 ) {
frame.location.reload()
}
}
Try something along the lines of the above code, it's a lot cleaner.

base url using jQuery

How to get base url in jQuery?
Think I am in http://localhost/test/test_controller/test's js file then I want to get only
/test
or
http://localhost/test/
You dont actually need to use jQuery. JavaScript provides this for you
var l = window.location;
var base_url = l.protocol + "//" + l.host + "/" + l.pathname.split('/')[1];
You can also use this custom method :
// it will return base domain name only. e.g. yahoo.co.in
function GetBaseUrl() {
try {
var url = location.href;
var start = url.indexOf('//');
if (start < 0)
start = 0
else
start = start + 2;
var end = url.indexOf('/', start);
if (end < 0) end = url.length - start;
var baseURL = url.substring(start, end);
return baseURL;
}
catch (arg) {
return null;
}
}
If you're getting the current page's url, check out the link object.
You'll probably want document.hostname or document.host.
If your looking for the hostname of a link inside the document, see this conversation

How to handle Querystring in JavaScript?

I have a js code:
window.onload = function() {
document.getElementById("Button1").onclick = function() {
var t1 = document.getElementById("Text1").value;
var t2 = document.getElementById("Text2").value;
document.URL = 'myurl?t1=' + t1 + '&t2' + t2;
}
}
Here i am adding t1,t2 as query param..now my question is lets say i have entered some data in Textbox1 but not in textbox2, in that case the url I am getting is
'myurl?t1=' + value of textbox1 + '&t2' + This will be blank;
I want to make it dynamic, i.e.if there is not value in Textbox2 then I dont want to append queryparam t2, same goes for t1 also..isit possible?
Use if clauses.
var url = "";
if (t1)
url += "&t1=" + encodeURIComponent(t1);
if (t2)
url += "&t2=" + encodeURIComponent(t2);
document.URL = "myurl" + url.replace(/^&/, "?");
Or even better, don't use JavaScript at all. Just use a form with action="get". This is exactly what they're for.
document.URL = 'myurl?t1=' + t1 + (''!=t2 ? '&t2' + t2 : '');
simply, use (? true:false) logic construction to test if var t2 is empty or not. If it's not empty add to document.URL '&t2'+t2, otherwise pass nothing.
document.URL = 'myurl?t1=' + t1 + (t2?'&t2' + t2:'');
I personally use this function for creating queries:
function CreateQuery(URL, D) {
// Returns a URL in format "URL?Key1=Value1&Key2=Value2"
var L = [];
for (var k in D) {
if (!D.hasOwnProperty(k)) continue;
var eK = encodeURIComponent(k);
var eV = encodeURIComponent(D[Key]);
L.push(eK+'='+eV);
}
if (L.length)
return URL+'?'+L.join('&');
return URL;
}
To use it, you might go e.g:
var q = {};
if (t1) q['t1'] = t1;
if (t2) q['t2'] = t2;
window.location = CreateQuery('myurl', a);
(Or use a <form>, which is probably still the better option as another user has suggested :-)

Categories

Resources