Responsive navbar

Hi guys,
This library is just an awesome box to start with angular while dependent on bootstrap css. I’m creating a navbar and just got through an issue here. Probably it’s a new-feature request or it can be said as a bootstrap-feature not yet in ng-bootstrap.

Feature description:

Look at this link where you can set collapsible navbar based on the size of the screen.
Bootstrap 4 documentation for navbar

This can be seen in responsive navbar section of this link. To the point, it actually uses navbar-toggleable-xs class to define this functionality. The navbar comes collapsible only when the screen size is xs, otherwise, its a regular navbar.

Version of Angular, ng-bootstrap, and Bootstrap:

Angular2: 2.0.1

ng-bootstrap: 1.0.0-alpha.6

Bootstrap: 4.0.0-alpha.4

11 thoughts on “Responsive navbar

  1. Hi @ravipunjwani

    We already have the NgbCollapse directive to do that. Replace the bootstrap example by the following snippet, and you’ll have the equivalent.

    Is there something more needed?

    <nav class="navbar navbar-light bg-faded">
      <button class="navbar-toggler hidden-sm-up" type="button" (click)="isNavbarCollapsed = !isNavbarCollapsed" aria-controls="exCollapsingNavbar2" aria-expanded="false" aria-label="Toggle navigation">
        &#9776;
      </button>
      <div [ngbCollapse]="isNavbarCollapsed" class="collapse navbar-toggleable-xs" id="exCollapsingNavbar2">
        <a class="navbar-brand" href="#">Responsive navbar</a>
        <ul class="nav navbar-nav">
          <li class="nav-item active">
            <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">Features</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">Pricing</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">About</a>
          </li>
        </ul>
      </div>
    </nav>
    
  2. i had the above example working, but then upgraded to bootstrap@4.0.0-alpha.6 (from bootstrap@4.0.0-alpha5) and it stopped working.

    i noticed that there is a navbar rewrite

    i changed my menu like this (and it works now) 😄

    <nav class="navbar navbar-toggleable-md navbar-light bg-faded">
      <button class="navbar-toggler navbar-toggler-right" type="button" (click)="isNavbarCollapsed = !isNavbarCollapsed"
              aria-controls="exCollapsingNavbar2" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <a class="navbar-brand" href="#">North America - Conventional</a>
      <div [ngbCollapse]="isNavbarCollapsed" class="collapse navbar-collapse" id="exCollapsingNavbar2">
        <div class="navbar-nav mr-auto">
          <a class="nav-item nav-link" routerLink="/transfers" routerLinkActive="active">Transfers</a>
          <a class="nav-item nav-link" routerLink="/jobs" routerLinkActive="active">Jobs</a>
          <a class="nav-item nav-link" routerLink="/jobs/7" routerLinkActive="active">Job 7</a>
        </div>
      </div>
    </nav>
  3. we need auto collapse for ngbCollapse when any link under it clicked:
    jquery e.g:

        $('.navbar-collapse ul li a').click(function() {
            /* always close responsive nav after click */
            $('.navbar-toggle:visible').click();
        });
  4. Even with @datumgeek ‘s fixes this still doesn’t work properly because it doesn’t know about reactive design and automatically set it correctly as those change.

    There needs to be an out of the box navbar that works EXACTLY like the bootstrap example that understands reactive design and works accordingly.

    That means:

    1. When it MD or Large the full menu is visible with no button.
    2. When xs or sm the menu is automatically hidden and the button shows up and they can tap on the menu to show it.
    3. If you drag your window size it should automatically react to the size change and when large enough the button should go away and the menu should automatically display and when small enough going back the other way the menu should hide and the button should show.

    What it doesn’t do right now is know the different sizing and change the value based on reactive design.

    I.e. you need a proper navbar control in here because this hack you have right now doesn’t actually address the issue and you’re requiring major code just to make work what works right out of the box with bootstrap 4 which defeats the purpose of this project.

  5. I was able to replicate bootstraps navbar example with the collapse directive except for animation. The collapse plugin doesn’t seem to do the slide in/out animation.

  6. @mcescalante you can always check our demo page code where we’ve got responsive navbar:

    <header class=”navbar navbar-light navbar-fixed-top navbar-expand-lg>
    <a class=”navbar-brand[routerLink]=”[‘/’](click)=”navbarCollapsed = true>ng-bootstrap</a>
    <button class=”navbar-toggler navbar-toggler-righttype=”button(click)=”navbarCollapsed = !navbarCollapsed
    [attr.aria-expanded]=”!navbarCollapsedaria-controls=”navbarContentaria-expanded=”falsearia-label=”Toggle navigation>
    <span class=”navbar-toggler-icon></span>
    </button>
    <div class=”navbar-collapse[ngbCollapse]=”navbarCollapsedid=”navbarContent>
    <ul class=”navbar-nav mr-auto>
    <li class=”nav-item[routerLinkActive]=”[‘active’]>
    <a class=”nav-link[routerLink]=”[‘/getting-started’](click)=”navbarCollapsed = true>Getting Started</a>
    </li>
    <li class=”nav-item[routerLinkActive]=”[‘active’]>
    <a class=”nav-link[routerLink]=”[‘/components’](click)=”navbarCollapsed = true>Components</a>
    </li>
    <li class=”nav-item d-lg-none*ngFor=”let component of components[routerLinkActive]=”[‘active’]>
    <a class=”nav-link[routerLink]=”[‘/components’, component.toLowerCase()](click)=”navbarCollapsed = true>{{ component }}</a>
    </li>
    </ul>
    <span class=”github-buttons d-none d-lg-inline>
    <a class=”github-button
    href=”https://github.com/ng-bootstrap/ng-bootstrap
    target=”_blank
    data-style=”mega
    data-count-href=”/ng-bootstrap/ng-bootstrap/stargazers
    data-count-api=”/repos/ng-bootstrap/ng-bootstrap#stargazers_count
    data-count-aria-label=”# stargazers on GitHub
    aria-label=”Star ng-bootstrap/ng-bootstrap on GitHub>Star</a>
    <a href=”https://twitter.com/intent/tweet?button_hashtag=ngbootstrap
    class=”twitter-hashtag-button
    data-size=”large
    data-text=”I&#39;m checking out ng-bootstrap, THE Angular UI framework for Bootstrap CSS
    data-url=”https://ng-bootstrap.github.io
    data-show-count=”true>Tweet #ngbootstrap</a>
    </span>
    </div>
    </header>
  7. I wanted to try Bootstrap 4 in hopes of getting access to some of their new goodies, but seeing how it’s so difficult to get something as simple as a navbar to work is quite disheartening. The code on the documentation for Bootstrap 4 simply doesn’t work with the latest version of Angular. The code from @pkozlowski-opensource works, but it seems like a lot of hoops and hurdles just to get one of the most basic components to work. (The hurdle being having to look up issues in ng-bootstrap when it should just work)

  8. @dougamos @collindutter You can add the angular/animations to have that slide-in/out effect.

    <nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
    	<div class="container">
    		<a href="#" class="navbar-brand">ngbs-1</a>
         <button class="navbar-toggler" (click)="toggleNavbar()"  type="button" aria-controls="theNavbar" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
    		<div [ngbCollapse]="isNavbarCollapsed" id="theNavbar"
         [@collapse]="isNavbarCollapsedAnim"
         class="navbar-collapse collapse navbar-toggleable">
    			<ul class="navbar-nav mr-auto ml-auto"> 
    				<li class="nav-item">
    					<a class="nav-link" href="#"> Home</a>
    				</li>
    				<li class="nav-item">
    					<a class="nav-link" href="#"> About</a>
    				</li>
    				<li class="nav-item">
    					<a class="nav-link" href="#"> Contact</a>
    				</li>
    			</ul>
    		</div>
    	</div>
    </nav>
    

    And in your component

    import {  trigger,state,style, animate, transition } from '@angular/animations'; 
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.scss'],
       animations: [
      trigger('collapse', [
        state('open', style({
          opacity: '1'
        })),
        state('closed',   style({
          opacity: '0',
          display: 'none',   
        })),
        transition('closed => open', animate('400ms ease-in')),
        transition('open => closed', animate('100ms ease-out'))
      ])
    ]
    })
    export class AppComponent {
      isNavbarCollapsed = true;
      _isNavbarCollapsedAnim = 'closed';
      ngOnInit() {
        this.onResize(window);
      }
      @HostListener('window:resize', ['$event.target']) 
    onResize(event) { 
      if(event.innerWidth > 990){
        //need to set this to 'open' for large screens to show up because of opacity in 'closed' animation.
        this._isNavbarCollapsedAnim = 'open';
          this.isNavbarCollapsed = true;
      }else{
        // comment this line if you don't want to collapse the navbar when window is resized.
       // this._isNavbarCollapsedAnim = 'closed';
      }
    }
      toggleNavbar(): void {
        if(this.isNavbarCollapsed){
            this._isNavbarCollapsedAnim = 'open';
          this.isNavbarCollapsed = false;
        } else {
        this._isNavbarCollapsedAnim = 'closed';
          this.isNavbarCollapsed = true;
        }
      }
      get isNavbarCollapsedAnim() : string {
        return this._isNavbarCollapsedAnim;
      }
    }
    

    Here’s a stackblitz demo https://stackblitz.com/edit/ng-bri-bs1-armbhz?file=app%%2Fapp.component.html

  9. Lol this is actually bs that the accepted answer was “here’s this directive which doesn’t do 90%% of what the bootstrap component does, but deal with it.” Paste the code from the first response into your ide and compare it with the BS4 component. Just terrible. I also like how the last response is 50+ lines of code to do what the BS4 component does in one. Defeating the purpose of using bootstrap, or angular for that matter. Why not just use es5 and some html and css, technically you COULD achieve everything bootstrap offers. Sad!