jquery multiple links text replacement from id in target href page - javascript

I'm experimenting with jquery, and thought it would be comfortable to have my links get their content from their source. I'm not really sure it's possible though.
<a href="page1.html" >pagetitle</a>
<a href="page2.html" >pagetitle</a>
What I want to achieve is replace "pagetitle" with text from #title id, ex : "My page 1" from target, for every link, on pageload.
Source element in the pages :
<h1 id="title">My page 1</h1>
Desired output :
<a href="page1.html" >My page 1</a>
<a href="page2.html" >My page 2</a>
I tried various solutions but I can't achieve the desired behavior.
If impossible with jquery, telling me will also help ! Thanks for your time.
Edit : I tried some basic lines as follow :
This works, but of course with only one page so obviously every title is the same.
$( 'a' ).load( 'page1.html .title' ).text();
These won't work, maybe I'm a bit clumsy !
$( 'a' ).load( 'a.attr("href") .title' ).text();
var distantcontent = $('a.attr("href")');
$( 'a' ).load( 'distantcontent .title' ).text();

Try this... It works with the test pages I made.
See comments in code.
$(document).ready(function(){
// Get all the href (If there is!)
var hrefArray = [];
$("a").each(function(){
if( $(this).attr("href") !="#" && $(this).attr("href") != "undefined" ){
hrefArray.push( $(this).attr("href") );
}
});
var i = 0;
function getTitles(href, i){
$.ajax({
url: href,
success: function(response){
// Stringify the result
var responseString = response.toString();
// Get the index of the title tag
var titleTagIndex = responseString.indexOf("<title>");
// If the title tag IS found
if(titleTagIndex != -1){
// Find the index of the title closing tag
var titleClosingTagIndex = responseString.indexOf("</title>");
// Get the sub-string between the two indexes we found.
title = responseString.substr(titleTagIndex+7,titleClosingTagIndex-(titleTagIndex+7));
console.log("Title found: "+title);
// Replace the link text.
$("a").eq(i).text(title);
}
// Get the next title
i++;
if(i<hrefArray.length){
getTitles(hrefArray[i], i);
}
},
error: function(request, status, error){
console.log(error);
}
})
}
// Get the first title
getTitles(hrefArray[i], i);
});
Now, the titles are requested one by one using ajax.
You WILL notice the delay for it to populate the titles on load.
If you also have external links on your page, instead of $("a"), use a class to target your "same domain" links... Because the ajax wil fail on external links and just stop the looping.

