Marcogomesr
Marcogomesr

Reputation: 2672

Angular 4 material Sidenav doesn't close the menu after being selected

I'm using the angular Material Sidenav it works well but with the problem that after select an option the menu still opens. It's so weird that this is mean to use as a navigation for small devices and the doc doesn't have any example using links

App.component

<md-sidenav-container>
     <md-sidenav #sidenav class="sidenav" mode="over">
    <ul class="sidenav">
      <li class="sidenav__list">
        <a class="sidenav__list__link " [routerLink]="['about']" >about</a>
      </li>

    </ul>
  </md-sidenav>

  <header>
    <div fxHide fxShow.lt-sm>
      <button class="btn__sidenav" md-button (click)="sidenav.toggle()">
        <i class="material-icons md-36">menu</i>
      </button>
    </div>

    </ng-template>
  </header>


    <div class="container">
      <router-outlet></router-outlet>
    </div>
    <wh-footer></wh-footer>
</md-sidenav-container>

basically, I have to load content for the about page and close the menu when the link is clicked, I dont know if I have to do manually or are there any directive or property that I can use

Upvotes: 3

Views: 5776

Answers (3)

Mister Smith
Mister Smith

Reputation: 28158

This depends on how do you use the SideNAv. If you want to emulate Android's Navigation Drawer, then you want it to auto-close upon selection.

My solution for the latest Angular Material version available (v12.0.2) consists on modifying the template so that the click handler of each element toggles the sidenav:

<mat-sidenav #sidenav>
    <mat-nav-list>
        <a mat-list-item [routerLink]="'/section1'" (click)="sidenav.toggle()"> Section 1 title </a>
        <a mat-list-item [routerLink]="'/section2'" (click)="sidenav.toggle()"> Section 2 title </a>
        ...
        <a mat-list-item [routerLink]="'/sectionN'" (click)="sidenav.toggle()"> Section N title </a>
    </mat-nav-list>
</mat-sidenav>

Upvotes: 0

Nehal
Nehal

Reputation: 13297

Option 1:

You add (click)="sidenav.close()" inside <a>, which will close the sidenav when user selects 'About`.

<a class="sidenav__list__link " [routerLink]="['about']" (click)="sidenav.close()">
    about
</a>

demo

If you don't want to add a click event in every <a> or <li>, you can put the click event inside <ul>. Sidenav will close for any <li> clicked/selected within that <ul>.

<ul class="sidenav" (click)="sidenav.close()">
    <li class="sidenav__list">
        <a class="sidenav__list__link " [routerLink]="['about']" >about</a>
    </li>
</ul>

Update

Option 2:

Subscribe to router events and close the sidenav when a router event takes place.

constructor(private _router: Router) { }

@ViewChild(MdSidenav) sidenav: MdSidenav;

ngOnInit() {
    this._router.events.subscribe(() => {
        if (this.isScreenSmall()) {
            this.sidenav.close();
        }
    });
}

isScreenSmall(): boolean {
    return window.matchMedia(`(max-width: ${SMALL_WIDTH_BREAKPOINT}px)`).matches;
}

material.angular.io uses this option. Check the implementation of this code in GitHub repo.

Upvotes: 13

Ian Samz
Ian Samz

Reputation: 2109

For Angular 5, From Nehal's Answer on Option 2, just change :

@ViewChild(MdSidenav) sidenav: MdSidenav;

to

@ViewChild(MatSidenav) sidenav: MatSidenav;

Worked Like a Charm. Also the sweetspot for small devices (tablets and under is 840px)

Upvotes: 1

Related Questions