Active Nav Bar Menu Item CSS3 /HTML5 - php

I currently have this:
jQuery:
jQuery(document).ready( function(){
var thispage = location.pathname.substring(1);
//document.write(thispage);
jQuery('#menu li a[href~="'+ thispage + '"]') // ~= is contains. Tweak as needed.
.addClass('active');
});
CSS:
li.active {
background-color: yellow;
}
HTML:
<nav id="topNav">
<ul id="menu">
<li>HOME</li>
<li>ABOUT US</li>
<li> TECHNOLOGY</li>
<li>CAREERS
<li>BLOG
<!--<ul>
<li style="background-color:#898486;">OPPORTUNITIES</li>
</ul>-->
<li class="last">CONTACT US</li>
</ul>
</nav>
My goal is to each menu item to shade a different color when the page is active. I have tried numerous ways to fix this but I am unable to get this to work. in my CSS i even have an element item for :focus, but it only works when the href="#" and not with my current setup. What am I doing wrong here?

Got it to work with two changes:
jQuery('#menu li a[href*="'+ thispage + '"]').parent().addClass('active');
As I suggested in my comment use *= as "contains", not ~= ("contains word"), and I think you wanted to add the active class to the <li/>, not the <a/> tag.

Related

JQuery show and hide data from a query in list format that displays parent clickable list that opens its child list

