Toggle visibility of Angular component depending on the value of the top menu item that was clicked

Utilize the code below to generate a menu list with three clickable options:

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

Display or hide the component below based on the selection made from the menu. For example, if the second and third options are clicked in the menu, the component should be hidden.

<app-test-component>

</app-test-list>

Consider using the following code snippet:

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

Answer №1

While this solution may not be perfect, based on the information provided in your question, this is the approach I have come up with.

To see a working example, you can click on the 'li' tags in the link below:

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

Answer №2

To improve your component, add a conditional ngIf to the selector and base it on the expected value rather than what it's not:

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

Helpful tip: Consider storing 'valueC' as a constant within the component instead of directly in the HTML. This way, referencing the value in both HTML and your filterChanged() function will be easier and less prone to errors if the value needs to be modified.

In the HTML file:

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

In the component file:

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

If your filterChanged() function solely updates the filterValue, you can also set the value directly from the HTML:

<ul>
    <li *ngFor="let filter of filterList"
        (click)="filterValue = filter"
        [attr.data-nav]="filter">
        {{ filter }}
    </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

Creating directional light shadows in Three.JS: A Step-by-Step Guide

Can shadows be generated using a DirectionalLight? When I utilize SpotLight, shadows are visible. However, when I switch to DirectionalLight, the shadow functionality doesn't seem to work. ...

Incorporating an HTML5 Theme with Angular 2

Is there a way to effectively set up my current Theme, which is built using bootstrap, CSS, and JS? I have included the following CSS and JS files in my theme, but I don't want to add them directly to index.html like in Angular 1. Can anyone suggest ...

The battle between CSS and jQuery: A guide to creating a dynamic zebra-style table without relying on additional plugins

Is there a better way to create a dynamic zebra styling for table rows while still being able to hide certain elements without losing the styling? In this code snippet, I'm using the CSS :nth-of-type(even) to style even rows but running into issues wh ...

In TypeScript, encountering an unanticipated intersection

In my "models" registry, whenever I select a model and invoke a method on it, TypeScript anticipates an intersection of parameters across all registered models. To demonstrate this issue concisely, I've created a dummy method called "getName". expor ...

The 'asObservable' property is not present on the type '() => any'.ts(2339)

Error: Property 'asObservable' does not exist on type '() => any'.ts(2339) Error: Property 'subscribe' does not exist on type 'Subscription'. Did you mean 'unsubscribe'?ts(2551) Error: Property 'sub ...

Permitting a typescript argument of Partial type to exclude all optional fields

I need to specify an input type for a function that may include fields defined by a type Foo. [EDIT] -- A previous version of this question, kept below, used generics. It seems like the question can be simplified without using generics to focus only on a ...

Type inference in TypeScript fails to capture inner level types

Looking at the code snippet below, I'm struggling to understand why FinalType is defined as { test: { test_inner: any } }. The presence of any is puzzling to me (especially since string seems to have disappeared). Interestingly, the return type of tes ...

The position of the legend in Amchart remains unchanged

Dealing with the issue of chart size when there is a large legend can be challenging. I came across an article that addresses this problem: Putting a legend outside the chart area. However, the downside to this solution is that it restricts placing the leg ...

Learning to extract information from a JSON file with various key and value combinations

I am facing a challenge with my JSON data file, which contains UserIDs as keys and Passwords as values. My goal is to use JavaScript for validation by reading this JSON file. The structure of my JSON is as follows: IDsNPass = '[{"A":"A15"},{"B":"B15" ...

Having trouble connecting the app-route with iron-selector and iron-pages

Feeling frustrated with my code. The <app-route> is functioning correctly, but the frustrating part is that the <iron-pages> just won't apply the class="iron-selected" to any of its children! index.html <app-location route="{{route}}" ...

Issue with IE due to jQuery/JavaScript conflict

After selecting one of the two radio buttons, I want to increment the total by $10. If the other option is selected, I want to revert back to the original total price. The jQuery function I am currently using is as follows: function check_ceu() { var ...

Tips for utilizing [(ngModel)] with an object that is empty, null, or undefined in Angular 4

When trying to assign [(ngModel)] inside my .html code to an empty (null or undefined) object, I encountered the error message _co.object is null. There are two scenarios: one where the object has a value and one where it does not. The ngModel works fine i ...

Troubles with validating forms using Material UI

Trying to make a new user using Material UI, the nonprofit field is optional. However, I'm facing an issue with validating the form and then proceeding to send the user's data to an axios POST request. Any assistance would be highly appreciated. ...

Utilizing an SSL certification (pem file) within JavaScript

Currently in the process of developing a program to extract data from the FAA's AIDAP database. I received a security certificate in the form of a .p12 file, which I have successfully converted into a .pem file. However, I am encountering difficulties ...

Sharing data between multiple components in VueJS is an essential aspect of building scalable and maintainable

I am struggling with the code I have. main.js new Vue({ el: '#app', template: '<App/>', components: { App } }) App.vue <template> <div id="app"> // struggling to pass data to component <basics :r ...

The execution of consecutive Ajax requests encounters issues in the Google Chrome and Safari browsers

I am facing an issue where I encounter a problem displaying a sequence of dialogue or AJAX results that depend on each other. For instance, when a user clicks to send a message, it triggers an ajax call, which opens a dialogue box. The user fills out the f ...

Guide to organizing files with custom directory layout in NodeJS

Imagine having multiple files spread across various folders. /parentDir/ |__dirA/ |__file1 |__file2 |... |__dirB/ |__file3 |... |... You want to consolidate them into an archive, with the option of using something like ...

Using jQuery to send a post request to a PHP script using either JavaScript or PHP

Just a quick question for those with experience. I am working on a page where I have implemented a jQuery AJAX post to another PHP page that contains JavaScript. My concern is, will the JavaScript code also be executed? Another scenario to consider is if ...

Is it possible to prevent the Virtual Keyboard from automatically appearing on mobile devices?

Whenever a user enters a number on a page component, the Virtual Keyboard on their Mobile device pops up and shifts the entire page. I am looking for a solution to either disable the on-screen keyboard or ensure that the text box remains visible even when ...

Matching the heights of div-containers within cards

Is there a way to ensure that the containers within my cards are all the same height? I'm not referring to the actual cards themselves, but rather the elements inside them. This is what my code currently looks like: .card-text { border: 1px solid ...