You need to iterate through the individual elements. Something like this:
$('a').each(function() {
u = $(this).attr('href');
console.log('$(this).load(' + u + ' .title)');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
My page 1
My page 2

Related

Unable to get offset of an element

I am trying to get offset of some elements which is working fine for me. But the problem occurs if element id contains single quotes. It throw an error, e.g, if the element id is whats_next its working fine.
But if id is what's_next if gave me an error.
Error: Syntax error, unrecognized expression: #What's_Next
....value:null},t.error=function(e){throw new Error("Syntax error, unrecognized exp...
Also I don't have access over HTML I can not change the HTML. Do you guys have any solution for this ?
Here is my code:
$('.custom-toc li a').click(function(){
var id = $(this).attr('href');
console.log(id);
console.log($(id).offset());
});
HTML of element where I am clicking:
<a rel="internal" href="#What's_Next">What's Next</a>
HTML of element offset element:
<span id="What's_Next"></span>
<h4 class="editable">What's Next2</h4>
You can escape ' using replace()
HTML:
<div class="custom-toc">
<ul>
<li>
dddfs
</li>
</ul>
</div>
<span id="What's_Next">hello</span>
<h4 class="editable">What's Next2</h4>
JS :
$('.custom-toc li a').click(function(){
var id = $(this).attr('href').replace(/([ #;&,.+*~\':"!^$[\]()=>|\/#])/g,'\\$1');
console.log(id);
console.log($(id).offset());
});
Have you tried going for the id as attribute approach?
Like this:
var id = "What's Next";
var elem = $("span[id="+id+"]");
Well I tried, and it doesn't work :) - Cudos to Garvit, he has it right, this is his solution (only simplified):
var id = $(this).attr('href');
console.log(id);
id = id.replace("'","\\'");
console.log($("#"+id).offset());
Here's another way to do it without escaping the quote, although it requires you to remove the hash from the front of the href (and also, using $("*") is slow)
$('.custom-toc li a').click(function() {
var href = $(this).attr('href').substring(1);
var a = $("*").filter(
function(index) {
return $(this).attr('id') == href;
}
);
console.log($(a[0]).offset());
You can't use the ' symbol inside your div's id - You should change
<span id="What's_Next"></span>
to
<span id="Whats_Next"></span>
EDIT:
because You can't/don't want to change div's id You are working on an invalid code. You should consider debugging it first to further work.
EDIT 2:
Thanks to #Tibrogargan comment I've checked the w3c recommendation and he's probably right:
id = ID A unique identifier for the element. There must not be
multiple elements in a document that have the same id value. Any
string, with the following restrictions:
must be at least one character long
must not contain any space characters
Source: w3c.org

change url using jquery for specific css classes

I am using below code to covert all links in a page - Now i want this conversion to happen only for certain parts of page and not for complete page. I am sure this can be done to specific div tags
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$( document ).ready(function() {
$("a[href^='http']").each(function() {
var value = $(this).attr('href');
$(this).attr('href','<url>/pqr.php?'+value);
});
});</script>
Please suggest how can i achive this link conversion for specific div tags.
Example to explain problem statement - Consider following code snippet on which url conversion is required for only class="testclass"
<div class="messageContent">
<article>
<blockquote class="messageText SelectQuoteContainer ugc baseHtml">
<div class="testclass">
Amazon 1
</div>
<i>eps</i><br>
<span style="text-decoration: underline"><b><i>How to avail this offer </i></b></span><br>
<i>Add product into the cart<br>
Login or register<br>
Enter your shipping details<br>
Make the Final Payment.</i><br>
<span style="text-decoration: underline"><span style="font-size: 12px"><b>link</b> </span></span><br>
Amazon 2
<div class="messageTextEndMarker"> </div>
</blockquote>
</article>
</div>
I want to convert only the first url (AMAZON 1) and not the second url (AMAZON 2)
Test snippet on js fiddle - http://jsfiddle.net/bontp6jk/4/
What you want to do is first define the parent class and then for that class select all the link elements.
In jQuery you can use multiple selectors that works as follows:
$("#test") // select div 'test'
$(".myClass") // select class 'myClass'
$(".myClass #test") // select div 'test' in class 'myClass'
$("a") // select all link elements
Therefore, what you need is the following: $(".testclass a") which selects all link elements in the class .testclass. Then you can use jQuery .each() function to do something with the link elements.
$( document ).ready(function() {
$(".testclass a").each(function() {
var value = $(this).attr('href');
alert(value);
});
});
jsFiddle
Try this
$( document ).ready(function() {
$("a[href^='http']").each(function() {
var $this = $(this);
var value = $this.attr('href');
if($this.closest('.testclass').length!==0){
$this.attr('href','http://test.com/url.php?url=' + value + '&uid=test&origin=forum');
$this.attr("target","_blank");
}
});
});

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.

How to keep the selected menu active using jquery, when the user comes back to page?

I have a typical menu structure -
<Ul class="nav">
<li>Menu1</li>
<li>menu2</li>
-------
</ul>
When I click on certain menu, as per my jquery written on load of layout.html, it selects particular menu.
<script>
jQuery(function(){
jQuery('.nav>li>a').each(function(){
if(this.href.trim() == window.location)
$(this).addClass("selected");
});
</script>
But on that page if I click on certain link which takes me on some other page and then when I come back the menu item does not remain selected.
How can I modify my jquery to achieve this?
Thanks in advance !
As SJ-B is saying, HTML5 Web Storage is a good solution.
If you don't intend to click more than one or two pages away from the page with your list menu, you could add a query to the link that takes you away form the page e.g. the id of one of your list menus.
href="somepage.html could become something like this href="somepage.html?menu_id=menu5
When using window.history.back(), you could then fish the id out of the URL using window.location.search and use id to select the list menu.
You can use simple css code. Use active attribute like
a:active
{
//Some style
}
You can use below code to achieve this.
var lastele=siteurl.substring(siteurl.lastIndexOf("/")+1);
jQuery(".nav>li> a").each(function(){
var anchorhref=jQuery(this).attr("href");
var finalhref=anchorhref.substring(anchorhref.lastIndexOf("/")+1);
if(finalhref==lastele){
jQuery(this).addClass("selected");
}
});
I would do something like this :
<ul class="nav">
<li id="home">Home</li>
<li id="contact">Contact</li>
</ul>
Javascript :
// http://mywebsite.com#home
// location.hash === '#home'
jQuery('.nav ' + location.hash).addClass('selected');
Try to use Session Object of HTML5.
sessionStorage.varName = id of selected item.
on load just check if the sessionStorage.varName has value or undefined, if not then get the value
`var value = sessionStorage.varName;` and set it.
Well there could be many ways, on which is this which i like and always use:
It works when you path name is same as your link name For e.g. yourwebsite.com/Menu1
function setNavigation() {
var n = window.location.pathname,t;
n = n.replace("/", "");
t = $("ul li:contains(" + n + ")");
t.addClass("active");
}
You can than define styling in your active class as you like.
I stumbled upon this when googling for something similar. I have a JQueryUI accordion menu. My menu is in an included script (classic asp), so it is on every page but I think it is a similar situation. I cobbled something together based on SJ-B's answer (don't know why it was down voted).
I have this:
function saveSession(id) {
if (window.sessionStorage) {
sessionStorage.activeMenu = $("#jqmenu").accordion("option", "active") ;
sessionStorage.activeLink = id ;
}
}
and this
$(function() {
//give every li in the menu a unique id
$('#jqmenu a').attr('id', function(i) {
return 'link'+(i+1);
});
var activeMenu = 0;
var activeLink = "";
if (window.sessionStorage) {
activeMenu = parseInt(sessionStorage.activeMenu);
activeLink = sessionStorage.activeLink;
}
$("#" + activeLink).parent().addClass("selectedmenu");
$("#jqmenu").accordion({collapsible: true, active: activeMenu, heightStyle: "content", header: "h3"});
$("#jqmenu a").click(function() { saveSession($(this).attr('id')); });
});
OK, a bit untidy and cobbled together from various suggestions (I'm still learning), but it seems to work. Tried on IE11 and Firefox. Chrome can't find localhost but that's another story.
add lines below
<script>
$(function(){
$("a[href='"+window.location+"']").addClass("selected");
});
</script>
var url = window.location.pathname,
urlRegExp = new RegExp(url.replace(/\/$/, '') + "$");
$('.nav li').each(function () {
if (urlRegExp.test(this.href.replace(/\/$/, ''))) {
$(this).addClass('active');
}
});

How to replace a link with another set of links in jQuery?

This question is linked to How can a Greasemonkey script split a link into three related links?.
In the answer given (which works) by the way, the method is to modify the initial link and append the other links to it. However it is designed for a commit comment linked to a single Redmine issue. I modified it so
$('a[title]').each( function () {
redmineURL = getProjectURL($(this).attr('title'));
});
$("a[href*='/commit/']").each ( function () {
/*-- Parse each link for the expected format:
refs #{number} {description text}
*/
var jThis = $(this);
if ($(this).text().match(/#\d+\b/g)) {
var commitText = $(this).text();
var cgitURL = $(this).attr('href');
//$(this).text (commitText[1]);
$(this).after(processLinkedCommit(redmineURL, commitText, cgitURL));
}
} );
With this method the original link should be replaced with the output of the function processLinkedCommit. redmineURL is Redmine project with the issue, which is computed from the a 'title' attribute in the page. commitText is the text of the commit which is in the link of Cgit page and cgitURL is the href attribute.
I want to replace the original link with up to about 10 URLs created by processLinkedCommit. It appears I will have to delete $(this) and replace it with the list of URLs, ie I have to put it after its previous sibling. How would I do this in jQuery?
After some more thought and looking up the docs, I came up with this solution. The replacements URLs are appended using the .after() function and the original link is removed using the .remove() function;
$('a[title]').each( function () {
redmineURL = getProjectURL($(this).attr('title'));
});
$("a[href*='/commit/']").each ( function () {
if ($(this).text().match(/#\d+\b/g)) {
var commitText = $(this).text();
var cgitURL = $(this).attr('href');
$(this).after(processLinkedCommit(redmineURL, commitText, cgitURL));
$(this).remove();
}
});

Categories

Resources