Changing Element Colour on Hover AngularJS

All we need is an easy explanation of the problem, so here it is.

So, I’m just getting started with angularjs and I’m already confused. I want to change the colour of a list element that corresponds to a hex code colour that is in an array. I’ve tried some stuff but I just can’t get it.

Here’s my code so far:
HTML

<div id="mainContentWrap" ng-app="newApp">
 <div id="personContainer" ng-controller="personController">
<ul id="personList">
    <li class="bigBox no_s" ng-style="personColour"  ng-repeat="i in persons" ng-hover="changeColor()">< href="#/{{i.person_id}}" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">{{i.person_name}}</a></li>
</ul>

Javascript:

var app=angular.module('newApp',[]);
app.controller('personController',function($scope,$rootScope){
    $rootScope.persons=[
        {person_id:'0',person_name:'Jim',colour:"cc0000"},
        {person_id:'4',person_name:'Bob',colour:"f57900"},
        {person_id:'2',person_name:'James',colour:"4e9a06"},
        {person_id:'9',person_name:'Paul',colour:"3465a4"},
        {person_id:'3',person_name:'Simon',colour:"77507b"}
    ];
    $scope.changeColor(){
        $scope.personColour=$scope.persons.color// not sure what to do here???
    }
});

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

There is no ng-hover directive. You’ll want to use ng-mouseenter and ng-mouseleave.

Also, keep in mind that the syntax for ng-style is an object corresponding the CSS key-value pairs.

<li ng-repeat="i in persons" ng-style="personColour" ng-mouseenter="changeColor(i)"></li>

$scope.changeColor = function(person) {
    $scope.personColour = {color: '#'+person.colour};
};

If you’d like for the color to change back to what it was before you hovered, you can create two functions, or pass a parameter to $scope.changeColour:

<li ng-repeat="i in persons" ng-style="personColour" ng-mouseenter="changeColor(i,true)" ng-mouseleave="changeColor(i,false)"></li>

$scope.changeColor = function(person, bool) {
    if(bool === true) {
        $scope.personColour = {color: '#'+person.colour};
    } else if (bool === false) {
        $scope.personColour = {color: 'white'}; //or, whatever the original color is
    }
};

To take it a step further

You could create a directive for each person.

<person ng-repeat="i in persons"></person>

// your module, then...
.directive('person', [function() {
    return {
        restrict: 'E',
        replace: true,
        template: '<li class="bigBox no_s"><a href="#/{{i.person_id}}" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">{{i.person_name}}</a></li>',
        link: function(scope, elm, attrs) {
            elm
                .on('mouseenter',function() {
                    elm.css('color','#'+i.colour);
                })
                .on('mouseleave',function() {
                    elm.css('color','white');
                });
        }
    };
}]);

Method 2

If you want to hack stay in the view:

<div ng-repeat="n in [1, 2, 3]" ng-style="{ 'background': (isHover ? '#ccc' : 'transparent') }" ng-mouseenter="isHover = true;" ng-mouseleave="isHover = false;">
 <span>{{ n }}</span>
</div>

Method 3

in the code bellow i add easy code to understand how to active style with condition. I hope that help you

<li ng-style="( (isOver == 'true') && (linkToActive == 'm1')  ) ? { 'background-color': '#00bdcb' } : {'background-color': '#ededed'}"
ng-mouseenter="vm.changeColorMenu('m1','true')" ng-mouseleave="vm.changeColorMenu('m1','false')">
</li>

<li ng-style="( (isOver == 'true') && (linkToActive == 'm2')  ) ? { 'background-color': '#00bdcb' } : {'background-color': '#ededed'}"
ng-mouseenter="vm.changeColorMenu('m2','true')" ng-mouseleave="vm.changeColorMenu('m2','false')">
</li>

</ul>

Javascript Code

function changeColorMenu(indexMenu,bool)
    {
        $scope.isOver = bool;
        $scope.linkToActive = indexMenu;
    }

Method 4

If you check an example here you will see that ng-style directive waits for css style, not just value, so in your case it’ll be:

$scope.person.colourStyle={'background-color':$scope.persons.color}

and in html it’ll be:

<li class="bigBox no_s" ng-style="i.colourStyle"  ng-repeat="i in persons" ng-hover="changeColor()">< href="#/{{i.person_id}}" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">{{i.person_name}}</a></li>

edit:

And You also need to set colour value to full hex for example: ‘#cc0000’.

Method 5

In Angular, there is not ng-hover directive, so you should use ng-mouseenter & ng-mouseleave to simulate it.

<ul id="personList">
    <li class="bigBox no_s" ng-style="personColour" 
        ng-repeat="i in persons" ng-mouseenter="changeColor($index)" 
        ng-mouseleave="recoverColor($index)">
            <a href="#/{{i.person_id}}" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener">{{i.person_name}}</a>
    </li>
</ul>

And you should use $index to get your element in persons Array

$scope.changeColor = function() {
    $scope.personColour = { 'color': '#' + $scope.persons[$index].color };
                           // or 'background-color' whatever you what
}

$scope.recoverColor = function() {
    $scope.personColour = {};
}

Method 6

See Plunker Demo Here

Use ng-style to conditionally apply CSS styles – I’ve chosen to name this style 'personStyle'. Next, bind the ng-mouseover event to set the personStyle background-color to the person’s colour attribute. Finally, bind the ng-mouseleave event to reset the personStyle when the mouse leaves the element. The changeColor() function is not needed for this solution to work.

<div id="personContainer" ng-controller="personController">
  <ul id="personList"> 
    <li class="bigBox no_s" ng-repeat="i in persons" ng-style="personStyle">
      <a href="#/{{i.person_id}}" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" ng-mouseleave="personStyle={}" 
             ng-mouseover="personStyle={ 'background-color':'#' + i.colour}">
             {{i.person_name}}</a>
    </li>
   </ul>
</div>

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply