Current selected item when some links are the same - javascript

I'm trying to create a stacked navigation list that highlights which item you have selected. It looks like this.
<div class="page-list">
<ul class="nav nav-pills nav-stacked">
<li><a href="Page1.html" > Page1 </a></li>
<li><a href="Page2.html" > Page2 </a></li>
<li><a href="Page3.html" > Page3 </a></li>
<li><a href="Page4.html" > Page4 </a></li>
<li><a href="Page5.html" > Page5 </a></li>
<li><a href="Unavailable.html" > Page6 </a></li>
<li><a href="Unavailable.html" > Page7 </a></li>
</ul>
</div>
The issue I am having is that the last two pages share the same link and I cant seem to get just the selected page to be highlighted in the list.
I was using this for my JavaScript.
<script>
$(function(){
$('a').each(function() {
if ($(this).prop('href') == window.location.href) {
$(this).addClass('current');
}
});
});
</script>
But this causes all links to the same page to highlight.
I tried solving it with this, but now no links highlight when clicked.
<script>
$(".page-list a").click(function() {
$(this).parent().previoussibling().find('a').removeClass('current');
$(this).addClass("current");
});
</script>

One way to fix this would be to create a query string to indicate which link should be highlighted.
...
<li><a href="Unavailable.html?page=6" > Page6 </a></li>
<li><a href="Unavailable.html?page=7" > Page7 </a></li>
...
Then in Javascript, read the query string and decide which page to highlight. This StackOverflow question can help you read the query string.
You could also accomplish this by using cookies if you don't want your users to see www.yourwebsite.com/Unavailable.html?page=7. See this tutorial for using cookies in JavaScript. There are a number of libraries out there that can help you when using cookies if you prefer that route.
Which ever way you choose to pass the information on to the next page, you will need to add an id to the a tags (or some other way to uniquely identify each link) so you can highlight the appropriate link.
Here is an example using the query string idea:
<div class="page-list">
<ul class="nav nav-pills nav-stacked">
...
<li><a id="6" href="Unavailable.html?page=6" > Page6 </a></li>
<li><a id="7" href="Unavailable.html?page=7" > Page7 </a></li>
</ul>
</div>
<script>
$(function(){
$('a').each(function() {
if ($(this).attr('id') == getParameterByName('page')) {
$(this).addClass('current');
}
});
});
function getParameterByName(name) {
//this code is taken directly from https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript#answer-901144
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
</script>

Related

How to expand certain part of a collapsible menu on page load based on a value

JSFiddle: http://jsfiddle.net/5qweu58f/4/
HTML (generated using XSLT):
<div id="dvExpProvHolder" class="hidOverflow innerDivCenter">
<ul class="uSPStyle" id="uSPStyle">
<li class="setRelative">
<a class="tfLink clickMe current" title="Care" data-toggle=".tfLink1" id="current" href="javascript:void(0);"><img src="theImages/imgMenu.png" id="imgFirstM" class="imgExpCol" />Care</a>
<ul class="uSPStyle uSPInner" style="width: 80%;">
<li><a class="tfLink clickMe" title="This is sub" data-toggle=".tf1SLink1" href="javascript:void(0);">This is sub</a></li>
</ul>
</li>
<li>
<a class="tfLink clickMe" title="Breast Cancer" data-toggle=".tfLink2" href="javascript:void(0);"><img src="theImages/imgMenu.png" id="imgFirstM" class="imgExpCol" />BC</a>
<ul class="uSPStyle uSPInner" style="width: 80%;">
<li><a class="tfLink clickMe" title="OUR LINK" data-toggle=".tf1SLink2" href="javascript:void(0);">OUR LINK</a></li>
</ul>
</li>
<li>
<a class="tfLink clickMe" title="About" data-toggle=".tfLink3" href="javascript:void(0);">About</a>
</li>
<li>
<a class="tfLink clickMe" title="Anxiety" data-toggle=".tfLink4" href="javascript:void(0);">Anxiety</a>
</li>
<li>
<a class="tfLink clickMe" title="Services" data-toggle=".tfLink5" href="javascript:void(0);">Services</a>
</li>
</ul>
</div>
Why doesn't the first UL lose the current class when another UL
is clicked? everything else works as expected.
The issue comes up when I would want the visitor to see BC > OUR LINK
section which shows "This is for second link sublink 1" without having to come to the page and then click on it. But because
they are all in one page, there is no way to do that out of the box.
I was wondering if there is a way to specify a query string in the
Url and use that to go directly to the sublink? For example:
http://www.myweb1.com/pages.aspx?id=098&menulink=2.1. The 2.1 would represent it is the second main menu and the first submenu. Is there
any way to incorporate that into my Jquery script?
Expanding on the examples from the authoritative question on the subject (How can I get query string values in JavaScript?) to solve this particular problem, you could use any of those methods for parsing window.location and taking action based on a query string parameter.
A working example is below, using a fake URL instead of window.location, as the snippet is in a sandboxed frame. This example uses URI.js, but there are many other options.
function log (o) {
var el = document.createElement('div');
el.innerHTML = o;
document.body.appendChild(el);
}
document.getElementById('button-1').onclick = function () {
log('Button 1 clicked!');
};
document.getElementById('button-2').onclick = function () {
log('Button 2 clicked!');
};
//Grab the "click" query string parameter. The button with the specified ID will be clicked.
//Using a fake URL instead of window.location inside this sandboxed frame
document.getElementById(URI('http://example.com?click=button-1').search(true)['click']).click();
<script src="https://cdnjs.cloudflare.com/ajax/libs/URI.js/1.16.1/URI.js"></script>
<button id="button-1">Button 1 - Auto-Clicked</button>
<button id="button-2">Button 2 - Not Auto-Clicked</button>

changing plus sign to minus when collapsed while keeping link

I'm pretty new to jQuery, so I admit I don't fully know what I'm doing. The top menu item is just text and not it's own link, but it has a dropdown. I'm trying to add a plus and minus sign before the text that toggles while keeping the original content clickable.
HTML
<div class="menu-clinical-materials">
<ul>
<li class="menu-item-has-children"><a>Clinical Studies & Articles</a>
<ul class="sub-menu" style="display: none;">
<li><a target="_blank" href="">Link 1</a></li>
<li><a target="_blank" href="">Link 2</a></li>
<li><a target="_blank" href="">Link 3</a></li>
<li><a target="_blank" href="">Link 4</a></li>
<li><a target="_blank" href="">Link 5</a></li>
</ul>
</li>
<li class="menu-item-has-children"><a>Counseling Sheets</a>
<ul class="sub-menu" style="display: none;">
<li><a target="_blank" href="">Link 1</a></li>
<li><a target="_blank" href="">Link 2</a></li>
<li><a target="_blank" href="">Link 3</a></li>
<li><a target="_blank" href="">Link 4</a></li>
<li><a target="_blank" href="">Link 5</a></li>
</ul>
</li>
</ul>
JS
jQuery.noConflict();
jQuery(document).ready(function () {
jQuery(".menu-item-has-children:has(ul)").prepend("<span class=\"Expander\">+</span>");
jQuery(".Expander").click(function () {
jQuery(this).html(jQuery(this).html() == "+" ? "-" : "+");
jQuery(this).toggleClass("Expanded").siblings("ul").slideToggle();
return false;
}).eq(0).addClass("Expanded").end().slice(1).siblings("ul").hide();
});
So I want "Clinical Studies & Articles" clickable, not just the +/- sign.
Here's what I have so far
EDIT
I was able to get it to work the way I wanted but using a different method. I'd still like to know how to do this with the .click function instead of toggle though. I'd appreciate it. Here's the fiddle with my workaround
Fiddle
Here is the changed JS
//<![CDATA[
jQuery.noConflict();
jQuery(document).ready(function () {
jQuery(".menu-item-has-children:has(ul)").prepend("<span class=\"plus-minus\">+</span>");
jQuery(".sub-menu").addClass('expander').hide();
jQuery('.menu-item-has-children').parent().toggle(function () {
jQuery(".plus-minus").text("-");
jQuery(".expander").slideDown();
}, function () {
jQuery(".plus-minus").text("+");
jQuery(".expander").slideUp();
})
});
Improved demo. Use event.stopPropagation() to prevent click on inner links to bubble and close the whole block.
//<![CDATA[
jQuery.noConflict();
jQuery(document).ready(function () {
jQuery(".menu-item-has-children:has(ul)").prepend("<span class=\"Expander\">+</span>");
jQuery(".menu-item-has-children").click(function () {
buttonText = jQuery(this).children('.Expander').html() == "+" ? "-" : "+";
jQuery(this).children('.Expander').html(buttonText);
jQuery(this).children('.Expander')
.toggleClass("Expanded").siblings("ul").slideToggle();
return false;
}).eq(0).slice(1).siblings("ul").hide();
});
//Prevent close on click of inner links.
jQuery(".sub-menu > li").click(function (e) {
e.stopPropagation();
});
//]]>

Why does this work? window.location.href

Example link: http://localhost/test/page.php?success
I'm curious about this. And I'm also new to JavaScript so it's not really a surprise but I understand the code below, I just do not know why it works away with what I seem to understand. See this question for more reference.
I have this JavaScript:
<script type="text/javascript">
jQuery(function($) {
var path = window.location.href.split( '?' )[0];
$('ul a').each(function() {
if (this.href === path) {
$(this).addClass('sub-menu active');
$(this).parent().closest("li").addClass('active');
$(this).parent().parent().closest("li").addClass('active');
}
});
});
</script>
The Sidebar:
<li class="sub-menu"> // Sidebar with no submenu
<a class="" href="page1.php">
<i class="icon-calendar"></i>
<span>This is page 1</span>
</a>
</li>
<li class="sub-menu"> // Sidebar with a submenu
<a href="javascript:;" class="">
<i class="icon-group"></i>
<span>This has sub pages</span>
<span class="arrow"></span>
</a>
<ul class="sub">
<li><a class="" href="page2.php">This is page 2</a></li>
<li><a class="" href="page3.php">This is page 3</a></li>
</ul>
</li>
The code puts an active class to the menu on the sidebar which href is equals to the current url. But window.location.href returns the whole url but what is inside the href's are just the page.php. So why does this.href === path work? When window.location.href.split( '?' )[0] returns http://localhost/test/page.php and the href is just page.php.
The href property of an anchor is normalized to an absolute value.
See this example:
HTML:
Test
JS:
var a = document.querySelector('a');
console.log(a.href);
In this instance the relative URL is being resolved to the location of the document containing the a element. You can use the base element to control the resolution of relative URLs.

Replace a URL on load using only class or url reference

I have some javascript that will find the current URL and set as li to class active. What I then need it to do so that the accordion menu will function correctly is to replace the URL in the associated a href with "#".
ie.
<li><a id="Create" href="../Create/Create.html"> Create</a>
needs to be changed to:
<li><a id="Create" href="#"> Create</a>
Here is my html:
<ul class="topnav">
<li class="">
<a id="Dashboard" href="../dashboard/dashboard.html"> Dashboard</a>
</li>
<li><a id="Create" href="../Create/Create.html"> Create</a>
<ul>
<li><a id="Monster" href="../Monster/Monster.html"> Monster</a>
<ul>
<li><a id="Custom" href="../Custom/Custom.html"> Custom</a>
<ul>
<li><a id="New" href="../New/New.html"> New</a></li>
<li><a id="Drafts" href="../Drafts/Drafts.html">> Drafts</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
And current Javascript that will give the current page a class of "active" on the corresponding "li" tag.
var url = window.location;
$('ul.topnav a').filter(function() {
return this.href == url;
}).parent().addClass('active');
This would be easily achieved utilizing the ID:
document.getElementById("Create").href="#";
but this is not an option due to the magnitude of the site. It needs to be done via javascript.
I've tried to do this with
document.getElementByClassName('li.active a').href="#";
but that is not working. I'm also concerned this might strip out all hrefs under that li.
Any help would be greatly appreciate!

Javascript function affecting other areas of page than what is specified

<div id="logo"><!-- logo -->
My Site
</div><!-- end logo -->
<?php
if ($_SESSION['uid'] == "")
{
echo "<div id='main_menu' class='log'>You are not logged in • <a href='login.php'>Login</a><br \></div>";
exit();
}
else
{
echo "
<div id='main_menu'>
<ul>
<li class='bar'> </li>
<li><a href='index.php' id='ajax_link'>Edit Site</a></li>
<li class='bar'> </li>
<li><a href='docs.php' id='ajax_link'>My Documents</a></li>
<li class='bar'> </li>
<li><a href='contacts.php' id='ajax_link'>Web Contacts</a></li>
<li class='bar'> </li>
<li><a href='social.php' id='ajax_link'>Social Media</a></li>
<li class='bar'> </li>
You are logged in as ".$_SESSION['username']." • <a href='logout_parse.php'>Logout</a><br \>
</ul>
</div>
";
}
?>
I've got this menu system built(above) and i'm using ajax and jquery to change in and out the main content(below) depending on the menu item selected.
var hash = window.location.hash.substr(1);
var href = $('#ajax_link').each(function(){
var href = $(this).attr('href');
if(hash==href.substr(0,href.length-4)){
var toLoad = hash+'.html #content';
$('#content').load(toLoad)
}
});
$('a').click(function(){
var toLoad = $(this).attr('href')+' #content';
$('#content').fadeOut('fast',loadContent);
window.location.hash = $(this).attr('href').substr(0,$(this).attr('href').length);
function loadContent()
{
$('#content').load(toLoad,'',showNewContent())
}
function showNewContent()
{
$('#content').fadeIn('normal');
}
return false;
});
however for some reason this code is affecting the login and logout links as well and i don't want that to happen.
I only recently added #ajax_links to try fix this problem as i was using #main_menu ul li a and #logo a before.
Can anyone tell me how i can fix this
First off, id attribute should be unique. Change all those links to use a class instead:
<li><a href='index.php' class='ajax_link'>Edit Site</a></li>
Now use that to improve the selector
$('a.ajax_link').click(function(){
....
And
$('.ajax_link').each(function(){
....

Categories

Resources