Link to home
Start Free TrialLog in
Avatar of Ryan Sacks
Ryan Sacks

asked on

How can I change the bootstrap .active class with JQuery?

Hi,I'm having trouble trying to change the bootstrap .active class state via jquery.I've googled and found several solutions but none of them are working for me.Here is my html code:

[code]<section id="hero">
   			<div class="container-fluid">
               <div class="container">
				   <div class="row">
						<div class="col-md-12">
							<nav class="navbar navbar-toggleable-md navbar-light">
							  <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNavDropdown2" aria-controls="navbarNavDropdown2" aria-expanded="false" aria-label="Toggle navigation">
								  <span class="navbar-toggler-icon"></span>
								  <span class="fas fa-times hide" data-wow-delay="2s"></span>
							  </button>
							  <a class="navbar-brand logo" href="index.php"></a>
							  <div class="collapse navbar-collapse" id="navbarNavDropdown2">
								<ul class="navbar-nav ml-auto">
								  <li class="nav-item active">
									<a class="nav-link" href="index.php">Home <span class="sr-only">(current)</span></a>
								  </li>
								  <li class="nav-item">
									<a class="nav-link" href="about.php">About Us</a>
								  </li>
								  <li class="nav-item">
									<a class="nav-link" href="howitworks.php">How it Works</a>
								  </li>
								  <?php
								  if( $_SESSION['loggedInUser'] ) { // if user is logged in
								  ?>
							      <li class="nav-item dropdown">
									<a class="nav-link" href="main.php">App Menu</a>
										<div class="dropdown-menu" aria-labelledby="navbarDropdown">
										  <a class="dropdown-item" href="#">Action</a>
										  <div class="dropdown-divider"></div>
										  <a class="dropdown-item" href="#">Another action</a>
										  <div class="dropdown-divider"></div>
										  <a class="dropdown-item" href="#">Something else here</a>
										</div>
								  </li>
								  <?php 
								  } else {
								  ?>
								  <li class="nav-item">
									<a class="nav-link" href="index.php#testimonials">Testimonials</a>
								  </li>
								  <?php } ?>
								  <li class="nav-item">
									<a class="nav-link" href="faq.php">FAQ</a>
								  </li>
								  <li class="nav-item">
									<a class="nav-link" href="contact.php">Contact</a>
								  </li>
								</ul>
							  </div>
							  <a href="#" id="btnsearch"><i class="fas fa-search"></i></a></nav><!-- nav -->
						</div><!-- col-sm-12 -->
						
					</div> <!-- row -->
                </div> <!-- container -->
            </div><!-- container-fluid -->
</div><!-- section -->

Here is my jquery code:

 $(document).ready(function(){
	
	$( '#hero .navbar-nav li a' ).on( 'click', function () {
		$( '#hero .navbar-nav' ).find( 'li.active' ).removeClass( 'active' );
		$( this ).parent( 'li' ).addClass( 'active' );	
	});

}); // close document ready function

Open in new window

[/code]

Any idea why my code isn't working?
Avatar of Zakaria Acharki
Zakaria Acharki
Flag of Morocco image

Hi Ryan,

As I can see there's no problem in the currently posted code if you're using the navbar for the same page, the active class will be switched between them successfully.

The main problem comes from the redirection when you click on the menu item it will redirect you to the related page what means the default active tab Home will be shown again with the active class on it.

Scenario :

You click on the link > The JS change the active class to the current clicked anchor parent > The page will be reloaded immediately to redirect you to the related link and you will not notice the JS change > The active li by default will be shown again.

Suggestion :

You could use cookies or local storage to save the value of the clicked link then when the page is ready you could check the data and set the active class to the target.
If you don't want to use cookies or local storage I suggest the use of hidden input that holds the current page link in every page then injects two lines inside the ready function, the first one will remove the active class from the default li and the second one will add the class to the current one.

HTML :

<input type="hidden" id="current_page" value="my_page.php">

Open in new window


Javascript :

$(function(){
   $('#hero li.active').removeClass('.active');
   $('#hero a[href=\"' + $("#current_page").val() + '\"]').parent().addClass("active");
});

Open in new window


NOTE : You could remove the first line if you can remove the default active class from the HOME li item.
You can use Javascript to get the actual page URL then add active class to the associate menu item

var url = window.location;
$('#hero .navbar-nav li a').filter(function() {
	return this.href == url;
}).parent().addClass('active');

Open in new window


Or  using PHP
I do prefer to use this method as it is more flexible
eg sometimes the link/page is not a menu item but we may want to set menu item active
<?php
$page = 'PageName.php';
?>

