Angular 4/5 | Custom Dropdown Component

I have been working on a custom dropdown directive in Angular that I can attach to any DOM element. Below is the code for my directive:

import { Directive, HostListener } from '@angular/core';

@Directive({
  selector: '[appDropdown]'
})
export class DropdownDirective {

  constructor() { }

  isOpen: boolean = false;

  @HostListener('click') toggle() {
    if (this.isOpen === true) {
      this.hide();
    } else {
      this.show();
    }
    this.isOpen = !this.isOpen;
  }

  private show() {
    // Need help with what to implement here
  }

  private hide() {
    // Need help with what to implement here
  }

}

This directive is designed to respond to clicks on the element it is applied to. When a click event is detected, I want to toggle the visibility of the dropdown element within the same container as the element with the directive. A simplified version of the HTML structure is as follows:

<a appDropdown>Dropdown</a>
<ul class="dropdown"> <--- How can I manipulate the display property of this element when clicking the anchor to show/hide the dropdown?
   <li><a>Option A</a></li>
   <li><a>Option B</a></li>
</ul>

I have checked the Angular documentation thoroughly but couldn't find a clear solution. Any assistance would be greatly appreciated. Thank you!

Answer №1

From what I understand, directives are not meant to be used in this way. I am aiming for a similar result.

As I work on something similar and go through the documentation (and @evandro-mendes' response above), I realize that structural directives are intended to modify the DOM's behavior without defining their own templates (check out angular docs).

Refer to https://github.com/valor-software/ngx-bootstrap/blob/development/src/dropdown/bs-dropdown.directive.ts (or their docs/demo ) where a directive is used to display/hide/manipulate the component, but not to define its own content.

In my approach, using ngx-bootstrap, I create a component as shown below:

dropdown.component.ts:

@Component({
    selector: 'dropdown',
    template: './dropdown.component.html'
})
export class AutosuggestComponent {

    @Input() viewModel: string[];
    @Input() isOpen: boolean = false;
}

dropdown.component.html

<div dropdown [isOpen]="isOpen" [autoClose]="true" placement="top">

<ng-content #input>
</ng-content>

<div *dropdownMenu class="dropdown-menu" role="menu">
    <div *ngFor="let item of viewModel" class="dropdown-item">
        {{item}}
    </div>
</div>

usage

<dropdown [viewModel]="sourceData" [isOpen]="isDropdownOpen">
    <input type="text">
</dropdown>

This method allows me to avoid specifying any custom behavior and still utilize the dropdown for any input in the application.

I hope this explanation helps :)

Answer №2

In my opinion, it would be beneficial to incorporate certain Angular5 attributes.

To learn more about this, you can visit the following link:

Building An Angular 5 Project with Bootstrap 4 and Firebase

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

The client using socket.io is receiving events for "double plus one"

While experimenting with socketio, I encountered a bug that others are experiencing as well but I haven't been able to find a valid solution. This is the server-side code: const app = require('express')(); const server = require('http& ...

Nodejs functions properly on a local machine, however, it encounters issues when deployed on a VPS

My nodejs/javascript code seems to be running fine on my local pc, but when I try to run it on my vps, it's not working properly. Even though I have the same node_modules installed and the code is identical. Here's a snippet of my code for refere ...

Can you provide the function that updates subscription and account details using Recurly JS?

Recurly has unfortunately declined to provide assistance with this issue. I must understand the specific format of the objects, as Recurly will not process any extra data or incorrect query arguments (which vary for each function). Ruby: subscription = ...

Auto Start Feature for jQuery Slider Function

Hey there, I currently have an image slider on my website that allows users to navigate through images by clicking on preview and next buttons. My query is: would it be possible to implement an auto start feature instead of having to click manually? Belo ...

Specialized type for extra restriction on enum matching

In my current project, I am dealing with two enums named SourceEnum and TargetEnum. Each enum has a corresponding function that is called with specific parameters based on the enum value. The expected parameter types are defined by the type mappings Source ...

Ways to extract a specific element from a webpage's body section

