0

I have a menu that looks like this:

enter image description here

As you can see from the address bar, I'm at the /clients route. I need my menu to have the "Clients" item highlighted. I'm really struggling to do this. There must be a straigtforward way of handling menu state in AngularJS???

I'm using angular-ui-router for routing and I'm happy that it's working as expected.

Here's my code:

<div ng-controller="MainCtrl as ctrl">

  <div layout="row">
    <div flex><img src="img/logo4.png" class="logo" /></div>
  </div>



  <md-toolbar hide-gt-sm layout="row" layout-align="end center">
    <md-menu-bar>
      <md-menu>
        <md-button aria-label="Menu" class="md-icon-button" ng-click="$mdOpenMenu($event)">
          <i class="material-icons">menu</i>
        </md-button>

        <md-menu-content width="4" ng-model="selected">
          <div data-ng-repeat="t in ctrl.menu">
            <md-menu-item ng-hide="{{ctrl.isDefined(t.subMenus)}}">
              <md-button style="font-size:14px">{{t.name}}</md-button>
            </md-menu-item>

            <md-menu-item ng-hide="{{!ctrl.isDefined(t.subMenus)}}">
              <md-menu>
                <md-button ng-click="$mdOpenMenu()">{{t.name}}</md-button>
                <md-menu-content width="3">
                  <md-menu-item ng-repeat="u in t.subMenus">
                    <md-button style="font-size:14px">{{u.name}}</md-button>
                  </md-menu-item>
                </md-menu-content>
              </md-menu>
            </md-menu-item>
          </div>
        </md-menu-content>
      </md-menu>
    </md-menu-bar>
  </md-toolbar>
</div>

And here's the MainCtrl Javascript:

(function () {
  'use strict';
  angular
  .module('eamorr')
  .controller('MainCtrl', MainCtrl);

  function MainCtrl($scope, $meteor, $mdDialog) {
    var vm=this;

    console.log("MainCtrl");


    vm.menu = [{
      "id": "home",
      "name": "Home",
      "href": "home"
    }, {
      "id": "about",
      "name": "About",
      "href": "about"
    }, {
      "id": "areas",
      "name": "Specialty Areas",
      "href": "areas",
      "subMenus":[{
        "id:":"areaRetail",
        "name":"Retail Pharmacy",
        "href":"areas?area=retail"
      },{
        "id:":"areaHospital",
        "name":"Hospital Pharmacy",
        "href":"areas?area=hospital"
      },{
        "id:":"areaIndustrial",
        "name":"Industrial Pharmacy",
        "href":"areas?area=industrial"
      }]
    }, {
      "id": "clients",
      "name": "Clients",
      "href": "clients"
    }, {
      "id": "blog",
      "name": "Blog",
      "href": "blog"
    }, {
      "id": "latest",
      "name": "Latest",
      "href": "latest"
    }];
  }


  vm.isDefined = function (thing) {
    if(typeof thing === "undefined"){
      return false;
    }
    return true;
  }
})();

Can anyone make any suggestions as to how to handle the state in a clean, maintainable way?

2
  • How about creating a directive which will check the location and add class to appropriate menu? Commented Nov 20, 2015 at 9:29
  • @AnandG I'm afraid I don't know what class I should use to highlight the md-button. Commented Nov 20, 2015 at 10:11

2 Answers 2

1

UI-Router provides an easy way to add classes if the state matches the current state. All we have to do is use ui-sref-active You can write something like this

<li ng-repeat="item in ctr.items" >
     <a ui-sref="{{item.href}}" ui-sref-active="active">{{item.name}}  </a>     
 </li>

Highlight current selected Menu-plunker

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for this work. The plunker is excellent. I'm just going through it now. The other problem is finding out what the class for an active <md-button> is called... I can't find it anywhere.
I think you can use md-primary to apply on button .
I ended up creating my own user-defined CSS class: .active{ background-color: rgba(158,158,158,0.2); } The ui-sref-active thing is brilliant!!! Thank you so much for telling me about it. I would have totally missed it otherwise...
I will try this with material .I will let you know if I succeed :)
1

In your controller add the following line

$scope.state = $state;

Note: Inject $state in your dependencies.

$state.current.name will get you the current state name with which you can change/add the classes to the target element with the help of ng-class

ng-class="{'class_name_to_highlight': state.current.name == 'client'}"

where class_name_to_highlight is the CSS class to highlight.

4 Comments

Hello this is very useful. Unfortunately, I don't know what the class_name_to_highlight is... I've searched the angular material website and can't find the correct class name (material.angularjs.org/latest/demo/button)
It's a user defined CSS class name, please change it with the one you have in your css file for highlighting the text/element.
OK. I'll give it a go and report back. I'd like to use the material design standard class names, rather than my own CSS.
I ended up creating my own CSS class... .active{ background-color: rgba(158,158,158,0.2); }

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.