What is the best way to avoid (click) from adding the class to each individual element within an ngFor loop?

I am facing a challenge with my mobile navigation menu, which is dynamically created using ngFor. Some items in the nav have dropdowns that need to be opened and closed on click. Unlike desktop where hover can be used, I had to implement a click event for mobile. Unfortunately, using :active pseudo-class is not an option according to our UX team's guidelines. The goal is for users to click on a nav item and only open/close its corresponding dropdown. However, the issue arises from ngFor applying the click event to every nav item, not just those with dropdowns. As a result, clicking on one item opens all dropdowns.

Below is my HTML structure:

<div id="mobNav" [ngClass]="{'toggleNav': isClassVisible}">
                            <ul class="navList">
                                <li class="root" *ngFor='let item of topMenu' (click)="toggleClass()" [ngClass]="{'more' : !item.url}">
                                    <a class="txt">{{item.name}}</a>
                                    <!--Mobile-->
                                    <ul *ngIf="!item.url" class="dropDown" [ngClass]="{'toggleMobileNav' : isMobileVisible}">
                                        <li *ngFor="let sItem of findChildren(item.tabID) " class="txt ">
                                            <a href="{{ sItem.url }} ">{{ sItem.name }}</a>
                                        </li>
                                    </ul>
                                </li>
                            </ul>
                        </div>

And here is the method being called. It simply toggles visibility:

  toggleClass(){
this.isMobileVisible = !this.isMobileVisible;
if(this.isMobileVisible === true){
  console.log("class added");

}      else{
    console.log("class not added");
  }

}

Answer №1

If you want to customize the HTML, consider creating separate HTML for different cases and then shifting the (click) functionality from <li> to the corresponding element.

Here is an example with modified HTML structure that may require adjustments in CSS as well:

<div id="mobNav" [ngClass]="{'toggleNav': isClassVisible}">
    <ul class="navList">
        <li class="root" *ngFor='let item of topMenu' [ngClass]="{'more' : !item.url}">
            <a *ngIf="item.url">
                <span class="txt">{{item.name}}</span>
            </a>
            <a *ngIf="!item.url" (click)="toggleClass(item)">
                <span class="txt">{{item.name}}</span>
                <!--Mobile-->
                <ul class="dropDown" [ngClass]="{'toggleMobileNav' : item.isMobileVisible}">
                    <li *ngFor="let sItem of findChildren(item.tabID) " class="txt ">
                        <a href="{{ sItem.url }} ">{{ sItem.name }}</a>
                    </li>
                </ul>
            </a>
        </li>
    </ul>
</div>

To make this more versatile, you can adjust the function to work with each item individually like so:

toggleClass(item){
    item.isMobileVisible = !item.isMobileVisible;
    if(item.isMobileVisible === true){
        console.log("class added", item);

    }      else{
        console.log("class not added", item);
    }
}

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

Limitations of GitHub's rate limiting are causing a delay in retrieving user commit history

I have developed a code snippet to retrieve the user's GitHub "streak" data, indicating how many consecutive days they have made commits. However, the current implementation uses recursion to send multiple requests to the GitHub API, causing rate-limi ...

React not correctly returning multiple values in function: TypeError: cannot iterate over undefined (cannot read property Symbol(Symbol.iterator))

Although there are numerous questions with a similar title, none of them address my specific concern. My current project involves a React app that retrieves data from a backend built with Node.js and MySQL. However, I encountered the following error while ...

Difficulty recognizing sessions in production for a self-hosted Next.js application using Clerk Dev Auth

Having trouble finding the next step in debugging as I couldn't resolve the issue on Clerk's Discord or GH Issues. It seems like it might be a Next.js problem rather than a Clerk one? I am currently running a self-hosted next.js app in a docker ...

In JSF, the loading bar is hidden before the page is completely loaded

Currently, I am facing an issue with the loading bar. It seems to disappear before the page content is fully loaded. Ideally, I would like the loading bar to remain visible until the entire page has been loaded correctly. In the layout.xhtml file, I have ...

Unable to capture the text within the span element. Attempting to retrieve a response from a previously run javascript function

Currently, I am facing a challenging task in FileMaker using Webdirect. I have implemented a QR code generator and reader, and while I can successfully read the code, I am struggling to capture the result of the scan. The scanned data is displayed in a hid ...

