Exclude the UL hierarchy from removing a class in jQuery

Check out this fiddle to see the code snippet: http://jsfiddle.net/3mpire/yTzGA/1/

I am using jQuery and I need to figure out how to remove the "active" class from all LIs except for the one that is deepest within the hierarchy.

<div class="navpole">
    <ul>
        <li class="active"><a href="#">Lorem ipsum</a></li>
        <li><a href="#">Lorem ipsum</a>
            <ul>
                <li class="active"><a href="#">Lorem ipsum</a></li>
                <li><a href="#">Lorem ipsum</a></li>
                <li><a href="#">Lorem ipsum</a>
                     <ul>
                          <li class="active"><a href="#">Lorem ipsum</a></li>
                          <li><a href="#">Lorem ipsum</a></li>
                     </ul>
                </li>
                <li><a href="#">Lorem ipsum</a></li>
            </ul>
        </li>
        <li><a href="#">Lorem ipsum</a></li>
        <li><a href="#">Lorem ipsum</a></li>
    </ul>
</div>

This is what I want the outcome to look like:

<div class="navpole">
    <ul>
        <li><a href="#">Lorem ipsum</a></li>
        <li><a href="#">Lorem ipsum</a>
            <ul>
                <li><a href="#">Lorem ipsum</a></li>
                <li><a href="#">Lorem ipsum</a></li>
                <li><a href="#">Lorem ipsum</a>
                     <ul>
                          <li class="active"><a href="#">Lorem ipsum</a></li>
                          <li><a href="#">Lorem ipsum</a></li>
                     </ul>
                </li>
                <li><a href="#">Lorem ipsum</a></li>
            </ul>
        </li>
        <li><a href="#">Lorem ipsum</a></li>
        <li><a href="#">Lorem ipsum</a></li>
    </ul>
</div>

Answer №1

Organize them based on the number of parents they have and exclude the last one, which is nested the deepest regardless of markup, then remove the class from the rest.

$('.active').sort(function(a,b) {
    return $(a).parents().length > $(b).parents().length;
}).not(':last').removeClass('active');

FIDDLE

To apply this to each navpole, simply use a each() function.

$('.navpole').each(function() {
    $('.active', this).sort(function(a,b) {
        return $(a).parents().length > $(b).parents().length;
    }).not(':last').removeClass('active');
});

FIDDLE

Answer №2

Important: Keep in mind that this solution assumes there is only one direct path from the root to the deepest .active element, which encompasses all .active elements below it (without any branching). If this condition cannot be assured, the provided solution may not function correctly.

$('.navpole .active').slice(0, -1).removeClass('active');

As the selected elements are ordered based on their appearance in the document, the "deepest" element will always be the last one. Therefore, we need to remove the class from every selected element except for the last one.

Check out the DEMO

Answer №3

To iterate through the active elements with the use of `each()`, and subsequently remove the class if their sibling elements contain a child element ul:

HERE'S THE UPDATED EXAMPLE

$('.navpole .active').each(function(){
    if($(this).siblings().children('ul').length > 0 ){
        $(this).removeClass('active');
    }
});

Answer №4

To only keep the last .active item within each .navpole, you can utilize the following code snippet:

$(document).ready(function () {
    // Iterate through each navpole
    $('.navpole').each(function(){
        // Determine the number of active elements
        var len = $('.active',this).length;
        // Filter out all but the last active element and remove the 'active' class
        $('.active',this).filter(function(index){
            return index != len-1;
        }).removeClass('active');
    }) 
});

Take a look at this Demo Fiddle for reference.

Answer №5

Give this a try! While the previous code snippet shared by adeneo is effective, it may encounter issues if there are two active nodes on the same level of the hierarchy and you wish to maintain all their active states. This modified version ensures that all lowest nodes remain selected if they are at the same hierarchy level.

$(document).ready(function () {
    $('.navpole').each(function () {
        var active = $(this).find(".active").map(function () {
            return $(this).parents().length;
        });
        var maxParents = Math.max.apply(Math, active);
        $(this).find(".active").each(function () {
            if ($(this).parents().length != maxParents) $(this).removeClass("active");
        });
    });
});

To see a demonstration, check out this fiddle: http://jsfiddle.net/CGcr9/1/

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

Unable to locate image in React framework