I am going to try and explain this as clearly as I can.
I am working with some script from #Prabu Parthipan which uses JQuery to open and close child lists of parent lists.
I have a query that returns an array of data. In the array I have two fields:
SeqHeader
SeqText
Each SeqHeader has variable number of SeqText items.
Example:
SeqHeader:Bedroom Door & Frame (inside & Outside)
SeqText:Chipped - Scratched - Stained - Needs Paint
SeqText:Chipped - Threshold - Sand/Stain - Repair
SeqText:Door Hinges - Squeaks/Sticks - Requires Oil/Repair
SeqHeader:Entry Door Lock
SeqText:Room Door Handle/Strike plate - Not Secure/Not Working
SeqText:Security Door Chain - Not Working
SeqText:Room Door Dead Lock - Not operating Correctly
SeqHeader:Bathroom Door Lock
SeqText:Door Handle/Strike plate - Not secure/Not Working
SeqText:Door Lock - Inoperable
I could display the above as rows using a PHP do while loop but I though it would be better to produce a list with sublists that open and close.
So adopting Prabu Parthipan code
#Prabu Parthipan code is:
$(document).ready(function(){
$('ul li.expanded > a')
.attr('data-active','0')
.click(function(event){
$('.submuneu').hide();
if($(this).attr('data-active')==0){
$(this).parent().find('ul').slideToggle('slow');
$(this).attr('data-active','1');
}
else
$(this).attr('data-active','0');
});
$('a.on').click(function(){
$('a.on').removeClass("active");
$(this).addClass("active");
});
});
In the body of the page I have:
<?php do { ?>
<tr>
<td colspan="3" class="imaindateselleft_padding">
<div class="leftsidebar_templ1">
<ul id="nav">
<li class="expanded"><a class="on"><?php print $row_AuditItems['SeqHeader']; ?></a>
<ul class="submuneu">
<li><a><?php print $row_AuditItems['SeqText']; ?></a> </li>
</ul>
</li>
</ul>
</div>
</td>
<td class="imaindatesel"> </td>
</tr>
<?php } while ($row_AuditItems = mysql_fetch_assoc($AuditItems)); ?>
As it is when the page is loaded it displays a SeqHeader for each SeqText. They are clickable and when clicked they open up the sub list.
What I want to do is have all the SeqText items relating to thier parent SeqHeader as a sublist so when the SeqHeader is clicked all the related sub items show, and click again so they hide.
Sorry if I have rabbled on.
Any help would be great and I thank you for your time.
Cheers.
Wouldn't it make more since to make a simple to use multi-dimensional array of the items you're getting? As I gather, you're using the deprecated mysql call to get rows of info from a DB. Each row will have the Header and the Text associated. Thus, if you call inline by each, row, you'll have a header for each row. Try the following instead.
<?php
$res = array();
while ($row = mysql_fetch_assoc($AuditItems)) {
if ($row['SeqHeader'] && $row['SeqText']) {
if (!$res[$row['SeqHeader']]) $res[$row['SeqHeader']] = array();
$res[$row['SeqHeader']][] = $row['SeqText'];
}
}
?>
<ul id="nav">
<?php foreach ($res as $k => $v): ?>
<li class="expanded">
<a class="on"><?php echo $k; ?></a>
<ul class="submuneu">
<?php foreach ($v as $item): ?>
<li><a><?php echo $item; ?></a></li>
<?php endforeach; ?>
</ul>
</li>
<?php endforeach; ?>
</ul>
I believe you're biggest problem now is in HTML layout. But this should help that. Fix that and then determine if the JS is still a problem, though what you want in JS is relatively easy.
Example of Easy JavaScript for dealing with opening and closing submenus using HTML Markup as:
UL > LI > A + UL > LI > A
// simply jQuery shorthand for document.ready = function() { ...
$(function() {
// the following is how to add events so that they work for even "dynamically" created elements.
// That is, elements created after code/page load.
$(document).on('click', 'li a', function(e) {
e.preventDefault(); // ensure it doesn't try to follow a link
// close all possible siblings and cousins
$(this).parents('li').each(function(i) { $(this).siblings().find('ul').slideUp(); });
// slide toggle current possible sub menu
$(this).next('ul').slideToggle(function() { if (!$(this).is(':visible')) $(this).find('ul').hide(); });
});
// uncomment the following line to ensure all sublist are closed,
// however, i strongly recommend this should be done using css
// $('ul ul').hide();
// change cursor for li elements having a sub menu
$('li').each(function(i) {
if ($(this).children('ul').length) { // test if it has a submenu
$(this).css({ cursor: 'pointer' });
// just for this test, i'm going to add a background color to A tags on li's having a submenu
$(this).children('a').css({ backgroundColor: '#f8f800' })
}
});
})
/* this simply hides all submenus outright */
ul ul { display: none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li><a>test1</a>
<ul>
<li><a>bleh</a></li>
<li><a>bleh Blah</a>
<ul>
<li><a>blo</a></li>
<li><a>bli</a>
<li><a>blu</a>
<ul>
<li><a>orange</a></li>
<li><a>fruit</a></li>
<li><a>apple</a></li>
</ul>
</li>
<li><a>ble</a>
<ul>
<li><a>gravy</a></li>
<li><a>steak</a></li>
<li><a>bra</a></li>
</ul>
</li>
</li>
<li><a>testCc</a></li>
</ul>
</li>
</ul>
</li>
<li><a>test2</a>
<ul>
<li><a>testPrev</a>
<ul>
<li><a>testA</a></li>
<li><a>testB</a></li>
<li><a>testC</a></li>
</ul>
</li>
<li><a>testNext</a>
<ul>
<li><a>testAa</a></li>
<li><a>testBb</a>
<li><a>testPrev2</a>
<ul>
<li><a>testA1</a></li>
<li><a>testB2</a></li>
<li><a>testC3</a></li>
</ul>
</li>
<li><a>testNext4</a>
<ul>
<li><a>testAa4</a></li>
<li><a>testBb5</a></li>
<li><a>testCc6</a></li>
</ul>
</li>
</li>
<li><a>testCc</a></li>
</ul>
</li>
</ul>
</li>
<li><a>test3</a>
<ul>
<li><a>blah</a></li>
</ul>
</li>
</ul>
You could try:
$(document).ready(function(){
$('ul li.expanded > a')
.attr('data-active','0')
.click(function(event){
$('.submuneu').hide();
if($(this).attr('data-active')==0){
$(this).parent().find('ul').slideToggle('slow');
$(this).attr('data-active','1');
}
else
{
$(this).attr('data-active','0');
}
});
$(document).on('click', 'a.on', function(){
$('a.on').removeClass("active");
$(this).addClass("active");
});
});
Some -code generated- elements need to be "listen" using $(document).on('event', 'element', function(){...});.
Hope it helps.

CSS, PHP, HTML Active Dropdown Link Issue

so I have been having an issue with some PHP strings that I can't seem to figure out. The goal is to have the "parent" link remain as an active state whilst allowing the dropdown function to contine.
<li class="<?php echo($activePage == "releases" ? "active" : "")?>" class="dropdown">
Press <i class="fa fa-angle-down"></i>
<ul class="dropdown-menu">
<li class="<?php echo($activePage == "releases" ? "active" : "") ?>">Releases</li>
<li class="<?php echo($activePage == "clips" ? "active" : "") ?>">Press Clips</li>
<li class="<?php echo($activePage == "assets" ? "active" : "") ?>">Press Assets</li>
</ul>
</li>
So the goal here is to get the PRESS link to show an active state when either of the three releases, clips or assets
You'll notice in the first list I have two classes at the moment. The PHP echo class when infront does display the PRESS link its active state however doesn't allow for any drop down, thus rendering the other three links invisible, when I place the other class in the front, the drop down works but then the PRESS link doesn't show an active state.
Can anyone solve this issue for me? Thanks a lot!
This is the setup I used for a site to make the active parent element stay highlighted, as I walked down the tree:
#navigation ul.nav > li:hover ul a:hover,
#navigation ul.nav > li:hover, #navigation ul.nav > li:hover ul li:hover {
background: #3e4b51 none repeat scroll 0 0 !important;
text-decoration: none;
}
The menu setup is this:
<nav id="navigation" class="col-full" role="navigation">
<ul class="nav">
<li>
HOME
</li>
<li>
Level 1
<ul class="sub-menu">
<li>
Level 2
<ul>
<li>
Level 3
<ul>
<li>
Level 4 Item 1
</li>
<li>
Level 4 Item 2
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>

