Home > Mobile >  Show/Hide angular component based on value from top menu item clicked
Show/Hide angular component based on value from top menu item clicked

Time:04-20

The below creates a menu list, of three options which can be clicked like a navigation:

<ul>
    <li
        *ngFor="let filter of filterList"
        (click)="filterChanged($event)"
        [attr.data-nav]="filter"
    >{{ filter }}</li>
</ul>

Show/hide the below component based on the values of the top menu events, let's say if I have 3 options in the menu I clicked the second and third value, it should hide the below component

<app-test-component>

</app-test-component>

Should I use

*ngIf="filter !== 'valueA' && 'valueB' "

CodePudding user response:

I have to admit, this is not the best solution but from what I could understand from your question this is what I came up with.

You can refer to the link below for an working example (click on the 'li' tags)

https://stackblitz.com/edit/angular-ivy-u8oxlv?file=src/app/app.component.ts

app.component.ts

export class AppComponent {
  filterList = ['First', 'Second', 'Third'];
  // List of items that has been selected by clicking
  selectedList = [];
  // List of items that needs to be selected for the condition
  itemsNeededForDisplay = ['Second', 'Third'];

  // Flag to either hide or display the component
  displayComponent: boolean = true;

  filterChanged(text) {

    // If we already selected the item, we should remove it from our list, otherwise add it to the list
    const foundIndex = this.selectedList.findIndex((sl) => sl == text);
    if (foundIndex == -1) this.selectedList.push(text);
    else this.selectedList.splice(foundIndex, 1);

    // After every click we should check if we should hide or display the component
    this.handleComponentDisplayRule();
  }

  handleComponentDisplayRule() {
    // This filter will return us a new array that matches the filter (we look if the selectedList has the 'itemsNeededForDisplay')
    let foundSelectedFilters = this.selectedList.filter((elem) => {
      return this.itemsNeededForDisplay.indexOf(elem) > -1;
    });

    // If we get the length same as our 'itemNeededForDisplay' it means that our list has all the values we are looking for
    this.displayComponent = foundSelectedFilters.length != this.itemsNeededForDisplay.length;
  }
}

app.component.html

<span> Selected: {{ selectedList | json }} </span>

<ul>
  <li
    *ngFor="let filter of filterList"
    (click)="filterChanged(filter)"
    [attr.data-nav]="filter"
  >
    {{ filter }}
  </li>
</ul>

<hello *ngIf="displayComponent"></hello>

hello.component.ts

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

@Component({
  selector: 'hello',
  template: `<h1>Hello {{name}}!</h1>`,
  styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent  {
  @Input() name: string;
}

CodePudding user response:

Add ngIf to your component selector and don't validate it on what value it's not but on the value it should be:

<app-test-component *ngIf="filterValue == 'valueC'"></app-test-component>

Additional advice: I suggest you keep 'valueC' in a constant within the component instead of the HTML, considering you'll reference to that value in the HTML and in your filterChanged() function. It'll prevent future mistakes should you want to change the value.

Then in the HTML you have

<app-test-component *ngIf="filterValue == valueC"></app-test-component>

And in the component

const valueA = 'ValueA';
const valueB = 'ValueB';
const valueC = 'ValueC';

If your filterChanged() function only sets the filterValue you can also just set the value straight from the html:

<ul>
    <li *ngFor="let filter of filterList"
        (click)="filterValue = filter"
        [attr.data-nav]="filter">
        {{ filter }}
    </li>
</ul>
  • Related