Click on an element in Angular to toggle it

A function in my codebase is responsible for toggling a specific section within a div element.

Currently, there are a total of 3 sections available in the app.

The functionality is implemented in the app.component.ts file:

show = false;


toggle() {
    this.show = !this.show;
}

In the app.component.html file:

<div>
    <div *ngIf="show">
      <div>One</div>
    </div>
    <button type="button" toggle()"></button>
</div>

<div>
    <div *ngIf="show">
      <div>Two</div>
    </div>
    <button type="button" toggle()"></button>
</div>

<div>
    <div *ngIf="show">
      <div>Three</div>
    </div>
    <button type="button" toggle()"></button>
</div>

As it stands now, all three sections toggle visibility when clicking on any button.

Is there a way to modify this behavior so that only the corresponding section toggles when clicking on its respective button with *ngIf="show"?

Answer №1

Here is the code snippet you are looking for: app.component.ts

toggleStatus =[false,false,false];

toggle(index:number) {
    this.toggleStatus[index] = !this.toggleStatus[index];
}

app.component.html

<div>
    <div *ngIf="toggleStatus[0]">
      <div>One</div>
    </div>
    <button type="button" toggle(0)"></button>
</div>

<div>
    <div *ngIf="toggleStatus[1]">
      <div>Two</div>
    </div>
    <button type="button" toggle(1)"></button>
</div>

<div>
    <div *ngIf="toggleStatus[2]">
      <div>Three</div>
    </div>
    <button type="button" toggle(2)"></button>
</div>

Answer №2

To simplify your controller code, consider exploring the use of Angular's TemplateRef to create distinct templates for different sections.

Templates:

<ng-template #templateOne>
  One
</ng-template>

<ng-template #templateTwo>
  Two
</ng-template>

<ng-template #templateThree>
  Three
</ng-template>

<ng-container *ngTemplateOutlet="template"></ng-container>
<br /><br />

<button type="button" (mouseup)="showRef(templateOne)">Show Template 1</button>
<button type="button" (mouseup)="showRef(templateTwo)">Show Template 2</button>
<button type="button" (mouseup)="showRef(templateThree)">Show Template 3</button>
<button type="button" (mouseup)="showRef(null)">Hide all</button>

In your controller, assign the desired <ng-template> block to the template variable in order to display it.

import { Component, TemplateRef } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent {
  template: TemplateRef<any>;

  showRef(template: TemplateRef<any>) {
    this.template = template;
  }
}

See a live demo here: Stackblitz

Answer №3

To manage the visibility of different sections, you can create a specialized class with properties for each section:

class SectionVisibilityManager {
     private boolean _section1 = false;
     private boolean _section2 = false;
     private boolean _section3 = false;

     public toggle(index: number): boolean {
         this['_section' + index] = !this['_section' + index];
     }

     public get section1(): boolean {
         return this._section1;
     }

     public get section2(): boolean {
         return this._section2;
     }

     public get section3(): boolean {
         return this._section3;
     }
}

You can then use getters to access these properties in your template:

<div>
   <div *ngIf="visibilityManager.section1">
     <div>One</div>
   </div>
   <button type="button" toggle()"></button>
</div>

<div>
    <div *ngIf="visibilityManager.section2">
      <div>Two</div>
    </div>
    <button type="button" toggle()"></button>
</div>

<div>
    <div *ngIf="visibilityManager.section3">
      <div>Three</div>
    </div>
    <button type="button" toggle()"></button>
</div>

In your component, make sure to define an instance of the SectionVisibilityManager object:

public visibilityManager: SectionVisibilityManager = new SectionVisibilityManager();

This approach allows you to have a centralized logic for managing section visibility within your application.

Alternatively, you can turn this class into a service and inject it where needed.

IMPORTANT: If your sections are dynamically created, consider using an array in the manager class along with methods for toggling specific indices and accessing elements by index.

Answer №4

You have the option to utilize [ngSwitch] for resolving this issue. Explore the stackblitz link below for more details.

app.component.html

<nav>
  <ul style="cursor: pointer;">
    <li (click)="showTab('tab1')"><a href="#">Tab1</a></li>
    <li (click)="showTab('tab2')"><a href="#">Tab2</a></li>
    <li (click)="showTab('tab3')"><a href="#">Tab3</a></li>
  </ul>
</nav>
<ng-container [ngSwitch]="tab">
  <div *ngSwitchCase="'tab1'">
    <h1>Tab 1</h1>
  </div>
  <div *ngSwitchCase="'tab2'">
    <h1>Tab 2</h1>
  </div>
  <div *ngSwitchCase="'tab3'">
    <h1>Tab 3</h1>
  </div>
</ng-container>

app.component.ts

export class AppComponent  {
  public tab: string = "tab1";

  public showTab(tab: string) {
    this.tab = tab;
  }
}

Visit stackblitz for live demo

Learn more about NgSwitch on Angular official documentation

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

What methods can I use to dismantle an Angular component?

I have created a modal as a component called <modal-component>. Within the <modal-component>, there is a close button. I am looking for a way to completely remove the <modal-component> when this close button is clicked. I envision somet ...