When attempting to display an image, I encountered a 404 error even though the folder containing it is being served properly. Code snippet from JSX file: render: function(){ ... return <button type="button" id="powerButton" onClick={this.someFun}>& ...

What steps can be taken to resolve the error message "Module '../home/featuredRooms' cannot be found, or its corresponding type declarations"?

Upon deploying my site to Netlify or Vercel, I encountered a strange error. The project runs smoothly on my computer but seems to have issues when deployed. I am using TypeScript with Next.js and even attempted renaming folders to lowercase. Feel free to ...

What causes the variable assigned in the outer subscription's scope to change as the inner subscriptions change?

In my Angular 6 code snippet provided below, I am facing an issue: ngOnInit() { this.route.queryParams.subscribe((params: Params) => { const stuffId: string = params.stuffId; this.service.getState().subscribe((state) => { ...

Angular.js filter issue: "Error: textProvider is not recognized provider"

I implemented a custom filter for my AngularJS project that is similar to the one in this fiddle http://jsfiddle.net/tUyyx/. myapp.filter('truncate',function(text,length){ var end = "..." text = text.replace(/\w\S*/g, function( ...

Using React and Material UI to create a table filtering system with checkboxes

I'm currently developing a filtering feature using checkboxes for a data display in a project utilizing React and Material-UI. Is there a custom solution available within Material-UI? If not, what steps should I take to achieve this? As I am rel ...

Utilizing ng-repeat $index for locating an element within an array

Within my $scope, there is a property called $scope.cars, which is an array of cars. Users have the ability to delete a car from this array. When calling the delete function deleteThis, I pass the $index parameter created by ng-repeat. However, in the Ja ...

POST request body is not defined

Client Interface: procedure OnButtonClick(Sender: TObject); begin gcm := GetGCMInstance; p := TJavaObjectArray<JString>.Create(1); p.Items[0] := StringToJString('460004329921'); FRegistrationID := JStringToString(gcm.register(p)); ...

"Is it possible to move the text on the canvas by dragging it to where you want it to be

Seeking help again after an unsuccessful attempt. How can I allow the user to add text to the canvas by dragging it to their desired location? For example, if they input text somewhere, it should appear on the canvas and then be draggable to any position ...

Unable to load JQuery from a div element

My goal is to create a standard .html file containing the navigation, footer, and other elements that will be used across multiple pages for a small site I'm building. I want to keep it simple and avoid using php or other programming languages. I&apo ...

Progressing through the Material UI LinearProgress bar in steps

How can I split a progress bar into more steps to achieve a design like this? https://i.stack.imgur.com/lRMj6.png I attempted using this code but couldn't find an option for splitting: <LinearProgress variant="determinate" classes={{ ...

What prevents me from extending an Express Request Type?

My current code looks like this: import { Request, Response, NextFunction } from 'express'; interface IUserRequest extends Request { user: User; } async use(req: IUserRequest, res: Response, next: NextFunction) { const apiKey: string = ...

Is it possible for me to identify the original state of a checkbox when the page first loaded, or the value it was reset to when `reset()` was

When a webpage is loaded, various input elements can be initialized as they are declared in the HTML. If the user modifies some of the input values and then resets the form using reset(), the form goes back to its initially loaded state. I'm curious, ...

Harvest Data from JSON Data Structure

My query pertains to handling data received from a URL in JSON format. Most examples I've come across focus on recursively printing symmetrical JSON objects, like this one. However, how can I effectively print the contents of the following JSON object ...

There seems to be a glitch in my JavaScript for loop as it is not iterating for the correct amount that it should

It seems like my for loop is not always iterating 7 times as intended. Sometimes it runs with 5 iterations, other times with 4 or 3. This is the JavaScript code I am using: var start = new Date().getTime(); var end = new Date().getTime(); function timeT ...

Is your Material UI Responsive Appbar overlapping the main content? Looking for a solution to address this issue?

Currently, I am in the process of developing a website that incorporates a responsive-based app bar with an attached drawer. The design concept I am following can be located at this link, which I have been modifying to suit my needs. However, I have encoun ...

Making sure Angular picks up on $scope changes

Currently, I am in the process of developing my inaugural AngularJS application and am faced with the challenge of a directive not updating its view when there are changes to the array received from the service. Below is the structure of my directive: an ...

Implementing the passing of value from view to controller in CodeIgniter through an onclick feature

I need to pass the button's id onclick from the view to the controller using ajax, but I keep getting this error: 500 Internal Server Error This is my view: <a data-toggle="modal"data-target="#Add_Money_to_campaign" ><button onclick="add ...

Strategies for Applying Filters in Search Feature on IOS Devices

Currently, I have an array of books that are being displayed on my view. At the top of the view, there are 3 filters available: (All | Reading level 1 | Reading Level 2 | Reading Level 3) (All | Informational | Literature) (All | Published in 2000-2005 | ...

The backtick is not functioning correctly when trying to append the result in the Internet Explorer browser

I am using the .html method to append HTML content to a specific div ID within my file. <html> <head> Title <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> </head> <body> ...

class-validator: ensures the correct number of digits are present in numeric values

Seeking assistance on validating the number of digits for numeric values using class-validator. Specifically, I want my entity to only accept numbers with 6 digits for a certain property. For example: const user1 = new User(); user1.code = 123456 // should ...