An effective method for modifying the active class on an li element in jQuery and ensuring that the user is directed to the desired page upon clicking the li element

I am facing an issue with my script tag. When I click on the links test.php or test2.php, the active class changes from index.php to the respective file but I am not redirected to the clicked page. I have tried solutions from various sources but none of them give me the desired result. I want to be directed to the clicked page and update the active class accordingly in the li element.

How to change active class while click to another link in bootstrap use jquery?

Active link after click

When I uncomment e.preventDefault(), I can navigate to the clicked link but the active class is not updated in the li element. When this line is commented, I cannot navigate to the clicked page, instead, the active class updates in the li element.

<div class="menu">
    <ul class="list">
        <li class="header">MAIN NAVIGATION</li>
        <li class="active">
            <a href="index.php">
                <i class="material-icons">home</i>
                <span>Home</span>
            </a>
        </li>
        <li class="">
            <a href="test.php">
                <i class="material-icons">group</i>
                <span>Test</span>
            </a>
        </li>
        <li class="">
            <a href="test2.php">
                <i class="material-icons">people</i>
                <span>Test2</span>
            </a>
        </li>
    </ul>
 </div>

And the script code:

$(document).ready(function () {
    $('.menu .list a').click(function(e) {

        $('.menu li.active').removeClass('active');

        var $parent = $(this).parent();
        $parent.addClass('active');
        e.preventDefault();
    });
});

The content of test.php is as follows:

<body class="theme-red">
    <nav class="navbar">
        <?php include_once('navbar.html'); ?>
    </nav>
    <section>
        <aside id="leftsidebar" class="sidebar">
            <?php include_once('left-side-bar.html');?>
        </aside>
    </section>

    <section class="content">
        <div class="container-fluid">
            <div class="row clearfix">
                <table id="tbl-users" class="table">
                    <thead>
                        <tr>
                            <th>ID</th>
                            <th>Name</th>
                        </tr>
                    </thead>
                    <tfoot>
                        <tr>
                            <th>ID</th>
                            <th>Name</th>
                        </tr>
                    </tfoot>
                    <tbody>
                    <?php
                        $accounts = get_details();
                        foreach($accounts as $acc){
                    ?>
                        <tr>
                            <td><?php echo $acc['id']; ?></td>
                            <td><?php echo $acc['name']; ?></td>
                        </tr>
                    <?php
                        }
                    ?>
                    </tbody>
                </table>
            </div>
        </div>
    </section>
</body>

Answer №1

The Cause of the Issue

An issue arises when you use e.preventDefault() on clicking an anchor tag, as it disrupts the default behavior of redirecting the page. This results in the page not loading while still adding the active class. On the other hand, if you do not use e.preventDefault(), the page redirects immediately before applying any changes, making it difficult to see the active class.

.

Solution to Resolve the Issue

To address this problem, you can return a value from test.php or test2.php which can be validated with JavaScript using if-else conditions to determine and set the active class accordingly for li elements.

Steps to Implement the Changes:

In each linked page like test.php or test2.php, add a hidden span with text that matches the hyperlink in the anchor tag. For example, for test.php add the following span:

<span id="curpage" style="display:none;">test.php</span>

Then include the following script at the end of the body tag or in a separate file that is included in all PHP files using <?php include(".."); ?>:

$('a[href=\"' + $("#curpage").text() + '\"]').parent().addClass("active");

You can try out the following sample code to implement this solution. Create two files within the same directory named a.html containing the code:

<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
  <span id="curpage" style="display:none;">a.html</span>
  <div class="menu">
  <li><a href="b.html">1</a></li>
  <li><a href="a.html">2</a></li>
</div>
<script>
  $('a[href=\"' + $("#curpage").text() + '\"]').parent().css("color","red");
</script>
</body>
</html>

And b.html containing the code:

<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
  <span id="curpage" style="display:none;">b.html</span>
  <div class="menu">
  <li><a href="b.html">1</a></li>
  <li><a href="a.html">2</a></li>
</div>
<script>
  $('a[href=\"' + $("#curpage").text() + '\"]').parent().css("color","red");
  </script>
  </body>
</html>

Now, by navigating between the pages using the links, you will observe the change in bullet color indicating the active page.

Answer №2

One method to ensure the active menu link remains displayed correctly is by implementing a unique identifier for each page within your HTML templates. By assigning a specific ID and data attribute to a designated div element, you can easily track the current page using JQuery.

<div id="page-name" data-page="home-page">

To dynamically update the active menu link based on the current page, you can retrieve the stored data with the following code:

var current_page = $("#page-name").data("page");

Subsequently, adjust the class of the menu links accordingly using conditional statements like so:

// Remove "active" class from all menu links
$(".menu li a").removeClass("active");

if (current_page === "home-page") {
    // Add "active" class to desired link
    $("#home-page-link").addClass("active")
}

It's advisable to utilize a switch statement for multiple pages and remember to include the corresponding JS file across all pages. Utilizing the Header template simplifies this process, requiring just a single inclusion. Lastly, ensure consistency in naming conventions for the "data-page" attribute in your HTML markup.

