I have followed the following to install bootstrap 4 into my Angular 2 project: Accepted Answer, following the first 1,2,3 and 4 steps
However when I add the following <
Variation on @VictorLuchian for newest BS4 beta, it seems 'show' class need to be added on the dropdown-menu as well. This version include a click outside close instead of mouseout
import { Directive,HostListener,HostBinding, ElementRef } from '@angular/core';
@Directive({
selector: '[customdropdown]'
})
export class CustomDropdownDirective {
private isOpen: boolean =false;
constructor(private _el: ElementRef) {
}
@HostBinding('class.show') get opened() {
return this.isOpen;
}
@HostListener('click') open() {
this.isOpen = true;
this._el.nativeElement.querySelector('.dropdown-menu').classList.add('show')
}
@HostListener('document:click', ['$event.target']) close (targetElement) {
let inside: boolean = this._el.nativeElement.contains(targetElement);
if(!inside) {
this.isOpen = false;
this._el.nativeElement.querySelector('.dropdown-menu').classList.remove('show')
}
}
}
You will need to add a dropdown directive in order for this to work. The directive looks like this:
import { Directive,HostListener,HostBinding } from '@angular/core';
@Directive({
selector: '[appcustomdropdown]'
})
export class CustomdropdownDirective {
constructor() { }
@HostBinding('class.open') get opened()
{
return this.isOpen;
}
@HostListener('click') open()
{
this.isOpen=true;
}
@HostListener('mouseleave') close()
{
this.isOpen=false;
}
private isOpen=false;
}
Then, you will add the attribute like so:
<li class="nav-item dropdown" appcustomdropdown >
navbar.component.html
<li class="nav-item dropdown show" appDropdown>
<a class="nav-link dropdown-toggle" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Categories
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a routerLink="yourLInk1" class="dropdown-item">Item 1</a>
<a routerLink="yourLInk2" class="dropdown-item">Item 2</a>
<a routerLink="yourLInk3" class="dropdown-item">Item 3</a>
<a routerLink="yourLInk4" class="dropdown-item">Item 4</a>
<div class="dropdown-divider"></div>
<a routerLink="yourLInk5" class="dropdown-item">Item 5</a>
</div>
</li>
dropdown.directive.ts
import { Directive, HostBinding, HostListener, ElementRef } from '@angular/core';
@Directive({
selector: '[appDropdown]'
})
export class DropdownDirective {
constructor(private elementRef: ElementRef) { }
private dropdownParentEl = this.elementRef.nativeElement.closest('.dropdown');
@HostListener('mouseenter') toggleOpen(){
this.dropdownParentEl.querySelector(".dropdown-menu").classList.add('show');
}
@HostListener('mouseleave') toggleClose(){
this.dropdownParentEl.querySelector(".dropdown-menu").classList.remove('show');
}
@HostListener('click') toogleOpen() {
this.dropdownParentEl.querySelector(".dropdown-menu").classList.toggle('show');
}
}
Somebody has created a new version of the template library specifically design for Angular 2+. According to the website, it was developed by ng-team, although the link it gives gets a 404 response. It does work, though, and I have used it in multiple places throughout my current project. You'll just have to pull in the library with npm. All of the instructions are on this website:
http://valor-software.com/ngx-bootstrap/#/
That page shows you all of the install and usage instructions you need to get started. I hope this helps!
i have used a different approach for getting drop down on collpased navbar.
STEP 1 Add click event on navbar toggle button
<button type="button" class="navbar-toggle" data-toggle="collapse" (click)="OnClik()" data-target="#myNavbar"
Html
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" (click)="OnClik()" data-target="#myNavbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">WebSiteName</a>
</div>
<div class="collapse navbar-collapse " [ngClass]="{'show': buttontoggled}" id="myNavbar">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Home</a></li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Page 1 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Page 1-1</a></li>
<li><a href="#">Page 1-2</a></li>
<li><a href="#">Page 1-3</a></li>
</ul>
</li>
<li><a href="#">Page 2</a></li>
<li><a href="#">Page 3</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="#"><span class="glyphicon glyphicon-user"></span> Sign Up</a></li>
<li><a href="#"><span class="glyphicon glyphicon-log-in"></span> Login</a></li>
</ul>
</div>
</div>
</nav>
Step2: implement the function inside Navbar component.ts (Above navbar html template is used inside navbar component)
import { Component} from '@angular/core';
export class HeaderComponent {
buttontoggled:boolean:false;
OnClik(){
this.buttontoggled=!this.buttontoggled;
}
Step 3
based on the navbar toggle button click add class show(bootstrap 4) or open
for previous bootstrap versions.
we can use ngClass Directive for this
<div class="collapse navbar-collapse " [ngClass]="{'show': buttontoggled}" id="myNavbar">
Work flow
Navbar toggle button will be visible when navbar geting collapsed for smaller resolutions
by handling the button click event we can set one flag to check if the button clicked or not
Based on this flag we will we will bind the css class show to navabr div using ngClass directive
Example Code StackBliz Link
Firstly Bootstrap 3 & 4 Drop down active state classes are different
In Boostrap 3 : In dropdown open state; .dropdown-toggle parent element is added 'open' CSS class
Where as in Boostrap 4 make use of "show" CSS class In drop down open state. Here .dropdown-toggle element's parent element and next sibling element with CSS class .dropdown-menu are added "show" css Class
Hence to make boostrap 4 dropdown working with angular 4 we will create new angular directive class and add it to boostrap dropdown in angular template
Step 1 - Crate new angular directive in ng-boostrap-dropdown.directive.ts
import { Directive, HostListener, ElementRef } from '@angular/core';
@Directive({
selector: '[appNgBoostrapDropdown]'
})
export class NgBoostrapDropdownDirective {
private isShow: boolean = false;
private dropdownParentEl = this.elementRef.nativeElement.closest('.dropdown');
constructor(private elementRef: ElementRef) { }
@HostListener('click') open() {
this.isShow = !this.isShow;
if (this.isShow) {
this.dropdownParentEl.classList.add('show');
this.dropdownParentEl.querySelector(".dropdown-menu").classList.add('show');
} else {
this.dropdownParentEl.classList.remove('show');
this.dropdownParentEl.querySelector(".dropdown-menu").classList.remove('show');
}
}
@HostListener('document:click', ['$event'])
clickout(event) {
if (this.elementRef.nativeElement.contains(event.target) && this.isShow) {
this.dropdownParentEl.classList.add('show');
this.dropdownParentEl.querySelector(".dropdown-menu").classList.add('show');
} else {
this.dropdownParentEl.classList.remove('show');
this.dropdownParentEl.querySelector(".dropdown-menu").classList.remove('show');
this.isShow = false;
}
}
}
Step 2 : Import this Directive in app.module.ts
import { NgBoostrapDropdownDirective } from './directives/ng-boostrap-dropdown.directive';
@NgModule({
declarations: [ AppComponent, NgBoostrapDropdownDirective ],
})
Step 3 : Apply directive in Template using appNgBoostrapDropdown
NAVIGATION :
<li class="nav-item dropdown" >
<a class="nav-link dropdown-toggle" appNgBoostrapDropdown href="#" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>
<div class="dropdown-menu" aria-labelledby="dropdown01">
<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>
</li>
</ul>
BUTTON DROPDOWN :
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" appNgBoostrapDropdown type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown button
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<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>
</div>
Example Code StackBliz Link