I think, that behaviour should be the following:
+1
+1
The requested behavior (ability to close an md-is-locked-open md-sidenav) seems conform with the material design spec.
The current implementation only allows using the md-sidenav widget as _permanent navigation drawer_ or _temporary navigation drawer_, but the specs explicitly mention _persisent navigation drawers_.
http://www.google.com/design/spec/patterns/navigation-drawer.html#navigation-drawer-behavior
Persistent navigation drawers can toggle open or closed. The drawer sits on the same surface elevation as the content. It is closed by default and opens by selecting the menu icon, and stays open until closed by the user. The state of the drawer is remembered from action to action and session to session.
Sitting outside of the page grid, when opened the drawer forces other content to change size and adapt to the smaller viewport.
Persistent navigation drawers are acceptable for all sizes larger than mobile.
Providing the possibility to toggle an md-is-locked-open``md-sidenav would allow using it as _persisent navigation drawer_.
+1
+1
Couldn't you just use the md-is-locked-open expression to accomplish this? You can string together multiple conditions in that expression to account for different states. It seems like a good option for maintaining persistent state between sessions as @freitag-solutions's quote from the design spec mentions, since you could initialize the state from persistent storage when the app starts up.
Here's a quick-and-dirty example that relies on parent scopes, but there are a number of ways you could do it:
http://codepen.io/mzbyszynski/pen/aOEQJX
Click the "Unlock Sidenav Left" button to unlock the sidenav.
Or am I misunderstanding what you are asking for?
@mzbyszynski yep, that's definitely a simple solution. Ashamed of not being able to come up to such obvious answer to the problem (( thanks. Closing.
While I see how @mzbyszynski's method somewhat fixes the problem (I'm already using a similar approach but totally forgot about this issue sorry!), I rather see it as hackfix than final solution. Nonetheless, thank you for the snippet and for taking a look at the problem @mzbyszynski!
The problem I see is that it still needs two different methods for toggling the sidenav depending on whether it is persistent or not. If it is persistent one needs to toggle md-is-locked-open, if it is non-persistent one needs to toggle md-is-open (in @mzbyszynski's codepen this corresponds to the methods 'unlock/lock sidebar' vs. 'toggle sidebar').
In my humble opinion it would be great to have a common way of interacting with the md-sidenav directive, regardless of it being used as persistent or non-persistent drawer.
My personal approach for a hybrid sidenav (persistent on large devices, non-persistent on small ones) as in @mzbyszynski's snippet is the following (see http://codepen.io/anon/pen/XbVyww for the actual implementation) :
md-is-open = $scope.isOpen
md-is-locked-open = $scope.IsOpen && $mdMedia('gt-md')
In my opinion, this is a very intuitive way of configuring such a hybrid sidenav and also somewhat works as expected. Unfortunately when toggling both properties to false (md-is-open, md-is-locked-open) a backdrop supporting the closing animation is shown, resulting in a somehow buggy experience and the need for another hack: e.g. hiding the backdrop via css when the sidenav is supposed to be persistent.
So, I still see the need for some fixing.
Probably it still would be great to have the toggle method work on locked sidenavs.
Maybe the method mentioned above should work without irritating backdrop.
In the end, I think the different modes of the sidenav (persisent/non-persistent) should at least have a common interface and should not need to be configured via independent properties (as it is currently the case where md-is-open controls non-persistent sidenavs and md-is-locked-open controls persistent ones but both cannot be used together).
What do you think?
@freitag-solutions What is your CSS 'hack' to remove the backdrop?
@mzbyszynski it seems that the codepen example does not work as nicely with the latest master branch. I get an md-backdrop flash on close, and no animation. I'd love to see something like $mdSidenav('left').toggleLocked();
If it helps , my use case is a data table that takes up as much of the real estate as possible. Then optionally, a filter sidebar can be opened to drill down (like Amazon's refine by).
@andrea-vega I think the issues you are seeing might be related to #4152. When I use angular material 0.10.1 with angular 1.3 the animations seem to work ok, but when I change to 1.4.4 then I don't see the animation anymore. I didn't notice the backdrop flashing but it might be.
Angular 1.3.15 + Angular Material 0.10.0:
http://codepen.io/mzbyszynski/pen/aOEQJX
Angular 1.3.15 + Angular Material 0.10.1:
http://codepen.io/mzbyszynski/pen/EjqXJW
Angular 1.4.4 + Angular material 0.10.1:
http://codepen.io/mzbyszynski/pen/ZGgyNO
@pdore-netfore Here's the css I used to remove the backdrop (except on mobile):
@media (min-width: 600px) {
md-backdrop.md-sidenav-backdrop {
display: none;
}
}
@mzbyszynski — I read somewhere around here that it is fixed with 1.4.5.
and also, that $mdSidenav is about to be refactored soon,
because right now it's just a fancy proof of concept.
@sm+1
The proposed solution is a hack and is inconsistent with $mdSidenav service.
I achieved this the following way:
<md-sidenav ng-show="ctrl.showSidebar" layout-column md-component-id="left" md-is-locked-open="$mdMedia('gt-sm')">
<md-content layout-fill role="navigation">
</md-content>
</md-sidenav>
And then in JS:
self.showSidebar = true;
self.toggleSideBar = function(){
self.showSidebar = !self.showSidebar;
};
@MikaelLandau But what about the sliding animation?
@PsyGik - I think all happens through CSS classes dynamically injected/removed according to the SIdebar's state. But I could be wrong.
Edit: Nevermind my comment, it is actually working..
In order to remove the flash of the backdrop. I used a variable for each attribute.
<md-sidenav md-component-id="left-sidenav" md-is-open="viewModel.leftSidenavOpen" md-is-locked-open="$mdMedia('gt-md') && viewModel.leftSidenavLockedOpen" >
<md-content layout-fill role="navigation">
</md-content>
</md-sidenav>
self.toggleLeftSidenav = function(){
if (self.$mdMedia('gt-md')) {
self.leftSidenavLockedOpen = !self.leftSidenavLockedOpen;
} else {
self.leftSidenavOpen = !self.leftSidenavOpen;
}
};
This also allows you to control if the sidenav is open once the screen size is changed. I personally expect the sidenav to disappear and not to become an overlay if the screen size hits the lower size.
self.toggleLeftSidenav = function(){
if (self.$mdMedia('gt-md')) {
self.leftSidenavOpen = false;
self.leftSidenavLockedOpen = !self.leftSidenavLockedOpen;
} else {
self.leftSidenavOpen = !self.leftSidenavOpen;
}
};
Tested with v1.0.5.
thx @roy46
work well...
I just had to initialize the self.leftSidenavLockedOpen on controller initialization, in addition to your code
self.leftSidenavLockedOpen = $mdMedia('gt-md');
Most helpful comment
In order to remove the flash of the backdrop. I used a variable for each attribute.
This also allows you to control if the sidenav is open once the screen size is changed. I personally expect the sidenav to disappear and not to become an overlay if the screen size hits the lower size.
Tested with v1.0.5.