Source:  Twitter logo

I'm trying to create a dropdown item in a Bootstrap navbar using Angular 6. My code is working when I test it online :

<nav class="navbar bg-light navbar-light navbar-expand">
<ul class="navbar-nav">
  <li class="nav-item dropdown" >
    <a class="nav-link dropdown-toggle" data-toggle="dropdown">Page1</a>
    <div class="dropdown-menu">
      <a class="dropdown-item" href="#">Page1.1</a>
    </div>
  </li>
  <li><a class="nav-link" href="#">Page2</a></li>
</ul>
</nav>

But the dropdown does not work with Angular 6. I've used the following method in order to use Bootstrap with Angular :

ng add @ng-bootstrap/schematics

And everything works fine except for that dropdown item !

I have came across the same problem earlier and I found as below:

  1. html should be binded with the class container in bootstrap as mentioned in Bootstrap Layout
  2. Dropdowns are built on a third party library Popper.js as mentioned in Bootstrap Dropdown

As far as I know from your problem that you haven't refer to the required javascript i.e. util.js, bootstrap.js, popper.js or minified version.

Here, I have done nothing much, just refer the required javascript files in the index file

<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>

And I created a nav component and design as required like this:

<div class="container">
    <!-- Content here -->
    <ul class="nav nav-pills">
        <li class="nav-item">
            <a class="nav-link active" href="#">Active</a>
        </li>
        <li class="nav-item dropdown">
            <a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">Dropdown</a>
            <div class="dropdown-menu">
                <a class="dropdown-item" href="#">Action</a>
                <a class="dropdown-item" href="#">Another action</a>
                <a class="dropdown-item" href="#">Something else here</a>
                <div class="dropdown-divider"></div>
                <a class="dropdown-item" href="#">Separated link</a>
            </div>
        </li>
        <li class="nav-item">
            <a class="nav-link" href="#">Link</a>
        </li>
        <li class="nav-item">
            <a class="nav-link disabled" href="#">Disabled</a>
        </li>
    </ul>
</div

The working demo can be found here. Hope this helps you.

23 users liked answer #0dislike answer #023
Iswar profile pic
Iswar

I have faced the same issue of bootstrap, but I got the solution. If you are using Angular 6, then no need to add popper.js for bootstrap. You need to add bootstrap 4 and then add rxjs-compat.

npm install rxjs-compat

And add ngx-bootstrap to perform dropdown action. Install the ngx-bootstrap,

npm install ngx-bootstrap --save

now we need to add the dropdown module from ngx-bootstrap in your application using following code

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
import { ModalModule } from 'ngx-bootstrap/modal';
import { AppComponent } from './app.component';

@NgModule({
 declarations: [
   AppComponent
 ],
 imports: [
   BrowserModule,
   CommonModule,
   BsDropdownModule.forRoot(),
   TooltipModule.forRoot(),
   ModalModule.forRoot()
 ],
 providers: [],
 bootstrap: [AppComponent]
})
export class AppModule { }

then I did some changes in your code and it's working fine for me.

<nav class="navbar navbar-default">
<ul class="nav navbar-nav">
  <li class="dropdown" dropdown >
    <a dropdownToggle role="button"> <!-- {2} -->
        Page1<span class="caret"></span></a>
    <div *dropdownMenu class="dropdown-menu">
      <a class="dropdown-item" href="#">Page1.1</a>
    </div>
  </li>
  <li><a class="nav-link" href="#">Page2</a></li>
</ul>
</nav>
8 users liked answer #1dislike answer #18
Rushikesh Salunke profile pic
Rushikesh Salunke

The answer of @Rushikesh Salunke is great but at the time i saw it i was already using @ng-bootstrap library, not ngx, and this is what i found from the docs.

First, import the NgbDropdown Module into the component where you want to use it.

import { NgbDropdown} from '@ng-bootstrap/ng-bootstrap';

Then modify your .html as follows:

<div ngbDropdown class="d-inline-block">
  <button class="btn btn-outline-primary" id="dropdownBasic1" ngbDropdownToggle>Toggle dropdown</button>
  <div ngbDropdownMenu aria-labelledby="dropdownBasic1">
    <button class="dropdown-item">Action - 1</button>
    <button class="dropdown-item">Another Action</button>
    <button class="dropdown-item">Something else is here</button>
  </div>
</div>

You can see other use cases here.

6 users liked answer #2dislike answer #26
gonzarodriguezt profile pic
gonzarodriguezt

Here you go...

I did below changes -

1. app.component.html

<p>
  Start editing to see some magic happen :)
