Bootstrap 4 in Angular 2 folder not working

I did the following to install bootstrap 4 in my Angular 2 project: Accepted answer, after the first 1,2,3 and 4 steps

However, when I add the following HTML to my header component:

 <nav class="navbar-dark bg-inverse"> <div class="container"> <a href="#" class="navbar-brand"></a> <ul class="nav navbar-nav float-xs-right"> <li class="nav-item dropdown"> <a href="#" class="nav-link dropdown-toggle" id="nav-dropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> SomeEmail@hotmail.com </a> <div class="dropdown-menu" aria-labelledby="nav-dropdown"> <a href="#" class="dropdown-item">Sign Out</a> </div> </li> </ul> </div> 

As you can see its drop-down list basically, when I click on the drop-down list, the page refreshes, instead it does not display the exit option.

This is my angular-cli.json :

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

And inside my Angular 2 module:

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

Then I import the NgbModule into the import section.

I obviously missed something, can someone shed light on the fact that it could be for sure?

+12
source share
14 answers
  1. Please install ng-bootstrap from this Get Started link using the following command:

     npm 'install --save @ng-bootstrap/ng-bootstrap' 
  2. Import it on app.module.ts as

     import '{NgbModule} from '@ng-bootstrap/ng-bootstrap';' 
  3. Import to

     imports:[ NgbModule.forRoot(), ] 
  4. Add ngbDropdown to ngbDropdown

  5. Add ngbDropdownToggle to drop-down ngbDropdownToggle Toggle DOM

  6. Add ngbDropdownMenu to the DOM popup menu

      <li ngbDropdown class="nav-item dropdown" > <a ngbDropdownToggle class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Manage </a> <div ngbDropdownMenu class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink"> <a class="dropdown-item" href="#">Save Data</a> <a class="dropdown-item" href="#">Fetch Data</a> </div> </li> </ul> 
+13
source

A variation on @VictorLuchian for the newest BS4 beta strong>, it seems that the show class also needs to be added to the drop-down menu. This version includes a click outside the close, not a mouse.

 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') } } } 
+12
source

Some CSS plugins and components depend on other plugins. If you include plugins separately, be sure to check these dependencies in the documentation. Also note that all plugins are jQuery dependent (this means jQuery must be included before the plugin files ).

In .angular-cli.json add the following lines to the script section:

 # version 4.x "scripts": [ "../node_modules/jquery/dist/jquery.js", "../node_modules/bootstrap/dist/js/bootstrap.js", ] 

Checkout here

+7
source

As Andrien said, you can simplify the code as follows.

 constructor(private _el: ElementRef) { } @HostBinding('class.show') isOpen = false; @HostListener('click') toogleOpen() { this.isOpen = !this.isOpen; this._el.nativeElement.querySelector('.dropdown-menu').classList.toggle('show') } 
+5
source

You will need to add a dropdown directive 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 add the attribute as follows:

 <li class="nav-item dropdown" appcustomdropdown > 
+3
source

StackBliz Code Example Link

First, Bootstrap 3 and 4. Different classes of active state are different

  1. In Boostrap 3: in a drop-down open state; Added parent element .dropdown-toggle " open " CSS class

  2. Where, as in Boostrap 4, use the " show " CSS class in the pop-up open state. Here is added the parent element of the .dropdown-toggle element and the next element with the CSS class. Dropdown-menu " show " css Class

Therefore, to make the boostrap 4 drop-down list work with angular 4, we will create a new class of angular directive and add it to the boostrap drop-down list in the angular template.

Step 1 - Create a 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 into app.module.ts

 import { NgBoostrapDropdownDirective } from './directives/ng-boostrap-dropdown.directive'; @NgModule({ declarations: [ AppComponent, NgBoostrapDropdownDirective ], }) 

Step 3: Apply the directive in the 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> 

StackBliz Code Example Link

+1
source

Inspired by the first version of Rahul Talar (Step 1 - Create a new angular directive in ng-boostrap-dropdown.directive.ts), I made several similar ones using Rendere2

 import { Directive, HostListener, ElementRef, Renderer2, OnInit } from '@angular/core'; @Directive({ selector: '[appDropdown]' }) export class AppDropdownDirective implements OnInit { private isShow = false; private classShow = 'show'; private parentNode: HTMLElement; private siblingNode: HTMLElement; constructor(private elementRef: ElementRef, private renderer: Renderer2) {} ngOnInit() { this.parentNode = this.renderer.parentNode(this.elementRef.nativeElement); this.siblingNode = this.renderer.nextSibling(this.elementRef.nativeElement); } @HostListener('click') open() { this.isShow = !this.isShow; if (this.isShow) { this.addClass(); } else { this.removeClass(); } } @HostListener('document:click', ['$event']) clickout(event) { if (this.elementRef.nativeElement !== event.target && this.isShow) { this.removeClass(); this.isShow = false; } } private addClass() { this.renderer.addClass(this.parentNode, this.classShow); this.renderer.addClass(this.siblingNode, this.classShow); } private removeClass() { this.renderer.removeClass(this.parentNode, this.classShow); this.renderer.removeClass(this.siblingNode, this.classShow); } } 
