joe2020wow
joe2020wow

Reputation: 237

Angular Toggle only the element click on

I have a method that toggles a div area.

At the moment I have 3 areas

app.component.ts

show = false;


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

app.component.html

<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>

At the moment is will show and hide the 3 sections.

How can I chan it so that it just toggles the div with the *ngIf="show" that I of the button I clicked?

Upvotes: 0

Views: 3483

Answers (4)

Jason White
Jason White

Reputation: 5843

You could also use [ngSwitch] to solve this problem. (See stackblitz below)

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;
  }
}

https://stackblitz.com/edit/angular-ivy-snj6zw

https://angular.io/api/common/NgSwitch

Upvotes: 0

Barremian
Barremian

Reputation: 31135

If you do not wish to have three different booleans in the controller, you could look into Angular TemplateRef to create different templates for each sections.

Template

<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>

Now you could set the template variable in the controller to the <ng-template> block that needs to be displayed.

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;
  }
}

Working example: Stackblitz

Upvotes: 1

Abdulrahman Hashem
Abdulrahman Hashem

Reputation: 1879

You could have a responsible class for doing this, with a property for each div:

class SectionVisibilityHandler {
     private boolean _div1 = false;
     private boolean _div2 = false;
     private boolean _div3 = false;

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

     public get div1(): boolean {
         return this._div1;
     }

     public get div2(): boolean {
         return this._div2;
     }

     public get div3(): boolean {
         return this._div3;
     }
}

And then, access these properties using getters:

<div>
   <div *ngIf="visibilityHandler.div1">
     <div>One</div>
   </div>
   <button type="button" toggle()"></button>
</div>

<div>
    <div *ngIf="visibilityHandler.div2">
      <div>Two</div>
    </div>
    <button type="button" toggle()"></button>
</div>

<div>
    <div *ngIf="visibilityHandler.div3">
      <div>Three</div>
    </div>
    <button type="button" toggle()"></button>
</div>

And the visibility handler object is defined in your component properties:

public visibilityHandler: SectionVisibilityHandler = new SectionVisbilityHandler();

This way, you can customize your logic behind showing/hiding the div in a specific class and method.

However, you can define this class as a service and inject it inside the component.

NOTE: If your divs are dynamically generated then you need an array in the handling class and two methods, one for toggling a specific index and another one to access arrays' elements by index.

Upvotes: 0

Charlie Cai
Charlie Cai

Reputation: 301

I guess below is what you want: 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>

Upvotes: 3

Related Questions