</p>
<nav class="navbar bg-light navbar-light navbar-expand">
<ul class="nav navbar-nav">
  <li class="dropdown" appDropdown>
    <a href="#" class="dropdown-toggle" role="button">Page1</a>
    <ul class="dropdown-menu">
      <li><a href="#">Page1.1</a></li>
      <li><a href="#">Page1.2</a></li>
      <li><a href="#">Page1.3</a></li>
    </ul>
  </li>
  <li><a class="nav-link" href="#">Page2</a></li>
</ul>
</nav>

2. app.module.ts

I have added one directive to listen click event for dropdown and imported same in app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';

import { DropdownDirective } from './dropdown.directive';

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HelloComponent, DropdownDirective ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

3. dropdown.directive.ts

Added directive to listen click event

import { Directive, HostListener, ElementRef, Renderer2 } from "@angular/core";

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

export class DropdownDirective {
  manageDropdown : boolean = false;

  constructor(private elementRef: ElementRef, private renderer: Renderer2)   {

  }

  @HostListener('click') openDropdown(eventData: Event) {
    if(!this.manageDropdown) {
      this.renderer.addClass(this.elementRef.nativeElement,'open');
      this.manageDropdown = !this.manageDropdown;
    } else {
      this.renderer.removeClass(this.elementRef.nativeElement, 'open');
      this.manageDropdown = !this.manageDropdown;
    }
  }
}

4. angular.json

Requesting you to do "npm install --save bootstrap@3" and do below changes in angular.json file.

"styles": [
              "src/styles.css",
              "../node_modules/bootstrap/dist/css/bootstrap.min.css"
            ],
            "scripts": [
              "../node_modules/bootstrap/dist/js/bootstrap.min.js"
            ]

Note - For your reference please visit reference link. You can see the dropdown demo.

2 users liked answer #3dislike answer #32
Flutterian profile pic
Flutterian

When you do everything right and follow the examples given, and it doesn't seem to work, it can be that you forgot to import Bootstrap Module.

You can do this by this line to your main module in which you intend to use the component:

import { NgbModule } from '@ng-bootstrap/ng-bootstrap'

@NgModule({
  declarations: [MyComponent],
  imports: [
    NgbModule
  ],
  exports: [MyComponent]
})
0 users liked answer #4dislike answer #40
Motasem Halawani profile pic
Motasem Halawani
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script>


<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
crossorigin="anonymous"></script>


<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"></script>

Adding this in index.html before closing body tag. This works for me.

 <ul class="navbar-nav navbar-right">
        <li class="nav-item dropdown">
            <a class="nav-link dropdown-toggle" role="button" data-toggle="dropdown" aria-haspopup="true"
                aria-expanded="false">
                Manage Data
            </a>
            <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                <a class="dropdown-item" href="">Save Data</a>
                <a class="dropdown-item" href="">Fetch Data</a>
            </div>
        </li>
    </ul>
0 users liked answer #5dislike answer #50
Aishwarya Satish Surwase profile pic
Aishwarya Satish Surwase

Step 1: install ng-bootstrap

ng add @ng-bootstrap/ng-bootstrap

Step 2: Add ng-bootstrap module to your component module file

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';

...

@NgModule({
  imports: [BrowserModule, NgbModule],
  ...
})

Step 3: In your component view file add the following code:

<div class="col">
    <div ngbDropdown class="d-inline-block">
      <button class="btn btn-outline-primary" id="dropdownBasic1" ngbDropdownToggle>Toggle dropdown</button>
      <div ngbDropdownMenu aria-labelledby="dropdownBasic1">
        <button ngbDropdownItem>Action - 1</button>
        <button ngbDropdownItem>Another Action</button>
        <button ngbDropdownItem>Something else is here</button>
      </div>
    </div>
  </div>

Ref: ng-bootstrap Docs

0 users liked answer #6dislike answer #60
Ritik Dua profile pic
Ritik Dua

For anyone who is looking for solution with bootstrap 4.4.1 and Angular 9+, i solved by creating custom directive with following host listener. just adding show to parent li was not doing anything

 @HostListener('click', ['$event']) onClick(event) {
         if (this.el.nativeElement.classList.contains('show')) {
            this.renderer.removeClass(this.el.nativeElement, 'show');
            this.renderer.setAttribute(this.el.nativeElement.childNodes[0], 'aria-expanded', 'false')
            this.renderer.removeClass(this.el.nativeElement.childNodes[1], 'show')

        } else {
            this.renderer.addClass(this.el.nativeElement, 'show')
            this.renderer.setAttribute(this.el.nativeElement.childNodes[0], 'aria-expanded', 'true')
            this.renderer.addClass(this.el.nativeElement.childNodes[1], 'show')
        }
    }
-1 users liked answer #7dislike answer #7-1
Artur O profile pic
Artur O

Copyright © 2022 QueryThreads

All content on Query Threads is licensed under the Creative Commons Attribution-ShareAlike 3.0 license (CC BY-SA 3.0).