Oliver Watkins
Oliver Watkins

Reputation: 13519

How to make a simple menu navigation in angularjs

I'm not really satisfied with what I can find. I just want a simple example of a menu system in Angularjs with hover effect and selection effect.

I understand that 'hover' effects can be done in CSS, but this is more of an exercise for me to understand angularjs better.

What I am trying to do is pretty basic stuff.

Basically I have some HTML which has some DIVs (or menu items) :

<div NavCtrl id="header">
    <div class="item" ng-click="click(1)" ng-mouseenter="hoverIn()" ng-mouseleave="hoverOut()">
1
    </div>
    <div class="item" ng-click="click(2)" ng-mouseenter="hoverIn()" ng-mouseleave="hoverOut()">
2
    </div>
    <div class="item" ng-click="click(3)" ng-mouseenter="hoverIn()" ng-mouseleave="hoverOut()">
3
    </div>
</div>

I want to do two things.

I understand..

  1. It is probably nicer to do the hover effect in CSS
  2. It is possible to do some inline logic in the HTML with angularjs

...because I want to have flow on effects from these events. A hover event needs to pull information out related to that menu item, and a click event should also be able to perform some action related to that menu item. Cheap CSS tricks are not going to solve this!

For my hover logic, I thought this would do the trick :

  $scope.hoverIn = function($event){
    angular.element($event.srcElement).addClass('hover')
  };

  $scope.hoverOut = function($event){
    angular.element($event.srcElement).removeClass('hover')
  };

However $event is undefined :( . How do I get to the element object from a mouseover event?

My click logic looks like this :

  $scope.click = function(position, $event) {

    elem = angular.element($event.srcElement);

    if (elem.hasClass("clicked")) {
      elem.removeClass("clicked")
    }else {
      elem.addClass("clicked")
    }

    // if (position == 1) //do something etc...
  };

Same problem : $event is undefined. I also want to pass in the index, so that I can do something special for certain menu items.

My Fiddle is here :

https://jsfiddle.net/zxjg3tpo/5/

Upvotes: 1

Views: 1057

Answers (3)

Petr Averyanov
Petr Averyanov

Reputation: 9486

ng-mouseenter="hoverIn($event)"

How it works: ng-mouseenter is kinda clever and it has $event in its scope in addition to what you have (i.e. you have hoverIn). So when it parse provided expression, it launches hoverIn with event.

All work with elements, like addClass should be done in directives where you have direct access to html element. Sometimes you may need angular.element(...) but in most cases you are happy with current element. (In directive link : function(scope, element, attrs))

Upvotes: 2

Osei Fortune
Osei Fortune

Reputation: 831

In angularjs you can get the event by using $event in your html code

<div class="item" ng-click="click(1,$event)" ng-mouseenter="hoverIn($event)" ng-mouseleave="hoverOut($event)">

Hover Logic

 $scope.hoverIn = function($event){
    angular.element($event.target).addClass('hover')
  };

  $scope.hoverOut = function($event){
    angular.element($event.target).removeClass('hover')
  };

Click logic

$scope.click = function(position, $event) {

    elem = angular.element($event.target);

    if (elem.hasClass("clicked")) {
      elem.removeClass("clicked")
    }else {
      elem.addClass("clicked")
    }

    // if (position == 1) //do something etc...
  };

Updated Fiddle : https://jsfiddle.net/zxjg3tpo/6/

Here is another updated Fiddle where the siblings have their class removed (to make the click work correct) https://jsfiddle.net/zxjg3tpo/9/

Upvotes: 1

Pranab Mitra
Pranab Mitra

Reputation: 389

You missed to pass $event from html and the srcElement was wrong. Please try the following:

HTML

    <body ng-app="navTest" ng-controller="NavTestCtrl">
<div id="header">
    <div class="item" ng-click="click(1, $event)" ng-mouseenter="hoverIn($event)" ng-mouseleave="hoverOut($event)">
1
    </div>
    <div class="item" ng-click="click(2, $event)" ng-mouseenter="hoverIn($event)" ng-mouseleave="hoverOut($event)">
2
    </div>
    <div class="item" ng-click="click(3, $event)" ng-mouseenter="hoverIn($event)" ng-mouseleave="hoverOut($event)">
3
    </div>
</div>
</body>

JS Code:

var app = angular.module('navTest', [

]);

app.controller('NavTestCtrl', function ($scope, $location, $http) {

  $scope.click = function(position, $event) {

    elem = angular.element($event.target);

    if (elem.hasClass("clicked")) {
      elem.removeClass("clicked")
    }else {
      elem.addClass("clicked")
    }

    // if (position == 1) //do something etc...


  };


  $scope.hoverIn = function($event){
    angular.element($event.target).addClass('hover')
  };

  $scope.hoverOut = function($event){
    angular.element($event.target).removeClass('hover')
  };
});

Upvotes: 1

Related Questions