Experience the click action that comes equipped with two unique functions: the ability to effortlessly add or remove a class

Currently, I am in the process of creating a list of anchor links that contain nested anchor links, and there are a few functionalities that I am looking to implement.

Upon clicking on a link:

  1. Add a class of "current"
  2. Remove the class of "current" from any other link or nested link
  3. If the item has children, toggle the value of a data-attribute (e.g., data-children="visible" or data-children="hidden")
  4. Ensure that the anchor link functionality remains intact

It is worth mentioning that whether the "data-children" attribute is present on the parent a.link or on the div.children is irrelevant to me.

HTML

<ul>
    <li><a href="#l1" class="link">Level 1</a></li>
    <li><a href="#l2" class="link" data-children="hidden">Level 2</a>
        <div class="children">
            <ul>
                <li><a href="#l2-1" class="link">Level 2.1</a></li>
                <li><a href="#l2-2" class="link" data-children="hidden">Level 2.2</a></li>
                <li><a href="#l2-3" class="link">Level 2.3</a></li>
            </ul>
        </div>
    </li>
    <li><a href="#l3" class="link">Level 3</a></li>
</ul>

JavaScript

let el = document.querySelectorAll('.link');
for (let i = 0; i < el.length; i++) {
  el[i].onclick = function() {
    let c = 0;
    while (c < el.length) {
      el[c++].className = 'link';
    }
    el[i].className = 'link current';

    let x = el.getAttribute('data-children');
    if (x === 'visible') {
      el.setAttribute('data-children', 'visible');
    } else {
      el.setAttribute('data-children', 'hidden');
    }
  };
}

The desired outcome is to enable any link to be marked as the "current" link, with the ability to toggle the display of any or all child links.

By clicking on a parent link, it will acquire the class="link current" and toggle the attribute to data-children="visible". Clicking the parent link again will switch the attribute to data-children="hidden," while maintaining the class="link current" for the link.

Answer №1

Give this a shot:

const elements = document.querySelectorAll('.link');
    for (let j = 0; j < elements.length; j++) {
        elements[j].onclick = function() {
            let count = 0;
            while (count < elements.length) {
                elements[count++].className = 'link';
            }
            elements[j].className = 'link current';

            // toggle data-children attribute for clicked link and children
            const hiddenNodes = elements[j].parentNode.querySelectorAll('[data-children=hidden]');
            const visibleNodes = elements[j].parentNode.querySelectorAll('[data-children=visible]');

            for (let k = 0; k < hiddenNodes.length; k++) {
                hiddenNodes[k].setAttribute('data-children', 'visible');
            }

            for (let k = 0; k < visibleNodes.length; k++) {
                visibleNodes[k].setAttribute('data-children', 'hidden');
            }
        };
    }
<ul>
    <li><a href="#l1" class="link">Level 1</a></li>
    <li><a href="#l2" class="link" data-children="hidden">Level 2</a>
        <div class="children">
            <ul>
                <li><a href="#l2-1" class="link">Level 2.1</a></li>
                <li><a href="#l2-2" class="link" data-children="hidden">Level 2.2</a></li>
                <li><a href="#l2-3" class="link">Level 2.3</a></li>
            </ul>
        </div>
    </li>
    <li><a href="#l3" class="link">Level 3</a></li>
</ul>

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

When a new marker is clicked on Google Maps, the previous Infowindow will automatically close