<ul>
<?php
$pages = array(
    "pages/home.php" => "Home", 
    "pages/contact.php" => "Contact Us", 
    "pages/services.php" => "services", 
    "pages/employees.php" => "Employees", 
    "pages/dashboard.php" => "Dashboard");

foreach ($pages as $url => $label) {
  echo '<li ';

  if(basename($_SERVER['REQUEST_URI'])== basename($url)){  
        echo "class='active'";                             
   }                                                      
  echo '><a href=', "$url", '>', "$label", '</a></li>';
}
?>
</ul>

Open in new window


or you can use PHP
$page = $_GET['page'] ;

Open in new window

Avatar of Ryan Sacks
Ryan Sacks

ASKER

How can I add the classes ‘nav-item’ and ‘nav-link’ on my li and a tags in your php solution? What is the $label variable?
‘Or you can use PHP’
Line of code, is that instead of the PHP solution before it or does that go along with the PHP solution?
Do you use any framework, do your pages passes through a controller action before showing?

If yes you could send the page name always as a variable ($my_page_name for example then in the HTML side you could add it staticly on all pages like :

<input type="hidden" id="current_page" value="<?php echo $my_page_name; ?>">

Open in new window

I’m not using a Framework, I’m a new web developer developing my first web app for a client. I will try 1 or 2 of the solutions posted above.
Ok @Ryan good luck and happy coding.
Hi lenamtl,
The php loop worked great, the problem is I have an if else statement that will display the Testimonials li link if the user is Not logged in and the Menu App li with dropdown menu items if the user IS logged in.
Here is my original code:

<ul class="navbar-nav ml-auto">
								  <li class="nav-item">
									<a class="nav-link" href="index.php">Home </a>
								  </li>
								  <li class="nav-item">
									<a class="nav-link" href="about.php">About Us</a>
								  </li>
								  <li class="nav-item">
									<a class="nav-link" href="howitworks.php">How it Works</a>
								  </li>
								  <?php
								  if( $_SESSION['loggedInUser'] ) { // if user is logged in
								  ?>
							      <li class="nav-item dropdown">
									<a class="nav-link" href="main.php">App Menu</a>
										<div class="dropdown-menu" aria-labelledby="navbarDropdown">
										  <a class="dropdown-item" href="pool_setup.php">Team Setup</a>
										  <div class="dropdown-divider"></div>
										  <a class="dropdown-item" href="team_admin.php">Team Administration</a>
										  <div class="dropdown-divider"></div>
										  <a class="dropdown-item" href="enter_games.php">Enter Game</a>
										  <div class="dropdown-divider"></div>
										  <a class="dropdown-item" href="enter_tickets.php">Enter Ticket</a>
										  <div class="dropdown-divider"></div>
										  <a class="dropdown-item" href="print_tickets.php">Print Tickets</a>
										  <div class="dropdown-divider"></div>
										  <a class="dropdown-item" href="tickets_admin.php">View All Tickets</a>
										</div>
								  </li>
								  <?php 
								  } else {
								  ?>
								  <li class="nav-item">
									<a class="nav-link" href="index.php#testimonials">Testimonials</a>
								  </li>
								  <?php } ?>
								  <li class="nav-item">
									<a class="nav-link" href="faq.php">FAQ</a>
								  </li>
								  <li class="nav-item">
									<a class="nav-link" href="contact.php">Contact</a>
								  </li>
								</ul>

Open in new window


and here your code that you sent me:

<ul class="navbar-nav ml-auto">
								  <?php
										$pages = array(
											"index.php" => "Home", 
											"about.php" => "About", 
											"howitworks.php" => "How It Works", 
											"index.php/#testimonials" => "Testimonials", 
											"faq.php" => "FAQ",
											"contact.php" => "Contact");

										foreach ($pages as $url => $label) {
										  echo '<li ';

										  if(basename($_SERVER['REQUEST_URI'])== basename($url)){  
												echo "class='active'";                             
										   }                                                      
										  echo '><a href=', "$url", ' class="nav-link">', "$label", '</a></li>';
										}
									?>
								</ul>

Open in new window


Is there any way to combine the loop and the if statement to also display the dropdown menu items for the li App Menu as I had it?
Here is an easiest way to do it

don't forget to set the page name
<?php $page_name = 'faq.php';?>

Open in new window

Then you can echo a class name 'active' to the menu item if the page name is the same
you can change and add class name it is just an example
<li 
<?php if ($page_name == 'faq.php') {echo 'class="active" ';}?>
>

Open in new window

This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.