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); }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.