bootstrap nav - change active class

KCTechNet
KCTechNet used Ask the Experts™
on
I have a bootstrap nav on my page but I can't get the active class to change to the clicked page.  many google search results use:
$('.menu li a').click(function(e) {
  var $this = $(this);
  if (!$this.hasClass('active')) {
    $this.addClass('active');
  }
  e.preventDefault();
});

Open in new window


This code is in the document.ready

but preventDefault stops the page from loading.  But if I leave that line out, the active tag goes back to the first nav item.  What am I doing wrong?

I have header.html which contains the includes and $document.ready()
I have menu.php which contains all of the nav li items
Then I have index.php and services.php which contain:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html> 
<head>
    <?php require_once('lib/header.html') ?>
</head>

<body>
    <?php require_once('lib/menu.php') ?>

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
If the nav is loading a new page then your code is going to change the class on the page before the new page loads - which is pretty useless.

You need to change the class on page load - not on click.

Do you have a link we can look at?
Most Valuable Expert 2017
Distinguished Expert 2018
Commented:
Ok here is why what you are doing won't work.

You have a nav bar implemented as a <ul> with the <li> elements containing links to their respective pages.

You click services which is linked to services.php - this triggers a page request.

However, before the request is initiated you are running some jQuery to change the class on the selected menu item ... just before the page is wiped and a new page is loaded. In other words, overwriting the change you just made with the jQuery.

While jQuery can be used to solve this on page load - if you are generating your pages with php anyway then it makes sense to set the class to the menu directly. You have not provided any information on how you are generating the pages at the back so you will need to adapt this to your particular solution. The code below works on the assumption you have some common template into which specific page's are loaded.
<?php
require_once('top.php');
?>
Services content here
<?php
require_once('bottom.php');
?>

Open in new window

Or possibly like this
<!doctype html>
<html>
<head>
... head here
</head>
<body>
<ul>
   Nav here
</ul>
<?php
require_once('$page.php');
?>
<footer>
</footer>
</body>
</html>

Open in new window

Whatever method you are using it is assumed there is some means to identify what page you are on. For the sake of this exercise lets assume the page is stored in a global variable called $page. When drawing your links you do something like this
<ul>
  <li <?php echo ($page == 'home') ? 'class="active"' : '';?>><a href="services.php">Services</a></li>
  <li <?php echo ($page == 'services') ? 'class="active"' : '';?>><a href="services.php">Services</a></li>
  <li <?php echo ($page == 'maintenance') ? 'class="active"' : '';?>><a href="maintenance.php">Maintenance Programs</a></li>
...
</ul>

Open in new window

In other words assign the class based on the page called at the time the page is created.
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Author

Commented:
Your code worked perfect to add the active class.  Thank you.

In regards on how the page is built, I am using the first method you show.  But I am very interested in the second method you posted. It looks a lot cleaner, but I don't understand where you would assign a value to $page.  I know you have answered the original question, but can you explain where $page would be assigned prior to require_once('$page.php');

Author

Commented:
and here's something odd...

Since I didn't need the jquery to add the class I removed the entire document.Ready() function.  When I did this, I noticed the page "flashes" when I switch between pages.  When I put the code back, the "flash" went away.  I then take out all the code within the document.ready function, so basically only leaving:

$(document).ready(function () {
    });

and the flashing stayed away.  what is going on there?
Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
Not sure about the flashing - is this not just the delay in retrieving the next page?
Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
In response to your other question about the method used - I just wrote an article - waiting for it to be approved - if it is I will post back here with a link.

Author

Commented:
yeah, sorry, that's what i meant by flashing. it was the page loading.  but with the document.ready you don't see the loading like that.
Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
Here is a link to an article that gives a basic explanation of the templating approach you asked about earlier

http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_13095-A-simple-PHP-master-Template-framework.html

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial