Script inside href how to - javascript

I'm using this link:
It is intended for use as a bookmark. When clicked it redirects the user to an url that takes the previous location removing the 7 first characters from it.
Instead of removing the first 7 characters from '+encodeURI(location.href)' I want it to do this:
if(encodeURI(location.href).match(/http:\/\//))
{
encodeURI(location.href).substring(7);
}
if(encodeURI(location.href).match(/https:\/\//))
{
encodeURI(location.href).substring(8);
}
if(encodeURI(location.href).match(/^www\./))
{
encodeURI(location.href).substring(4);
}
How could make this work inside the href?
thanks

How about something like this:
location = 'http://www.linkimprov.com/?ref=' + encodeURI(
location.href.match(/(?=https?:\/\/)?(?=www\.)?(.*)/)[1]
).substring(7);
Or in a link:
EDIT: Try this:
location = 'http://www.linkimprov.com/?ref=' + encodeURI(
location.href.match(/^(https?:\/\/)?(www\.)?(.*)/).pop()
).substring(7);

Related

Javascript Help - my breadcrumbs script to work correctly

Can someone take a look at this and tell me what I'm doing wrong? Basically the script is supposed to grab the URL of the page, splits the URL into an array via '/' and then document writes the HTML href link for each subdirectory. It kinda works until there is a webpage that is 2 folders deep from the root, and then it messes up.
If this is the URL for example: website.com/root/folder/subfolder/page.html it gives me:
> Home / Folder / Subfolder / Page
visually on the page, which is correct. (website.com/root/ is the actual home page.)
The link for 'Home' is correct and takes you to website.com/root/.
The second link for 'Folder' is correct and takes you to website.com/root/folder/.
However, the third link for 'Subfolder' is wrong and for some reason links to website.com/root/ again.
It's got to be something on line 14 where it says getLoc(i-3,subs[i],subs.length)+defp+ but I can't figure out what I'm missing.
Here is the script:
function breadCrumbs(base,delStr,defp,cStyle,tStyle,dStyle,nl) {
tit=document.title.replace(/Ak DRB > /g,"");
loc=window.location.toString();
subs=loc.split("/");
document.write('<strong>></strong> Home '+'<span class="'+dStyle+'">'+delStr+'</span> ');
if (loc.includes(".html") && !loc.includes("index.html")) {
a=1;
}else{
a=2;
}
for (i=4;i<(subs.length-a);i++) {
SUB=makeCaps(unescape(subs[i]));
document.write(''+SUB+' '+'<span class="'+dStyle+'">'+delStr+'</span> ');
}
if (nl==1) document.write("<br>");document.write('<span class="'+tStyle+'">'+tit+'</span>');
}
function makeCaps(a) {
g=a.split(' ');for (l=0;l<g.length;l++) g[l]=g[l].toUpperCase().slice(0,1)+g[l].slice(1);
return g.join(" ");
}
function getLoc(c,e,f) {
var d="";
if (c>0) {
for (k=0;k<c;k++) d=d+"../";
}else{
d="../"+e+"/";
}
return d;
}
OMG, I got it to work. I just had my relative path structure wrong and was trying to make it too complicated. All you need for the final getLoc function is:
function getLoc(c,e,f) {
var d="";
var g=f-5;
if (c==g) {
d="./";
}else{
d="../";
}
return d;
}

Using window.history.pushState multiple times, for a URL with multiple /

So I'm trying to achieve that when a user first chooses a category (from a list or something similar) the URL will go from
www.website.com/products/
to
www.website.com/products/category1
The user the gets presented with multiple subcategories, and when a user proceed to choose one of those, i want the URL go from:
www.website.com/products/category1
to
www.website.com/products/category1/subcategory1
For a illustration, see this
Regardless i have played around with the .pushState, and it works great for my category1, but when i press the subcategory1-2-3, it just keeps adding the stuff to the URL.
In my first event handler i do:
window.history.pushState(null, null, jQuery(this).attr('category'));
and that gives me the correct address im looking for /products/category1/
But when i then try to do:
window.history.pushState(null, null, jQuery(this).attr('category') + "/" + jQuery(this).attr('subcategory'));
It will simply just keep adding stuff to my URL, what exactly am i doing wrong here?
The problem is that your URLs are relative to the current directory, which means that category/sub-category points to a different location depending on whether you are viewing https://example.com/products/category or https://example.com/products/category/sub-category.
You can see how the error accumulates by running the snippet below:
var url = 'http://example.com/products/'
function parseRelative (url, base) {
console.log(
'Relative: ', url,
'\nBase:\t ', base,
'\n => ', url = new URL(url, base).href
)
return url
}
for (var i = 0; i < 3; i++) {
url = parseRelative('category/sub-category', url)
}
.as-console-wrapper { min-height: 100%; }
Fixing the problem simply requires changing your URLs to the path-absolute form /products/...:
$('.example-button').click(modifyUrl)
function modifyUrl() {
var url = '/products/' + [$(this).attr('data-category'), $(this).attr('data-sub-category')].join('/')
history.pushState(null, '', url)
console.log(location.href)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="example-button" data-category="category" data-sub-category="sub-category">Click Me!</button>

Algolia search: access results onclick

I am using algolia search for my rails app, I sat up the auto completion method using typehead.js. But I can't redirect properly when I have uppercase in the URL... Here is my code:
// replace YourIndexName by the name of the index you want to query.
var index = algolia.initIndex('Pin');
// Mustache templating by Hogan.js (http://mustache.github.io/)
var template = Hogan.compile('<div class="hit">' +
'<a href="http://yhumans.com/{{{twitter}}}">'
+
'<div class="small-text">' +
'{{{ _highlightResult.name.value }}} ' +
'</div>' +
'<div class="small-text">' +
'#' +
'{{{ _highlightResult.twitter.value }}} ' +
'</div>' +
'</a>' +
'</div>');
// typeahead.js initialization
$('#user-search').typeahead(null, {
source: index.ttAdapter({ hitsPerPage: 5 }),
displayKey: 'twitter',
templates: {
suggestion: function(hit) {
// select matching attributes only
hit.matchingAttributes = [];
for (var attribute in hit._highlightResult) {
if (attribute === 'name' || attribute == 'twitter') {
// already handled by the template
continue;
}
// all others attributes that are matching should be added in the matchingAttributes array
// so we can display them in the dropdown menu. Non-matching attributes are skipped.
if (hit._highlightResult[attribute].matchLevel !== 'none') {
hit.matchingAttributes.push({ attribute: attribute, value: hit._highlightResult[attribute].value });
}
}
// render the hit using Hogan.js
return template.render(hit);
}
}
});
The problem is with this lines that I am using to let the user click on results to access page:
<a href="http://yhumans.com/{{{twitter}}}">'
In fact some of my users has capitalize letters in their twitter usernames, So I can't redirect properly to their profiles on search results.
Let me explain: http://yhumans.com/myname is a correct URL. http://yhumans.com/MyName is a wrong URL
I tried to use lowercase for that variable: "twitter". But I could not find a way to do it properly.
I know that one way to do it would be to lowercase the twitter variable. But the thing is that the function 'downcase!' doesn't seems to works in js.
Any ideas ?
First, two comments that won't answer the question directly, but are related:
with Hogan templates, you should use {{variable}} when the text shouldn't have HTML in it, and {{{variable}}} when it should. That's why you should use {{twitter}}.
Algolia has actually forked typeahead.js#0.10 into autocomplete.js, you should have a look at that.
That being said, you gave one solution, even if you are right, .downcase! doesn't exist, it's actually .toLowercase().
In your suggestion function, just lowercase the twitter attribute that way:
function (hit) {
hit.twitter = hit.twitter.toLowerCase();
// ...
}
One issue with that way of handling the autocomplete redirection is that the user won't be able to use his/her keyboard to chose the result. The recommended way with both autocomplete.js and typeahead.js is to use, respectively the autocomplete:selected or typeahead:selected event:
$('#user-search').typeahead(/* ... */).on('typeahead:selected', function (ew, selection, dataset) {
// Redirect to http://yhumans.com/my-twitter-name
window.location.href = 'http://yhumans.com/' + selection.twitter;
});
To display the current selection to the user when he/she hovers or picks the result with the arrows, you can put a different background color with .aa-hint (autocomplete.js) or .tt-hint (typeahead.js).

javascript unexpected token }

I have this block of code where I'm creating two link elements on a web page and adding a click event to them:
function createNewChat(){
//alert("new chat fired");
var roomName = document.getElementById("roomName").value
if (roomName){
resetErrorLog();
$('#createRoom').append('<p>would you like to password protect this room?</p>');
$('#createRoom').append('<div> yes </div>');
$('#createRoom').append('<div> no </div>');
}
else {
document.getElementById("errorlog").innerHTML = "<p>The room name input box seems to be empty</p>";
}
}
The DOM updates properly, but when I click the link I get an unexpected token } on line 2, which is an tag. This block of code is much later in the file. The helper method isn't getting fired at all so I'm pretty sure that the problem is with this code. Help is much appreciated.
onclick="newChatHelper("yes")" is a quoting issue in the HTML
You need to use onclick="newChatHelper('yes')" — notice the single quotes within the function call
But because you already have this in a single quote, you need to escape the inner single quotes, like this:
'<div> no </div>'
You could also consider not using the onclick attribute at all
$('#createRoom').append(
$('yes').click(function(event) {
newChatHelper("yes");
event.preventDefault();
}).wrap('<div/>').parent()
);
OR
$('#createRoom').append(
$('<div></div>').append(
$('yes').click(function(event) {
newChatHelper("yes");
event.preventDefault();
})
)
);
var roomName = document.getElementById("roomName").value
you may want to close this up with a ;
var roomName = document.getElementById("roomName").value;
var roomName = document.getElementById("roomName").value
by
var roomName = document.getElementById("roomName").value;

jQuery - remove li from array with delete image

I'm attempting to make a menu bar that can have <li> elements added and removed. So far so good, but when I try and remove them I'm running into issues. I've toyed with this for a couple hours and now I'm wondering if this whole process could just be made easier (maybe an object?).
Anyways, here's the full code (80 lines), with comments to follow along.
var tabs = $('.accountSelectNav');
var titles = [];
var listItems = [];
// when the page loads check if tabs need to be added to the ul (menu bar)
$(document).ready(function(e) {
if ($.cookie('listItems') != null) {
console.log('not null');
//return "listItems" to it's array form.
listItems = JSON.parse($.cookie('listItems'));
$('.accountSelectNav').append(listItems);
}
});
$('.selectTable td:first-child').on('click', function(e) {
$('#home_select').removeClass('navHighlight');
//grab the text value of this cell
title = $(this).text();
$.ajax({
url:'core/functions/getAccountId.php',
type: 'post',
data: {'title' : title}
}).fail (function() {
alert('error');
}).done(function(data) {
accountId = $.trim(data);
// store values in the cookie
$.cookie('account_id', accountId, {expires : 7});
$.cookie('title', title, {expires : 7});
window.location = ('home_table.php');
});
// make sure the value is NOT currently in the array. Then add it
var found = jQuery.inArray(title, titles);
if (found == -1) {
titles.push(title);
addTab();
}
// make sure the value is NOT currently in the array. Then add it
found = jQuery.inArray(title, listItems);
if (found == -1) {
addListItem();
//place <li>'s in cookie so they may be used on multiple pages
$.cookie('listItems', JSON.stringify(listItems));
};
});
$("body").on("click", ".deleteImage", function (e) {
var removeTitle = $(this).closest('li').find('a').text();
var removeItem = $(this).closest('li')[0].outerHTML;
//remove title from "titles" array
titles = jQuery.grep(titles, function (value) {
return value != removeTitle;
});
//remove <li> from "listItems" array
listItems = jQuery.grep(listItems, function (value) {
return value != removeItem;
});
// this shows the <li> is still in the listItemsarray
console.log(listItems);
// put the array back in the cookie
$.cookie('listItems', JSON.stringify(listItems));
removeTab(this);
});
$("body").on("mouseover", ".accountSelectNav li", function(e) {
$(this).find('.deleteImage').show();
});
$("body").on("mouseleave", ".accountSelectNav li", function(e) {
$(this).find('.deleteImage').hide();
});
function addTab() {
tabs.append('<li class="navHighlight">' + '' + title + '' + '' + '<img src="images/delete.png" class="deleteImage"/>' + '' + '</li>');
};
function removeTab(del) {
$(del).closest('li').remove();
}
function addListItem() {
var s = ('<li class="navHighlight">' + '' + title + '' + '' + '<img src="images/delete.png" class="deleteImage"/>' + '' + '</li>');
listItems.push(s);
}
So you see I have two arrays of equal length that should always be the same length. One stores the title to be displayed in the tab, the other holds the html for the <li> which will be appended to the <ul>. I have no problem removing the title from its array. However removing the <li> from it's array is becoming a rather big hassle. You see when I get the <li> element after its been inflated the html inside does not exactly match what was put in, the browser adds style elements.
Example, the variable "removeItem" represents the html value of the selected <li> I wish to remove. It looks like this:
<li class="navHighlight">Test1<img src="images/delete.png" class="deleteImage" style="display: inline;"></li>
yet the value in my array "listItems" looks like this:
<li class="navHighlight">Test1<img src="images/delete.png" class="deleteImage"/></li>
So my attempt at removing it from my array always fails because they aren't a perfect match.
Now my question is how do I remove this <li> item? Also is there an easier way to do this whole process and I'm just not seeing it?
Thanks for your time.
EDIT
Fiddle by request here
Easiest way I can explain it.
Click the link to the fiddle.
Click any cell in the "App Name" column
This will add a <li> to the <ul> (menu) above of the table
When you hover over the <li> a picture appears
Click the picture
This should remove the <li>, both from the <ul> and from the array listItems
right now it does not
In the process of making this easier to check, I've taken your JSFiddle and did the following:
removed extra console.log and comments
removed interaction with cookies (since I did not have them in the first place, I figured they wouldn't just the first scenario)
After doing so I reached a point (you can see it here) where the desired functionality just works.
I even went ahead and removed the ajax stuff because that alert was driving me crazy. (here)
Since this works fine, my guess is that your issue lies between the lines that I removed.
Your usage of cookies is as follows:
To load existing tabs and add them back again
To save account_id and title, which is not used back again
To persist the listItems after a new item has been added
I then opened up the console with your version of the fiddle and the execution of javascript stops at $.cookie() with the error undefined is not a function.
This clearly indicates that the issue present in the Fiddle is that jQuery.cookie is not present and so those calls are halting the execution of the rest of your script. This also explains why it just started working when I took them out.
I posted the whole process of how I got there to indicate how I trimmed down the problem to specific parts, which is useful to reduce the problem space. When you're out of options and reach a place when you're lost, it's easier to post a question with less code and the specific part of the problem that you've identified. This will help you in finding the issues that you're facing and StackOverflow to provide proper answers to your questions.
Hope it helps!
Here is the solution I came up with. It should be much easier for people to understand than my original post. Although it's a long read it may be worth it, especially for new developers.
The point of this code is to make a menu bar out of an un-ordered list or <ul>. The menu bar needs to be used on multiple pages. So I'll be using cookies.
I start with this code to get a text value from my table.:
$('.selectTable td:first-child').on('click', function(e) {
// This value will be used later for the name of the tab or `<li>` inside our menu bar or `<ul>`
title = $(this).text();
});
Then I place the value in an array. I do this only if the array does not already have this string inside it. I do not want duplicates:
var found = jQuery.inArray(title, titles);
var titles = [];
if (found == -1) {
titles.push(title);
}
Then I store the array into a cookie, using a library like this:
$.cookie('titles', JSON.stringify(titles));
Now when any page loads that needs this menu bar I run this code to check if there are any values:
$(document).ready(function() {
if ($.cookie('titles') != null) {
titles = JSON.parse($.cookie('titles'));
}
});
Now I need to loop through the array. When I loop through the array I have to do 3 things:
1) Grab the string value.
2) Add the html to my new string so it becomes a list item or <li>.
3) Append the newly created <li> to our <ul>.
Like so:
for(var i = 0; i < titles.length; i++) {
var str = titles[i];
var listItem = '<li class="navHighlight">'
+ '<a href="#">'
+ str
+ '</a>'
+ '<a href="#">'
+ '<img src="images/delete.png" class="deleteImage"/>'
+ '</a>'
+ '</li>';
$('.accountSelectNav').append(listItem);
}
Now, if I want to remove this <li> I click the delete image found inside our <li>. What delete image you say? Look at the html I added again. You will see I add an <img> tag in there.
Now delete like so:
$("body").on("click", ".deleteImage", function (e) {
// grabs the text value of my li, which I want to remove
var removeTitle = $(this).closest('li').find('a').text();
// runs through my titles array and returns an array without the value above
titles = jQuery.grep(titles, function (value) {
return value != removeTitle;
});
});
Then I simply place the new array inside my cookie once again. Like this:
$.cookie('titles', JSON.stringify(titles));
And finally I remove the tab like this:
removeTab(this);
function removeTab(del) {
$(del).closest('li').remove();
}
Yay, I'm done. So now, if anyone has a more elegant way of accomplishing this I'm listening. I have no doubt there's a better way, javascript/jQuery isn't even close to my strong point.
The full code can be found here.

Categories

Resources