I'm interested in changing the md-sidenav
- from Angular Material 2 - mode from side (for desktops) to over (mobile). Is there a way to change it programmatically?
Thanks
To set up a sidenav we use three components: <mat-sidenav-container> which acts as a structural container for our content and sidenav, <mat-sidenav-content> which represents the main content, and <mat-sidenav> which represents the added side content.
From the docs: A mat-sidenav can be opened or closed using the open(), close() and toggle() methods. Each of these methods returns a Promise that will be resolved with true when the sidenav finishes opening or false when it finishes closing.
Building on Steve G's solution you could update app.component.html
<md-sidenav [mode]="isLargeScreen() ? 'side' : 'over'" [opened]="isLargeScreen()"></md-sidenav>
And then in app.component.ts
isLargeScreen() {
const width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
if (width > 720) {
return true;
} else {
return false;
}
}
This gives you a sidebar on desktop opened by default, and on mobile it overlays but is hidden by default!
I found the solution by ObservableMedia.
Component:
import {Component, OnInit, ViewEncapsulation} from "@angular/core";
import {ObservableMedia} from "@angular/flex-layout";
@Component({
moduleId: module.id,
selector: 'app-sidebar',
templateUrl: './sidebar.component.html',
styleUrls: ['./sidebar.component.scss'],
encapsulation: ViewEncapsulation.None,
})
export class SidebarComponent implements OnInit {
constructor(public media:ObservableMedia ) {
}
ngOnInit(): void {
}
}
template:
<md-sidenav-container>
<md-sidenav #sidenav mode="{{media.isActive('gt-sm') ? 'side' : 'over'}}" align="begin" class="md-whiteframe-4dp" opened >
<md-nav-list>
...
</md-nav-list>
</md-sidenav>
</md-sidenav-container>
Sure! You could do your screen width test (or browser detection, blech) in your component on initialization and store the result in a variable as a string.
Using width detection as an example, you might do something like this:
Partial app.component.ts
import { Component, ElementRef, ViewChild, OnInit } from '@angular/core';
export class AppComponent implements OnInit {
@ViewChild('wrapper')
private wrapperElement: ElementRef;
private menuMode; // Where we'll store the resulting menu mode
ngOnInit() {
// Do your simple test on the container, for example
if (this.wrapperElement.nativeElement.offsetWidth <= 720) {
this.menuMode = "over";
} else {
this.menuMode = "side";
}
}
}
And bind the variable to the sidenav in the template.
Partial app.component.html
<div #wrapper>
<md-sidenav-container>
<md-sidenav #sidenav [mode]="menuMode"></md-sidenav>
...
</div>
The bulk of that work is just determining how you want to perform the test.
You could also just test window instead of a wrapper, but I prefer testing a wrapper.
Notes:
@HostListener("window:resize",
["$event"])
, but that's outside of the scope of your original
question.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With