Answer №3

If you want to dynamically add a class to the navigation item of the current page when the page loads, here's how you can achieve it:

  1. First, check the URL of the current page:
    $(location).attr('href') OR $(location).attr('pathname')
  2. Next, iterate through anchor elements (a) in the navigation menu to see if any of the href attributes match the current page URL using the .indexOf() method with a conditional statement:
    if(anchorEl.indexOf(currentPageUrl) >= 0)
  3. If there is a match, add the required class using the .addClass() function: $(this).addClass('current');

Check out this code snippet for a visual demonstration:

Please note that this example uses specific URLs to illustrate functionality and is not intended for production environments.

$(document).ready(function () {
    var currentPageUrl = $(location).attr('href'), // store current page url
        anchorEl;
    
    $('.menu a').each(function(){
    
      anchorEl = $(this).attr('href'); // store href attribute of current anchor element
      console.log('anchor link url:',anchorEl);
      console.log('current window url:',currentPageUrl);
    
      if(anchorEl.indexOf(currentPageUrl) >= 0) { 
        $(this).addClass('current');
        console.log('class "current" added.');
      }
    });
});

/* 

Note:
$(location).attr('href') = full absolute path (https://example.com/page)
$(location).attr('pathname') = relative path (/page)

*/
.current {
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="menu">
  <ul class="list">
    <li>
      <a href="https://example.com/page1">
          <span>Example Page 1</span>
      </a>
    </li>
    <li>
      <a href="https://example.com/page2">
          <span>Example Page 2</span>
      </a>
    </li>
    <li>
      <a href="https://example.com/current-page">
          <span>This should be the <em>current</em> page</span>
      </a>
    </li>
  </ul>
</div>

Answer №4

Have you considered using e.preventDefault()? This function stops the default behavior of an object, such as a redirect in this case. By doing so, you can prevent your application from automatically redirecting to the specified href.

If you want to implement this feature, you can update your code like this:

$(document).ready(function () {
    $('.menu .list a').click(function(e) {

        $('.menu li.active').removeClass('active');

        var $parent = $(this).parent();
        $parent.addClass('active');
        e.preventDefault();

        // Make the necessary changes here
        location.href = $(this).attr('href');
    });
});

Edit 1: You can follow these steps:

1) Assign a specific class name to each li tag

2) Send the required class name (which should have the active class) after redirection and page load

3) Retrieve the class name passed through the url and add or remove it from your li tags

Your updated html code will look like this:

<div class="menu">
    <ul class="list">
        <li class="header">MAIN NAVIGATION</li>
        <li class="home active">
            <a href="index.php">
                <i class="material-icons">home</i>
                <span>Home</span>
            </a>
        </li>
        <li class="group">
            <a href="test.php">
                <i class="material-icons">group</i>
                <span>Test</span>
            </a>
        </li>
        <li class="people">
            <a href="test2.php">
                <i class="material-icons">people</i>
                <span>Test2</span>
            </a>
        </li>
    </ul>
 </div>

If you need the corresponding script code for this solution, let me know and I'll update my answer.

Edit 2: To make this work, include the following script codes in your file:

function setActiveClass() {
    //Remove active class from all li tags
    $('.menu li.active').removeClass('active');
    //Get the current url
    var url = $(location).attr('href');

    if (url.contains("activeClass")) {
        //Find the index of active class in the url
        var start = url.indexOf("#activeClass");
        //Adjust the end index based on the longest class name ("people" has 6 characters)
        var end = start + 6;
        //Extract the passed class name from the url
        var className = url.substring(start, end);

        //Add the active class based on the passed class name
        if(className.contains("home"))
            $(".home").addClass('active');
        else if(className.contains("group"))
            $(".group").addClass('active');
        else
            $(".people").addClass('active');
    } else {
        //Add the active class in default mode (when there's no redirect yet)
        $("#defaultLiTag").addClass('active');
    }
}

$(document).ready(function () {
    //Call the function
    setActiveClass();

    $('.menu .list a').click(function(e) {
        e.preventDefault();

        var classNameOfParent = $(this).parent().attr('class');

        var classNameToBePassedByUrl = "home";

        if(classNameOfParent.contains("group"))
            classNameToBePassedByUrl = "group";
        else if(classNameOfParent.contains("people"))
            classNameToBePassedByUrl = "people";

        location.href = $(this).attr('href') + "#activeClass=" + classNameToBePassedByUrl;
    });
});

Answer №5

After encountering the same issue and researching extensively, I stumbled upon a helpful solution in the following link. Hopefully, it can assist you as well. It is recommended to remove the "active" class and add it to the clicked navbar item. Using location.href helps to add the active class when the page reloads.

https://example.com/refresh-active-page-jquery/

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issues with basic emit and listener in socket.io

I recently inherited an App that already has socket IO functioning for various events. The App is a game where pieces are moved on a board and moves are recorded using notation. My task is to work on the notation feature. However, I am facing issues while ...