How to Make Menu Active

I have menu as follows
<ul>
<li>Home</li>
</ul>
how to make it Active when I visit that Page. I tried as follows but no luck
#navigation a:active {
color: #000;
background: -webkit-gradient(linear, left top, left bottom, from(#DFE7FA), to(#FFF));
border-bottom-width:0px;
}
I'm new webie thanks for any suggestions
Add id to your code as below
Update
<div id="menu">
<ul>
<li id="myHome">Home</li>
</ul>
</div>
Write Script as Below
<script>
window.onload = menuSelect('myHome');
</script>
Each page has a class on the body tag that identifies it:
BODY OF HOME PAGE:
<body class="home">
<ul>
<li>Home</li> //Each navigation item also includes a class identifying that particular link.
<li>About Us</li>
</ul>
</body>
BODY OF ABOUT US PAGE:
<body class="aboutUs">
<ul>
<li>Home</li>
<li>About Us</li>
</ul>
</body>
Then you target those classes in your CSS, defining a different state for the current page:
CSS STYLE:
body.home a.home, body.aboutUs a.aboutUs{
//HERE GOES YOUR CSS
color: #000;
background: -webkit-gradient(linear, left top, left bottom, from(#DFE7FA), to(#FFF));
border-bottom-width:0px;
}
In your index.php page, you need to edit the HTML this way:
<ul>
<li>Home</li>
</ul>
In other pages, say about.php, you might have something like this:
<ul>
<li>Home</li>
<li>About</li>
</ul>
And change the CSS to .active and not :active, as the second one is a state of element:
#navigation a.active {
color: #000;
background: -webkit-gradient(linear, left top, left bottom, from(#DFE7FA), to(#FFF));
border-bottom-width:0px;
}
The :active pseudo-selector is for when an element is well, active, for example while a link is being clicked.
What you will need to do is give your <a> element a class attribute and style it accordingly.

How to have the class="selected" depending on what the current page/url is

This is my first post so forgive as I am just new in the world of web development.
Normally, when I try to make a website, I create a file called header.html and footer.html so that I only change data once in all of the pages rather than having multiple same headers on many html files. And include them all in a php file together with the content and the php codes that comes per page.
Now my problem is because I only have 1 header, the css is designed in a way that whatever the current menu/tab is, it will be marked as "selected" so that its obvious to the user what page they are currently in.
My question is how do I solve this problem:
1.) To have the class="selected" depending on what the current page/url is.
<!--Menu Starts-->
<div class="menu">
<div id="smoothmenu" class="ddsmoothmenu">
<ul>
<li>Home</li>
<li>About </li>
<li>Services </li>
<li>Features</li>
<li>Support
<ul>
<li>Support 1</li>
<li>Support 2</li>
</ul>
</li>
</ul>
</div>
</div>
<!-- Menu Ends--!>
Thank You :)
If you're looking for a non-javascript / php approach...
First you need to determine which nav-link should be set as active and then add the selected class. The code would look something like this
HTML within php file
Call a php function inline within the hyperlink <a> markup passing in the links destination request uri
<ul>
<li><a href="index.php" <?=echoSelectedClassIfRequestMatches("index")?>>Home</a></li>
<li><a href="about.php" <?=echoSelectedClassIfRequestMatches("about")?>>About</a> </li>
<li><a href="services.php" <?=echoSelectedClassIfRequestMatches("services")?>>Services</a> </li>
<li><a href="features.php" <?=echoSelectedClassIfRequestMatches("features")?>>Features</a></li>
<li>Support
<ul>
<li><a href="support1.php" <?=echoSelectedClassIfRequestMatches("support1")?>>Support 1</a></li>
<li><a href="support2.php" <?=echoSelectedClassIfRequestMatches("support2")?>>Support 2</a></li>
</ul>
</li>
</ul>
PHP function
The php function simply needs to compare the passed in request uri and if it matches the current page being rendered output the selected class
<?php
function echoSelectedClassIfRequestMatches($requestUri)
{
$current_file_name = basename($_SERVER['REQUEST_URI'], ".php");
if ($current_file_name == $requestUri)
echo 'class="selected"';
}
?>
You could ID each link and use JavaScript/Jquery to add the selected class to the appropriate link.
<!--Menu Starts-->
<div class="menu">
<div id="smoothmenu" class="ddsmoothmenu">
<ul>
<li id="home-page">Home</li>
<li id="about-page">About </li>
<li id="services-page">Services </li>
<li id="features-page">Features</li>
<li id="support-page">Support
<ul>
<li id="support1-page">Support 1</li>
<li id="support2-page">Support 2</li>
</ul>
</li>
</ul>
</div>
</div>
<!-- Menu Ends--!>
On your content page use jQuery to do something like:
$(document).ready(function(){
$("#features-page").addClass("selected");
});
Another method you could use is:
Add class element based on the name of the page
Give each link a separate id then use jQuery on the individual pages.
<li>Home</li>
<li>About </li>
<li>Services </li>
<li>Features</li>
<li>Support
<ul>
<li>Support 1</li>
<li>Support 2</li>
</ul>
</li>
On the services page:
$(document).ready(function(){
$("#services").addClass("selected");
});
Or even better as robertc pointed out in the comments, there is no need to even bother with the id's just make the jquery this:
$(document).ready(function(){
$("[href='services.php']").addClass("selected");
});
One variant on Chris's approach is to output a particular class to identify the page, for example on the body element, and then use fixed classes on the menu items, and a CSS rule that targets them matching. For example, this page:
<DOCTYPE HTML>
<head>
<title>I'm the about page</title>
<style type="text/css">
.about .about,
.index .index,
.services .services,
.features .features {
font-weight: bold;
}
</style>
</head>
<body class="<?php echo basename(__FILE__, ".php"); ?>">
This is a menu:
<ul>
<li>Home</li>
<li>About </li>
<li>Services </li>
<li>Features</li>
</ul>
</body>
...is pretty light on dynamic code, but should achieve the objective; if you save it as "about.php", then the About link will be bold, but if you save it as "services.php", then the Services link will be bold, etc.
If your code structure suits it, you might be able to simply hardcode the page's body class in the page's template file, rather than using any dynamic code for it. This approach effectively gives you a way of moving the "logic" for the menu system out of the menu code, which will always remain the same for every page, and up to a higher level.
As an added bonus, you can now use pure CSS to target other things based on the page you're on. For example, you could turn all the h1 elements on the index.php page red just using more CSS:
.index h1 { color: red; }
You can do it from simple if and PHP page / basename() function..
<!--Menu Starts-->
<div class="menu">
<div id="smoothmenu" class="ddsmoothmenu">
<ul>
<li><a href="index.php" <?php if (basename($_SERVER['PHP_SELF']) == "index.php") { ?> class="selected" <?php } ?>>Home</a></li>
<li><a href="about.php" <?php if (basename($_SERVER['PHP_SELF']) == "about.php") { ?> class="selected" <?php } ?>>About</a> </li>
<li><a href="services.php" <?php if (basename($_SERVER['PHP_SELF']) == "services.php") { ?> class="selected" <?php } ?>>Services</a> </li>
<li><a href="features.php" <?php if (basename($_SERVER['PHP_SELF']) == "features.php") { ?> class="selected" <?php } ?>>Features</a></li>
</ul>
</div>
</div>
Sorry for my bad English, however may be it could help. You can use jQuery for this task. For this you need to match the page url to the anchor of menu and then add class selected to it. for example the jQuery code would be
jQuery('[href='+currentURL+']').addClass('selected');

How to add class to selective <li> in a generated menu

Hi I am looking for a solution to add a class to every list item <li> which has a child item with a class of <span class="separator"> and a different class to <li> with an anchor link.
I use Joomla and the menu is being generated somewhat like this:
<ul class="menu">
<li class="item1"><span>Home</span></li>
<li class="parent item59"><span class="separator"><span>Demo</span></span></li>
<li class="item62"><span>Article</span></li>
<li id="current" class="parent active item27"><span>CMS</span>
<ul>
<li class="item50"><span>The News</span></li>
<li class="item48"><span>Web Links</span></li>
<li class="item65"><span class="separator"><span /></span></li>
<li class="item49"><span>News Feeds</span></li>
<li class="item66"><span class="separator"><span /></span></li>
<li class="item67"><span class="separator"><span /></span></li>
<li class="item68"><span class="separator"><span /></span></li>
</ul>
</li>
<li class="item71"><span class="separator"><span>Help</span></span></li>
</ul>
What I want is to add class "anclink" or "seplink" to the <li> depending on their child item so that the final output looks like below.
<ul class="menu">
<li class="item1 anclink"><span>Home</span></li>
<li class="parent item59 seplink"><span class="separator"><span>Demo</span></span></li>
<li class="item62 anclink"><span>Article</span></li>
<li id="current" class="parent active item27" anclink><span>CMS</span>
<ul>
<li class="item50 anclink"><span>The News</span></li>
<li class="item48 anclink"><span>Web Links</span></li>
<li class="item65 seplink"><span class="separator"><span /></span></li>
<li class="item49 anclink"><span>News Feeds</span></li>
<li class="item66 seplink"><span class="separator"><span /></span></li>
<li class="item67 seplink"><span class="separator"><span /></span></li>
<li class="item68 seplink"><span class="separator"><span /></span></li>
</ul>
</li>
<li class="item71 seplink"><span class="separator"><span>Help</span></span></li>
</ul>
How can I achieve this using PHP or even a jQuery solution will be fine.
Kindly help.
With jQuery:
$('#menu > li:has( > span.separator )').addClass('seplink');
$('#menu > li:has( > a )').addClass('anclink');
or:
$('#menu > li > span.separator').parent().addClass('seplink');
$('#menu > li > a').parent().addClass('anclink');
EDIT: I was just walking out the door when I left this solution, so I didn't have the chance to note that I'd strongly favor the second solution since it utilizes a valid CSS selector.
It will perform better in browsers that support querySelectorAll.
Without jQuery:
var ul = document.getElementsByClassName("menu");
var li = ul[0].getElementsByTagName("li");
for ( var i = 0; i < li.length; i++ ){
var class = li[i].className;
class += ( li[i].childNodes[0].tagName.toUpperCase() == 'A' ) ? ' anclink' : ' seplink';
li[i].className = class;
}
Edit
So you can eitheir use getElementsByClassName as defined in http://robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/ or use another method such as getElementsByTagName (in your case the root of your nested list is the first UL.
For testing purpose I'd advise you to paste this code in the HEAD of your HTML document. Also, you need to call this function once the window is loaded as you want to apply changes on the window's loaded elements.
<script type="text/javascript">
window.onload = function(){
var ul = document.getElementsByTagName("ul")[0];
var li = ul.getElementsByTagName("li");
for ( var i = 0; i < li.length; i++ ){
var myClass = li[i].className;
myClass += ( li[i].childNodes[0].tagName.toUpperCase() == 'A' ) ? ' anclink' : ' seplink';
li[i].className = myClass;
}
};
</script>
Adding a second answer, because I'd advise against loading the entire jQuery library if this is its only purpose.
An alternative would be to use Sizzle, which is the CSS selector engine that is included in jQuery. It is a much smaller download, and as such, may be a decent compromise.
You'd get the library, and use it like this:
var li_span = Sizzle('#menu > li > span.separator'),
li_a = Sizzle('#menu > li > a'),
s = li_span.length,
a = li_a.length;
while( s-- ) {
if( li_span[ s ].className === 'separator' ) {
li_span[ s ].parentNode.className += ' seplink';
}
}
while( a-- ) {
li_a[ a ].parentNode.className += ' anclink';
}
The downloaded file is full size, so you'll want to minify it.
Hey #Patrick and #Nabab none of the solutions worked for me but some how managed to work around with this script and it is working fine in even in IE 6-9 and Firefox. I didnt get chance to check on Opera, Chrome and Safari will try it later.
$(document).ready(function() {
$('ul.menu li:not(:has(li))')
.addClass(function() {
return (
($('span.separator',this).length)
? 'seplink' : (($('a[href]',this).length)
? 'anclink' : null));
});
});
This script was contributed by some generous member yesterday here as an answer to this question. I couldn't get his / her name but don't know why later it disappeared from the list of answers. Luckily I had already copied it by then. I am posting this as an answer as it is working perfectly for me.
I am anyway using the entire jQuery library because there are other aspects of my template which need it. Kindly advise if you guys see any challenge which I may not know, in using this script.

Categories