"Discover the Step-by-Step Guide to Launching Fresh Content or Code in the Current Tab and

I have a webpage with multiple tabs, each representing different content. Now, I want to create a functionality where if a user clicks on the "Home" tab, they are prompted to enter a password (e.g., 1234). Upon entering the correct password, the user shoul ...

Displaying dynamic HTML content in a Bootstrap modal using React JS is a great

I have been attempting to showcase an Unordered List within a Bootstrap Modal in React JS, with the list being dynamic. My current approach isn't yielding the desired results as the HTML elements are appearing as strings. var ModalHeader = React.cre ...

What is the process for transforming a method into a computed property?

Good day, I created a calendar and now I am attempting to showcase events from a JSON file. I understand that in order to display a list with certain conditions, I need to utilize a computed property. However, I am facing difficulties passing parameters to ...

Is it true that jQuery and JavaScript operate within separate namespaces?

Within my jQuery code, I am trying to increment a value using the following function: $(document).ready(function(){ var fieldCounter = 0; ... The issue I am facing is that I am unable to access this incremented value from a non-jQuery function. Conver ...

How to Send Data with NodeJS by Utilizing the Finish Event

Is there a way to retrieve the JSON data sent during the nodejs finish event? This is how I send the JSON data: oResponse.json({ version: "1.0.0", author: "Someone", contributors: "also Someone" }); I would like ...

Limit the options in jQuery UI auto-complete to search by name from a variety of JSON responses

I am looking to enhance my search functionality by utilizing jqueryUi's auto-complete feature to specifically target Names and exclude other array values such as fax. Here is how I have implemented it in php: <?php require_once 'db_conx.php&a ...

Combining duplicate objects in a JavaScript array

I am looking to identify duplicates by country code and merge them into a single object The array structure is: [{...},{...}] Objects {Country_Code: "RU", Country: "Russia", Provider: "Shell1", Price: "0.123"}, {Country_Code: "EN", Country: "Russia", P ...

Guide to implementing hapi-auth-jwt2 authorization on a specific route within hapi.js?

I am facing an issue with using an access token in hapi.js. I am struggling to comprehend how to utilize this token for authentication purposes. Currently, I am referring to the article on dwyl/hapi-auth-jwt2. My database setup involves mongodb. However, I ...

Tips for avoiding the freezing of bootstrap-select scroll when a large number of options are present

I have integrated a bootstrap-select with a total of 1000 options. However, I am encountering an issue where when I attempt to scroll down the list of options, it only goes down approximately 60 options and then freezes in that position. Can anyone provi ...

What are some potential disadvantages of using `import type` or activating the `@typescript-eslint/consistent-type-imports` rule in ESLint?

Recently, I encountered an issue that was resolved by utilizing the import type feature in TypeScript instead of just using import. It came to my attention that there exists an eslint rule called @typescript-eslint/consistent-type-imports which, when activ ...

How can I fix the issue of the onClick function in my React list not activating the toggle?

How to Activate Toggle Functionality Currently, I am working on a project using React where I developed a list with active states. I have implemented the onClick functions, but unfortunately, they are not working as intended. When I click on the list item ...

Utilize Vue JS to trigger a query when an option is selected in a drop-down select

I'm new to Vue and facing a challenge. I have multiple drop-down select menus that fetch data from an Axios request. The select only responds when I click the submit button. I want it to update when the user makes a selection from the drop-down. I can ...

Angular - Using the DatePipe for date formatting

Having trouble displaying a date correctly on Internet Explorer using Angular. The code works perfectly on Chrome, Firefox, and other browsers, but not on IE. Here is the code snippet : <span>{{menu.modifiedDate ? (menu.modifiedDate | date : "dd-MM- ...

Exploring TypeScript's reluctance to automatically infer value types and strategies for overcoming this behavior

I have been working on implementing a type-safe router in TypeScript and I am facing challenges with inferring types. export interface Route<Args> { match(path: string): Args | void; build(args: Args): string; } export type Routes<State> ...

Converting a Curl command to a JavaScript POST request: best practices

Is it possible to convert the given curl code into a JavaScript post request that will function effectively in all browsers? curl https://connect.stripe.com/oauth/token \ -d client_secret=sk_test_f7PKXx5NRBFG5r41nTrPT7qB \ -d code="{AUTHORIZATIO ...