Modify anchor link color in a one-page website by using Jquery to detect scroll position changes when reaching different page sections

Each if statement contains specific numbers to change the text color of the visited/current/active anchor link. The height of the page is dependent on its width. How can this be resolved? Apologies if my explanation is confusing, English isn't my stro ...

Detecting the State of the Keyboard in Ionic 2

Seeking an easy way to determine if the mobile device keyboard has been opened or closed using Ionic2 and Angular2. Is there a 'keyboard-open' or 'keyboard-close' class that Ionic sends to the body/html? ...

The timer is malfunctioning

I am new to JavaScript and looking to create a simple countdown. I came across this script: http://codepen.io/scottobrien/pen/Fvawk However, when I try to customize it with my own settings, nothing seems to happen. Thank you for any assistance! Below is ...

CSS - spacing anomaly among inline-block items

I am facing a strange issue with the arrangement of elements in my container div. I have set them to display: inline-block, and they are supposed to expand horizontally if the contents exceed the device width. However, there is an unexpected margin between ...

IE9 not triggering jQuery's .load method

I am facing an issue where the load method is not firing on IE9.0 for 4 divs (class=mydiv) with images inside, while it works on other browsers I've tested. I'm unsure if this issue persists in other versions of Internet Explorer. $.noConflict() ...

Unable to upload a file to an email using the mandrillapp JSON API

Having trouble sending an email with an attached document via the Mandrillapp JSON API using the method send-template in JavaScript. The email sends successfully, including images attached to the images array. However, documents sent in the attachements ar ...

Issue with nextJS/Firebase database while experimenting with enabling web frameworks

I encountered an issue with a nextJS app I built on Firebase, following the steps and running the commands mentioned below: % npx create-next-app@latest % cd myapp % firebase experiments:enable webframeworks % npm install -g firebase-tools % firebase ...

The browser fails to implement styling prior to a demanding workload

Is it possible to refresh a section of my webpage that contains numerous DOM elements? My ideal approach would be to hide the section using visibility: hidden;, then redraw it, and finally set visibility back to visible;. However, I've encountered an ...

What could be causing the flexbox code to not take effect and the text to refuse wrapping?

I've been utilizing flexbox to style my content, and it worked seamlessly on the first three divs. However, when I attempted to apply the same styling to the fourth one, it didn't quite work out as planned. Despite trying options like flex-wrap t ...

React Nested Grid with Material-UI

https://i.stack.imgur.com/toxDA.jpg I am striving to replicate the layout demonstrated in the image below So far, I have the following code snippet: <Grid container justify=“space-between”> <Grid container item> <Grid ite ...

Utilizing i18n's useTranslation and Redux's connect Higher Order Components to export components efficiently

My application has been utilizing Redux for quite some time, with the component exports structured like this: export default connect(mapStateToProps, mapDispatchToProps)(MyComponent); Now, I am integrating an i18n translation library and would like to use ...

Generate a custom comment page for every URL identifier

I am currently working on creating a PHP comment page that displays unique comments for each specific URL ID. However, I have encountered an issue where the comment page is shared among all URLs. I understand that I need to add the URL ID (bug ID) to the M ...

The Jade variable assignment variable is altered by the Ajax result

Seeking a solution to update a Jade variable assigned with the results of an ajax post in order for the page's Jade loop to utilize the new data without re-rendering the entire page. route.js router.post('/initial', function(req, res) { ...

What sets id and class apart from each other?

I understand that for id we need to use the '#' symbol and for class '.' symbol. However, I am unsure of the specific purposes of both class and id in styling CSS. Can someone provide clarification on when I should use id and when I sho ...

Issue: Unable to locate module 'js-yaml' while executing npm start command

Unable to locate module 'js-yaml' Require stack: D:\REACT NATIVE\portfolio\node_modules\cosmiconfig\dist\loaders.js D:\REACT NATIVE\portfolio\node_modules\cosmiconfig\dist\createExplore ...

Connecting to a fresh dynamic route does not impact the getInitialProps data

I am struggling to understand the difference between componentDidMount and getInitialProps. Despite my best efforts to research, I still can't figure out when to use each one in my specific case. Let me give you some context. I have a page called /co ...

Switch the orientation of the unordered list from horizontal to vertical in a dynamic way

Perhaps a repeated inquiry, yet I have been unable to discover a solution for this issue... I am dealing with a div element (referred to as master) that I do not have the ability to adjust in terms of width or height. Contained within the master is anoth ...

Refresh ng-repeat following data entry or push in Angular Material dialog

Currently, I am facing an issue with adding a new object to an ng-repeat array. The array is populated with data fetched through an $http request. My goal is to input data in a dialog and pass it to a function that will then add the data as an object to th ...

"Disabling Dropzone.js functionality once a file has been selected - here's how

When using my dropzone, I typically choose a file to save first and then click the save button. However, I am facing an issue: how can I disable the dropzone area after selecting a file? I attempted the following approach: accept: function (file, done) { ...