When utilizing node-fetch to retrieve the body of a site, I follow this process: import fetch from 'node-fetch'; (async () => { const response = await fetch('link'); const body = await response.text(); console.log(body) ...

Guide on utilizing the maven-exec-plugin to execute npm clean commands

I am currently utilizing the exec-maven-plugin in my project. I have added extensions for npm install and npm clean commands. Below is the configuration section of the plugin in the pom file, which includes extensions for npm install, tsc run, and npm clea ...

Error: An attempt to make changes to a database that does not permit mutations has resulted in an InvalidStateError

I am facing an issue while attempting to initiate a transaction within the then() function. An exception is thrown when I try to do so. Below is the code snippet in question: open.onsuccess = function (e1) { var dbase = e1.target.result; $.get("https://w ...

Conditioning types for uninitialized objects

Is there a way to create a conditional type that can determine if an object is empty? For instance: function test<T>(a: T): T extends {} ? string : never { return null } let o1: {} let o2: { fox? } let o3: { fox } test(o1) ...

Utilizing Angular 5: Enhancing ngFor with a Pipe and a Click Event

Iterating through an array of objects using *ngFor, I apply various filters via pipes to manipulate the resulting list. One of these pipes relies on a user input from a search field. Upon clicking on one of the ngFor elements, the corresponding object is p ...

Trouble arises when attempting to establish an isolated scope within Angular alongside UI Bootstrap

My table of data is set up with AngularJS, and one of the columns is calculated using a function in the controller. On my webpage, I have a button that opens a modal. When I use UI Bootstrap to open the modal, it creates a new isolated scope (child of the ...

Calculate the occurrences of numbers within a string in an array of objects containing a specific string each time an object is removed

I am facing an issue where I need to re-number strings based on their type, regardless of their previous number. For example, if I delete Oranges 2 from [Oranges 1, Oranges 2, Oranges 3], it should become [Oranges 1, Oranges 2]. This means the numbers shou ...

Challenge with Routing in Angular 2

I'm dealing with a route setup like this: path: 'something/:id/somethingElse' In my header.component.html, I need to include a link to this page. I tried the following approach: <a routerLink="['something',myIdThatIsDynamicO ...

Is there a way to make the hoverzoom effect only apply to a specific object instead of all objects?

I'm currently troubleshooting my code in order to implement a hover effect on Mui <cards> when a user hovers over the object. I have managed to make it work partially, but the issue is that the effect gets applied to all objects instead of just ...

I am encountering an issue where the useState hook is returning an undefined value on separate components, even after

When setting up a login context, I wrap all my routes with the context provider and pass the initial value using useState: <userContext.Provider value={{loggedUser, setLoggedUser}}> In LogInMenu.jsx, which is responsible for setting the loggedUser ( ...

Different applications of data streaming apart from multimedia content

Exploring the various applications of streaming, particularly when sending data from a server to a visual client such as a web browser or an application, has sparked my curiosity. While I grasp the fundamental idea of transmitting data in chunks rather t ...

Partially accessible Angular service within a callback function

I'm currently facing an issue in my Angular simple app related to a factory that is not fully available within a callback function. You can check out a simplified version of the application on this Plunkr link. Here's a snippet of the code: Th ...

Having trouble getting a JS file to work with the Laravel Inertia.js and Vue.js3 template

Just getting started with inertia.js and facing an issue. My CSS styles are being applied, but my JavaScript file isn't functioning as expected. I'm working on an admin dashboard using Laravel 9 and vue.js-3 with a custom HTML template. Interes ...

Conceal any ng-repeat elements that do not contain corresponding grandchildren within two levels of nested ng-repeats

Apologies for the enigmatic title, but the issue at hand is quite cryptic ¯\_(ツ)_/¯ I'm dealing with a complex problem involving 3 nested ng-repeats to display Google Analytics' account structure. Within this structure are multiple acco ...

How can I generate a dummy JSON response using Backbone Fetch?

Exploring Backbone and looking for a way to simulate the response of a .fetch() call within a model without using a testing library or connecting to an external service. If the setting in the model is this.options.mock === true, I'd like to use an in ...