Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change class on mouseover in directive

I am having trouble working out how to get a class to change on a nested directive.

This is the outer ng-repeat

<div data-courseoverview data-ng-repeat="course in courses | orderBy:sortOrder | filter:search"          data-ng-controller ="CourseItemController"          data-ng-class="{ selected: isSelected }"> 

Below is the inner ng-repeat which is using another directive

<li data-ng-repeat="item in social" class="social-{{item.name}}" ng-mouseover="hoverItem(true);"     ng-mouseout="hoverItem(false);"     index="{{$index}}"><i class="{{item.icon}}"     box="course-{{$index}}"></i></li> 

Here is the directive im calling for the hover event

ecourseApp.directive("courseoverview", function() {    return {         restrict : 'A',         replace: true,      /*scope: {         index: '@'     },*/             transclude: true,           templateUrl: "views/course-overview.html",     link: function link(scope, element, attrs) {         scope.switched = false;         //hover handler         scope.hoverItem = function(hovered){             if (hovered) {                 element.addClass('hover');                 $('#course-0 figure').addClass('tint')             }             else                 element.removeClass('hover');         };     }   }}); 

This needs $('#course-0 figure').addClass('tint') to change the calling item.

like image 273
Rob Paddock Avatar asked Jun 04 '13 16:06

Rob Paddock


2 Answers

In general I fully agree with Jason's use of css selector, but in some cases you may not want to change the css, e.g. when using a 3rd party css-template, and rather prefer to add/remove a class on the element.

The following sample shows a simple way of adding/removing a class on ng-mouseenter/mouseleave:

<div ng-app>   <div      class="italic"      ng-class="{red: hover}"     ng-init="hover = false"     ng-mouseenter="hover = true"     ng-mouseleave="hover = false">       Test 1 2 3.   </div> </div> 

with some styling:

.red {   background-color: red; }  .italic {   font-style: italic;   color: black; } 

See running example here: jsfiddle sample

Styling on hovering is a view concern. Although the solution above sets a "hover" property in the current scope, the controller does not need to be concerned about this.

like image 67
Bjørn Egil Avatar answered Oct 13 '22 11:10

Bjørn Egil


I have run into problems in the past with IE and the css:hover selector so the approach that I have taken, is to use a custom directive.

.directive('hoverClass', function () {     return {         restrict: 'A',         scope: {             hoverClass: '@'         },         link: function (scope, element) {             element.on('mouseenter', function() {                 element.addClass(scope.hoverClass);             });             element.on('mouseleave', function() {                 element.removeClass(scope.hoverClass);             });         }     }; }) 

then on the element itself you can add the directive with the class names that you want enabled when the mouse is over the the element for example:

<li data-ng-repeat="item in social" hover-class="hover tint" class="social-{{item.name}}" ng-mouseover="hoverItem(true);" ng-mouseout="hoverItem(false);"                 index="{{$index}}"><i class="{{item.icon}}"                 box="course-{{$index}}"></i></li> 

This should add the class hover and tint when the mouse is over the element and doesn't run the risk of a scope variable name collision. I haven't tested but the mouseenter and mouseleave events should still bubble up to the containing element so in the given scenario the following should still work

<div hover-class="hover" data-courseoverview data-ng-repeat="course in courses | orderBy:sortOrder | filter:search"  data-ng-controller ="CourseItemController"  data-ng-class="{ selected: isSelected }"> 

providing of course that the li's are infact children of the parent div

like image 38
Warrenn enslin Avatar answered Oct 13 '22 13:10

Warrenn enslin