+1
source

CSS must be in the <head></head> .
I quote from bootstrap

Copy the stylesheet <link> into your <head> before all other stylesheets to load our CSS.

I keep quoting

Add our JavaScript, jQuery, and Tether plugins at the end of your pages, before the closing tag. Be sure to put jQuery and Tether, as our code depends on them.

Make sure you have a link to bootstrap documentation this way, where I get these quotes https://v4-alpha.getbootstrap.com/getting-started/introduction/

and check this answer in the post in which you share the link fooobar.com/questions/49172 / ...

0
source

Someone has created a new version of the template library specifically designed for Angular 2+. According to the website, it was developed by the ng team, although the link it gives gets a 404 response. It really works, and I used it in several places throughout my current project. You just need to pick up the library using npm. All instructions are on this website:

http://valor-software.com/ngx-bootstrap/#/

This page shows all the installation and use instructions that you need to get started. Hope this helps!

0
source

I used a different approach in order to get a drop on the folded navbar.

STEP 1 Add a click event on the navigator 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> 

Step 2: implement the function inside Navbar component.ts (Above the navbar template, html is used inside the navbar component)

 import { Component} from '@angular/core'; export class HeaderComponent { buttontoggled:boolean:false; OnClik(){ this.buttontoggled=!this.buttontoggled; } 

Step 3 Based on the navigator toggle button, click the add show show (bootstrap 4) or open button for previous boot versions. we can use the ngClass directive for this

  <div class="collapse navbar-collapse " [ngClass]="{'show': buttontoggled}" id="myNavbar"> 

Work flow

Navbar toggle button will be visible when a crash occurs when entering the navigation bar for lower resolutions

handling the button click event, we can set one flag to check if the button is pressed or not

Based on this flag we will link the css class to the navabr div using the ngClass directive

0
source

I use a theme that is not an assembly for Angular, and it contains the classic bootloader, I had the same problem and fixed it by modifying the bootstrap.js file.

The problem is that listening events are loaded from $ (document) .on, and the problem is in the "document" part.

In my bootstrap file, this is line 18001

  /** * ------------------------------------------------------------------------ * Data Api implementation * ------------------------------------------------------------------------ */ $(document).on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API + " " + Event.KEYUP_DATA_API, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { event.preventDefault(); event.stopPropagation(); Dropdown._jQueryInterface.call($(this), 'toggle'); }).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) { e.stopPropagation(); }); 

Change $ (document) to $ ("body") and this will work.

  $("body").on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API + " " + Event.KEYUP_DATA_API, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { event.preventDefault(); event.stopPropagation(); Dropdown._jQueryInterface.call($(this), 'toggle'); }).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) { e.stopPropagation(); }); 
0
source

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'); } } 
0
source
 import { Directive, HostListener, HostBinding, ElementRef } from '@angular/core'; @Directive({ selector: '[appDropdown]' }) export class DropdownDirective { constructor(private _el: ElementRef) { } @HostBinding('class.show') isOpen = false; @HostListener('click') toggleOpen(){ this.isOpen=!this.isOpen; if(this.isOpen){ this._el.nativeElement.querySelector('.dropdown-menu').classList.add('show'); } else{ this._el.nativeElement.querySelector('.dropdown-menu').classList.remove('show'); } } } 
0
source

With Angular 8 and Bootstrap 4.2, this is a working solution that I use:

1- First I created a custom directive. It listens for the button click event in the drop-down container and switches the .show class of the .dropdown-menu element (standard Bootstrap 4 behavior). In addition, it will close the drop-down menu if there is a click anywhere else in the document.

 import {Directive, ElementRef, HostBinding, HostListener, OnInit} from '@angular/core'; @Directive({ selector: '[appDropdown]' }) export class DropdownDirective implements OnInit { dropDownMenu: HTMLElement; @HostListener('document:click', ['$event']) toggleOpen(event: Event) { if ( this.dropDownButton.nativeElement.contains(event.target) ) { this.dropDownMenu.classList.toggle('show'); } else { this.dropDownMenu.classList.remove('show'); } } constructor(private dropDownButton: ElementRef) { } ngOnInit(): void { this.dropDownMenu = this.dropDownButton.nativeElement.querySelector('.dropdown-menu'); } } 

2- Once your directive is created and registered. Be sure to apply the directive to the dropdown element, as in this example:

 <div class="btn-group" appDropdown> <button type="button" class="btn btn-primary dropdown-toggle">Dropdown menu<span class="caret"></span></button> <ul class="dropdown-menu"> <li class="dropdown-item"><a href="#">Item One</a></li> <li class="dropdown-item"><a href="#">Item Two</a></li> <li class="dropdown-item"><a href="#">Item Three</a></li> </ul> </div> 
0
source

Source: https://habr.com/ru/post/1261855/


All Articles