Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 - hide bootstrap navbar on nav click

Tags:

angular

In mobile, clicking bootstrap navbar item does't hide the menu.

My menu button, which shows for mobiles:

<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">

Searching for this issue returned results unreleated to angular 2 and I have no idea how to implement them.

How I can I hide my navbar when user clicks a link?

<li><a routerLink="/page">Click this should hide nav</a></li>
like image 926
Elikos Avatar asked Oct 28 '16 10:10

Elikos


4 Answers

Pretty nice and easy way to do it within Angular 2/4 template only:

<nav class="navbar navbar-default" aria-expanded="false">
  <div class="container-wrapper">

    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" (click)="isCollapsed = !isCollapsed">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
    </div>

    <div class="navbar-collapse collapse no-transition" [attr.aria-expanded]="!isCollapsed" [ngClass]="{collapse: isCollapsed}">
      <ul class="nav navbar-nav" (click)="isCollapsed = !isCollapsed">
        <li [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact: true}"><a routerLink="/">Home</a></li>
        <li [routerLinkActive]="['active']"><a routerLink="/about">About</a></li>
        <li [routerLinkActive]="['active']"><a routerLink="/portfolio">Portfolio</a></li>
        <li [routerLinkActive]="['active']"><a routerLink="/contacts">Contacts</a></li>
      </ul>
    </div>

  </div>
</nav>
like image 121
donmutti Avatar answered Nov 17 '22 23:11

donmutti


You could add a custom directive that does it for you

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

@Directive({
    selector: "[menuClose]"
})
export class CloseMenuDirective {
    @Input()
    public menu: any;

    constructor(private element: ElementRef) { }

    @HostListener("click")
    private onClick() {
        this.menu.classList.remove("show");
    }
}

Don't forget to add this to your app.module in the declarations array

import { CloseMenuDirective } from './directives/close-menu.directive';
@NgModule({
    declarations: [
        ...declarations,
        CloseMenuDirective
    ]
})
export class AppModule { }

And then in your HTML you create a reference to your menu and pass that to your link element.

<div class="page-layout">
    <!-- Mark the menu with #menu, thus creating a reference to it -->
    <aside class="collapse navbar-toggleable page-menu" id="navbar-header" #menu>
        <ul class="nav">
            <li class="nav-item">
                <a class="nav-link"
                   [routerLink]="['./somewhere']"
                   routerLinkActive="active"
                   menuClose      <!-- Our custom directive above -->
                   [menu]="menu"> <!-- Bind to menu -->
                    <span>My Link</span>
                </a>
            </li>
        </ul>
    </aside>
</div>
like image 5
Patrick Avatar answered Nov 18 '22 00:11

Patrick


This code simulates a click on the burguer button to close the navbar by clicking on a link in the menu, keeping the fade out effect. Solution with typescript for angular 7. Avoid routerLink problems.

ToggleNavBar () {
    let element: HTMLElement = document.getElementsByClassName( 'navbar-toggler' )[ 0 ] as HTMLElement;
    if ( element.getAttribute( 'aria-expanded' ) == 'true' ) {
        element.click();
    }
}

<li class="nav-item" [routerLinkActive]="['active']">
    <a class="nav-link" [routerLink]="['link1']" title="link1" (click)="ToggleNavBar()">link1</a>
</li>
like image 5
edu Avatar answered Nov 17 '22 22:11

edu


This is a limitation of navbar (https://github.com/valor-software/ngx-bootstrap/issues/540). So you need to manipulate the DOM element.

<div class="navbar-header page-scroll">
    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
    </button>
    <a class="navbar-brand" routerLink="/">
        <img src="assets/images/logo.png">
    </a>
</div>
<div class="collapse navbar-collapse navbar-ex1-collapse">
    <ul class="nav navbar-nav navbar-right" >
        <li class="hidden">
            <a></a>
        </li>
        <li><a routerLink="/" (click)="onMenuClick()">Home</a></li>
        <li><a routerLink="/about" (click)="onMenuClick()">About</a></li> 
    </ul>
</div>

And on .ts file your minimal code shoul be:

import { Component, ElementRef, Renderer } from '@angular/core';

export class HeaderComponent {
    constructor(private el: ElementRef, private renderer: Renderer) {
    }
    onMenuClick() {
        //this.el.nativeElement.querySelector('.navbar-ex1-collapse')  get the DOM
        //this.renderer.setElementClass('DOM-Element', 'css-class-you-want-to-add', false) if 3rd value is true 
        //it will add the css class. 'in' class is responsible for showing the menu.
        this.renderer.setElementClass(this.el.nativeElement.querySelector('.navbar-ex1-collapse'), 'in', false);        
    }
}
like image 2
Towhid Avatar answered Nov 18 '22 00:11

Towhid