Here are some specific locations to consider: var places = [{ "id": 1, "ReferenceNumber": "52525252525", "Address" : "School" , "Latitude": "21.585486", "Longitude": & ...

The functionality of a website's design acts as a safeguard against unauthorized data transfers

I am encountering a major issue with my website. The layout I have created seems to be hindering me from making any modifications. My website consists of several containers, with three small containers stacked on top of each other as the main section of ...

Error: Unable to locate corresponding closing tag for "<%"

I'm struggling to figure out what I might have missed. Everything appears correct, but the nested and somewhat complex code that I am writing seems to be causing an issue with EJS. The variable posts has been passed from node.js to the EJS file. How c ...

Sveltejs template not displaying on M1 MacBook Air after running - stuck on blank screen

Currently, I am in the process of learning Sveltejs and have been utilizing for the tutorial, which has been quite effective. However, I decided to work on developing and testing Sveltejs applications locally on my MacBook Air M1. I downloaded the provid ...

npm package.json scripts not executing

Whenever I try to run npm start or npm run customScriptCommand, npm seems to not be executing anything on my project and just quickly returns a new line in the terminal. I attempted to solve this issue by uninstalling node and npm from my machine, then in ...

What is the standard practice in AJAX for determining a specific state during page loading?

Since I started diving into the world of serious ajax operations, one question has been on my mind. Let me illustrate with an example. Imagine fetching a standard HTML page for a customer from the server. The URL could look like this: /myapp/customer/54 ...

Retrieve the Javascript variable and assign it to a PHP variable

When attempting to assign a JavaScript variable to a PHP variable and output the value in an alert, I am encountering an error. The output is shown as "; alert(simple); var p1sds = "My Custom String"; <?php $dsfd = "<script>document.writeln(p ...

Encountering a missing value within an array

Within my default JSON file, I have the following structure: { "_name":"__tableframe__top", "_use-attribute-sets":"common.border__top", "__prefix":"xsl" } My goal is to add values by creating an array, but I am encountering an issue where my ...

What are the steps to convert a canvas element, using an image provided by ImageService as a background, into a downloadable image?

I've been working on an app that allows users to upload an image, draw on it, and save the result. To achieve this functionality, I'm using a canvas element with the uploaded image as its background. The image is retrieved through ImageService. B ...

The D3.js text element is failing to show the output of a function

I'm having an issue with my chart where the function is being displayed instead of the actual value. How can I make sure the return value of the function is displayed instead? The temperature values are showing up correctly. Additionally, the \n ...

Determining the quantity of items within a div using jQuery

Similar Question: Retrieve the count of elements inside parent div using jQuery Can you determine the total number of elements within a specific div? <div id=count"> <span></span> <span></span> <span></ ...

Harnessing the power of the bluebird promise library

Within myPeople function, there is a promise function being called as shown below: var myPeople = function(){ var go; return new Promise (function(resolve){ User .getPeople() .then(function(allPeople){ ...

Maintain parental visibility with children when navigating to a different page

I am currently working on a vertical accordion menu that opens on hover, stays open, and closes when other items are hovered. The great assistance I received from @JDandChips has been instrumental in getting this feature up and running. Now, my main focus ...

Issue with floating date and time not functioning properly in ICS file for Yahoo Calendar

I have set up a calendar event in Google, Apple, and Yahoo calendars for each individual customer. The event is scheduled based on the customer's address at a specific time, so there should be no need for timezone conversion. However, I encountered an ...

Implementing CSRF token for the current window's location

Is there a way to add a CSRF token to all instances where window.location.href is used in my Javascript code? It's not possible to override the window.location object and its properties like window.location.href. Creating a universal function to inc ...

Using Jquery to find the class that matches the current element

Is it possible to select a specific div by its class when there are multiple divs sharing the same class and triggering the same function on button click? I only want to target the class where $(this) is located. I've experimented with .parent, .chil ...

Having Difficulty Converting JavaScript Objects/JSON into PHP Arrays

This particular inquiry has no relation to the previously mentioned identical answer/question... In JavaScript, I am dealing with a substantial list of over 1,000 items displayed in this format... var plugins = [ { name: "Roundabout - Interac ...

Vuetify: Utilizing condition-based breakpoints

Here is the layout that I am working with: https://i.stack.imgur.com/qlm60.png This is the code snippet that I have implemented: <template> <v-card> <v-card-text> <v-container grid-list-xl fluid class="py-0 m ...

Production build encountering unhandled TypeError in proxy

One day, I decided to tweak MUI's styled function a bit, so I came up with this proxy code: import * as muiSystem from '@mui/system'; type CreateMUIStyled = typeof muiSystem.styled; type MUIStyledParams = Parameters<CreateMUIStyled>; ...

Experiencing issues with a blank or non-functional DataGrid in Material UI components

My DataGrid table is showing blank. I experienced the same problem in a previous project and recreated it in a new one with updated versions of django and mui libraries. Here is an example of my data displayed with DataGrid not working I posted a bug rep ...