MojioMS MojioMS - 3 months ago 86
AngularJS Question

how to create a collapsable/expandable open-locked sidenav with angular material

I want to have a sidenav with angular material which has 2 states: collapsed (only icons of the items are shown) and expanded (labes + icons shown). The example behaviour is shown at the RDash Dashboard, which is unfortunetally done with bootstrap.

Since the default sidenav of angular material does not provide that feature, I wanted to do it myself.

I have 2 ideas on how to do it:

1) using 2 different side-navs: one for collapsed, one for expanded. Then switching open-locked between them or just hiding/showing always one at a time.

2) using only 1 sidenav. somehow programmatically change the width, and the items of the sidenav and keeping it open-locked.

My favourite approach would be 2, but I want to know if there are any better ways to achieve that kind of sidenav with angular material?

Answer

I think approach 2 is the best - CodePen

Markup

<div ng-controller="AppCtrl" layout="column" style="height:500px;" ng-cloak="" class="sidenavdemoBasicUsage" ng-app="MyApp">
  <section layout="row" flex="">
    <md-sidenav class="md-sidenav-left" md-component-id="left" md-whiteframe="4" id="leftSideNav">
      <md-toolbar class="md-theme-indigo" layout="row">
        <h1 class="md-toolbar-tools">Sidenav Left</h1>
        <span flex></span>
        <md-button ng-click="toggleExpand()">{{toggleExpandButtonLabel}}</md-button>
      </md-toolbar>
      <md-content layout-padding="">
        <md-button ng-click="close()" class="md-primary">
          Close Sidenav Left
        </md-button>
      </md-content>
    </md-sidenav>

    <md-content flex="" layout-padding="">
      <div layout="column" layout-align="top center">
        <div>
          <md-button ng-click="toggleLeft()" class="md-primary">
            Toggle left
          </md-button>
        </div>
      </div>
    </md-content>
  </section>
</div>

JS

angular
  .module('MyApp',['ngMaterial', 'ngMessages', 'material.svgAssetsCache'])
  .controller('AppCtrl', function ($scope, $timeout, $mdSidenav, $log, $element) {
    $scope.toggleLeft = buildToggler('left');
    $scope.toggleExpandButtonLabel = "Expand";
    var sideNav = angular.element($element[0].querySelector('#leftSideNav'));

    $scope.toggleExpand = function () {
      if ($scope.toggleExpandButtonLabel == "Expand") {
        sideNav.css("width", "500px")
      }
      else {
        sideNav.css("width", "320px")
      }
      $scope.toggleExpandButtonLabel = ($scope.toggleExpandButtonLabel == "Expand") ? "Collapse" : "Expand";
    }

    $scope.close = function () {
      $mdSidenav('left').close();
      $scope.toggleExpandButtonLabel = "Expand";
      sideNav.css("width", "320px")
    };

    function buildToggler(navID) {
      return function() {
        $mdSidenav(navID)
          .toggle()
          .then(function () {
            $log.debug("toggle " + navID + " is done");
          });
      }
    }
});
Comments