The process of automatically formatting Typescript has transformed into an unfortunate auto-discarding action

Typescript autoformatting has become a concerning issue. Whenever I input quoted strings (" or `), the code surrounding it seems to temporarily glitch, with other strings appearing as code. This problem has recently escalated, particularly with strings li ...

Tips for Disabling ML5 Posenet

Looking to halt Posenet after completing app task private sketch(p: any) { p.setup = () => { this.poseNet = ml5.poseNet(p.createCapture(p.VIDEO), { outputStride: 8 }); this.poseNet.on(&apos ...

Is it possible to directly parse a multipart/mixed response without needing to first convert it into a string?

My current challenge involves receiving a multipart/mixed response over HTTP that includes JSON data and PDFs in byte format. Due to Angular's limitations with handling such responses, I have resorted to converting the response into a string using the ...

Flex-Layout in Angular - The Ultimate Combination

Recently, I decided to delve into Angular and the Flex-Layout framework. After installing flex-layout through npm, I proceeded to import it in my app.module.ts file like so: import { FlexLayoutModule } from '@angular/flex-layout'; imports: [ Fl ...

Exploring Angular 9: Experimenting with iterating over a collection of objects and performing validations

Forgive me if this is a basic question, but I am new to Angular 9 and json. I am attempting to iterate through a list and only create a table row if the correct ID matches the ID passed from the previous page link. I am struggling to make the if statement ...

Creating a function in Angular to locate each object based on its ID

Hello there, I am currently working on creating a method called findChildByIdInData(data:any, childId:string). This method will take in a JSON main node with children that have unique IDs, and the goal is to find a specific object based on the ID provided ...

Exporting Arrays in Ionic Angular with Typescript is an essential feature

When trying to access an exported component in Typescript, there may be issues with importing the module correctly into another component. An error message is displayed when calling the AddToArray method: Cannot read property 'push' of undefi ...

Can one extract a property from an object and assign it to a property on the constructor?

Currently working with TypeScript, I am looking to destructure properties from an object. The challenge lies in the fact that I need to assign it to a property on the constructor of the class: var someData = [{title: 'some title', desc: 'so ...

What is the best way to organize objects based on their timestamps?

I am faced with the task of merging two arrays of objects into a single array based on their timestamps. One array contains exact second timestamps, while the other consists of hourly ranges. My goal is to incorporate the 'humidity' values from t ...

What is the way to imitate a variable with Jasmine Spy?

Trying to troubleshoot a login feature, how can I mock everything except string variables? @Component({ selector: 'app-login', templateUrl: './login.component.html', styleUrls: ['./login.component.scss']) export c ...

Utilizing external clicks with Lit-Elements in your project

Currently, I am working on developing a custom dropdown web component using LitElements. In the process of implementing a feature that closes the dropdown when clicking outside of it, I have encountered some unexpected behavior that is hindering my progres ...

"Sequencing http.get requests in Angular 2 using

In my service, I have a series of http.get requests structured as follows: constructor(private http:Http) {} getDetails(sysID:string){ var details; this.http.get('https://blahURL').map(res => res.json().filter(f => f.id == another.id)[0] ...

When executing the "node app.js" command, the <app-root> element appears empty in the browser

After creating an Angular 7 application with the Angular CLI and adding my express server, I encountered a strange issue. When starting my app with the command "node server/app.js", the browser displayed <app-root></app-root> in the "Elements" ...

The use of the cache-control request header field is prohibited when attempting to sign in with an Angular frontend during the

I recently developed an application using Angular with a Java backend in Spring. However, I'm facing an error when trying to log in and it's related to CORS policy. Whenever I try to login, I receive the following error message: Access to XMLH ...

Unresolved HTTP header problem with Angular 4 and Siteminder

Struggling with integrating Siteminder authentication for my nodejs/angular 4 web application has been a challenge for me over the past few weeks. On the server side (node), my code looks like this: app.get('*', function(req, res) { //read Si ...

Utilizing TypeScript interfaces with additional parameter object members does not result in the anticipated compilation error

Consider the different types listed below: type Person = { id: string; name: string; }; interface PeopleRepository { getPerson(query: { id: string }): Person; } class Repository implements PeopleRepository { getPerson({ id, age }: { id: string; ...

Angular failing to retrieve URL parameters correctly

As I was trying to retrieve URL queries like www.website.com?a:b, I decided to follow the guidance provided in a particular Angular tutorial. This official tutorial (accessible via this link) instructed me to implement the following simple code snippet wit ...

I am having trouble accessing my JSON data via HTTP get request in Angular 2 when using TypeScript

I am working on developing a JSON file configuration that can be accessed via HTTP GET request in order to retrieve the desired value from the config file and pass it to another component. However, whenever I try to return the value, it shows up as undefin ...

Type 'ɵɵComponentDeclaration' must be provided with at least 7 but no more than 8 type arguments

Recently, in my project, I encountered an issue with the ng-particles v3.5.3 library on my login and sign-in pages. The problem arose suddenly and was displayed in my terminal as follows: Error: node_modules/ng-particles/lib/ng-particles.component.d.ts:18: ...