1

I have set up my ng-class like this:

<ul class="picker-dropdown list-inline form-control">
    <li ng-repeat="colour in controller.colours.data" ng-class="{'active': controller.team.data.colours.indexOf(colour) > -1}">
        <a href style="background-color: #{{ colour.hex }};" ng-click="controller.setColour(colour)"></a>
    </li>
</ul>

and my team looks like this:

{
    loading: false,
    data: {
        id: 0,
        name: 'Test',
        sport: '',
        colours: [{
            id: 31,
            name: 'Hot Pink (Pms Magenta)',
            hex: 'd40082'
        },{
            id: 32,
            name: 'Baby Pink (196u)',
            hex: 'ffc2cc'
        },{
            id: 33,
            name: 'Cream',
            hex: 'ffffe5'
        }]
    }
};

Now, I expect that the active class will be added to the three colours in my repeat. controller.colours.data looks like this:

[
    {
        "hex": "000000",
        "id": 1,
        "name": "Black"
    },
    {
        "hex": "ffffff",
        "id": 2,
        "name": "White"
    },
    {
        "hex": "001444",
        "id": 3,
        "name": "School Navy Blue"
    },
    {
        "hex": "000e31",
        "id": 4,
        "name": "Sport Navy Blue Pms 532"
    },
    {
        "hex": "003072",
        "id": 5,
        "name": "Royal Blue (Pms286)"
    },
    {
        "hex": "83cce4",
        "id": 6,
        "name": "Pale Blue (Pms292)"
    },
    {
        "hex": "051667",
        "id": 7,
        "name": "Reflex Blue (Pms Ref Blu)"
    },
    {
        "hex": "0080bc",
        "id": 8,
        "name": "Cyan Blue (Process Cyan)"
    },
    {
        "hex": "004066",
        "id": 9,
        "name": "Petrol Blue (Pms3035)"
    },
    {
        "hex": "ff0000",
        "id": 10,
        "name": "Red (Pms200)"
    },
    {
        "hex": "a50021",
        "id": 11,
        "name": "Cranberry (Pms209)"
    },
    {
        "hex": "990033",
        "id": 12,
        "name": "Maroon (Pms202)"
    },
    {
        "hex": "990000",
        "id": 13,
        "name": "Burgundy (Pms195)"
    },
    {
        "hex": "003300",
        "id": 14,
        "name": "School Bottle Green"
    },
    {
        "hex": "1d4012",
        "id": 15,
        "name": "Sport Bottle Green (Pms350)"
    },
    {
        "hex": "12872b",
        "id": 16,
        "name": "Emerald Green (Pms347u)"
    },
    {
        "hex": "336648",
        "id": 17,
        "name": "Sage Green (Pms5545)"
    },
    {
        "hex": "089770",
        "id": 18,
        "name": "Leaf Green (Pms569)"
    },
    {
        "hex": "e26b0a",
        "id": 19,
        "name": "Orange (Pms021)"
    },
    {
        "hex": "ffc000",
        "id": 20,
        "name": "Gold (Pms1375)"
    },
    {
        "hex": "ffff00",
        "id": 21,
        "name": "Sunshine (Pms1225c)"
    },
    {
        "hex": "ffff66",
        "id": 22,
        "name": "Sunburst Pms115c)"
    },
    {
        "hex": "a6a6a6",
        "id": 23,
        "name": "Grey (Pms Cool Grey 6c)"
    },
    {
        "hex": "404040",
        "id": 24,
        "name": "Charcoal Pms432)"
    },
    {
        "hex": "7030a0",
        "id": 25,
        "name": "Purple (Pms2613)"
    },
    {
        "hex": "d40082",
        "id": 26,
        "name": "Hot Pink (Pms Magenta)"
    },
    {
        "hex": "ffc2cc",
        "id": 27,
        "name": "Baby Pink (196u)"
    },
    {
        "hex": "ffffe5",
        "id": 28,
        "name": "Cream"
    },
    {
        "hex": "704626",
        "id": 29,
        "name": "Brown (Pms731)"
    },
    {
        "hex": "351f16",
        "id": 30,
        "name": "Chocolate (Pms476)"
    },
    {
        "hex": "d40082",
        "id": 31,
        "name": "Hot Pink (Pms Magenta)"
    },
    {
        "hex": "ffc2cc",
        "id": 32,
        "name": "Baby Pink (196u)"
    },
    {
        "hex": "ffffe5",
        "id": 33,
        "name": "Cream"
    },
    {
        "hex": "ff0000",
        "id": 34,
        "name": "Red (Pms200)"
    },
    {
        "hex": "a50021",
        "id": 35,
        "name": "Cranberry (Pms209)"
    },
    {
        "hex": "990033",
        "id": 36,
        "name": "Maroon (Pms202)"
    }
]

Does anyone know why this isn't working?

r3plica
  • 13,017
  • 23
  • 128
  • 290

1 Answers1

1

You have a few issues in your code.

This:

ng-repeat="colour in controller.colours.data"

produces the colour variable on each iteration, and it looks like:

{
    "hex": "000000",
    "id": 1,
    "name": "Black"
}

So, it's an object.

Because of that, you can't do:

controller.team.data.colours.indexOf(colour)

because in JS, two objects with identical properties are not considered the same objects. That works only with primitives.

I understand you want to match each object's id, and probably the easiest way to do it is to have a temporary array containing only the ids of the colours, like this:

team.data.tmp = [31, 32, 33];

and then simply do:

controller.team.data.tmp.indexOf(colour.id) !== -1

Working example

See it in action here, note that the active ones have triple the width of the standard ones:

angular.module('app', [])
  .controller('Ctrl', function($scope) {
    $scope.controller = {};
    $scope.controller.team = {
      loading: false,
      data: {
        id: 0,
        name: 'Test',
        sport: '',
        colours: [{
          id: 31,
          name: 'Hot Pink (Pms Magenta)',
          hex: 'd40082'
        }, {
          id: 32,
          name: 'Baby Pink (196u)',
          hex: 'ffc2cc'
        }, {
          id: 33,
          name: 'Cream',
          hex: 'ffffe5'
        }],
        tmp: [31, 32, 33]
      }
    };
    $scope.controller.colours = {};
    $scope.controller.colours.data = [{
      "hex": "000000",
      "id": 1,
      "name": "Black"
    }, {
      "hex": "ffffff",
      "id": 2,
      "name": "White"
    }, {
      "hex": "001444",
      "id": 3,
      "name": "School Navy Blue"
    }, {
      "hex": "000e31",
      "id": 4,
      "name": "Sport Navy Blue Pms 532"
    }, {
      "hex": "003072",
      "id": 5,
      "name": "Royal Blue (Pms286)"
    }, {
      "hex": "83cce4",
      "id": 6,
      "name": "Pale Blue (Pms292)"
    }, {
      "hex": "051667",
      "id": 7,
      "name": "Reflex Blue (Pms Ref Blu)"
    }, {
      "hex": "0080bc",
      "id": 8,
      "name": "Cyan Blue (Process Cyan)"
    }, {
      "hex": "004066",
      "id": 9,
      "name": "Petrol Blue (Pms3035)"
    }, {
      "hex": "ff0000",
      "id": 10,
      "name": "Red (Pms200)"
    }, {
      "hex": "a50021",
      "id": 11,
      "name": "Cranberry (Pms209)"
    }, {
      "hex": "990033",
      "id": 12,
      "name": "Maroon (Pms202)"
    }, {
      "hex": "990000",
      "id": 13,
      "name": "Burgundy (Pms195)"
    }, {
      "hex": "003300",
      "id": 14,
      "name": "School Bottle Green"
    }, {
      "hex": "1d4012",
      "id": 15,
      "name": "Sport Bottle Green (Pms350)"
    }, {
      "hex": "12872b",
      "id": 16,
      "name": "Emerald Green (Pms347u)"
    }, {
      "hex": "336648",
      "id": 17,
      "name": "Sage Green (Pms5545)"
    }, {
      "hex": "089770",
      "id": 18,
      "name": "Leaf Green (Pms569)"
    }, {
      "hex": "e26b0a",
      "id": 19,
      "name": "Orange (Pms021)"
    }, {
      "hex": "ffc000",
      "id": 20,
      "name": "Gold (Pms1375)"
    }, {
      "hex": "ffff00",
      "id": 21,
      "name": "Sunshine (Pms1225c)"
    }, {
      "hex": "ffff66",
      "id": 22,
      "name": "Sunburst Pms115c)"
    }, {
      "hex": "a6a6a6",
      "id": 23,
      "name": "Grey (Pms Cool Grey 6c)"
    }, {
      "hex": "404040",
      "id": 24,
      "name": "Charcoal Pms432)"
    }, {
      "hex": "7030a0",
      "id": 25,
      "name": "Purple (Pms2613)"
    }, {
      "hex": "d40082",
      "id": 26,
      "name": "Hot Pink (Pms Magenta)"
    }, {
      "hex": "ffc2cc",
      "id": 27,
      "name": "Baby Pink (196u)"
    }, {
      "hex": "ffffe5",
      "id": 28,
      "name": "Cream"
    }, {
      "hex": "704626",
      "id": 29,
      "name": "Brown (Pms731)"
    }, {
      "hex": "351f16",
      "id": 30,
      "name": "Chocolate (Pms476)"
    }, {
      "hex": "d40082",
      "id": 31,
      "name": "Hot Pink (Pms Magenta)"
    }, {
      "hex": "ffc2cc",
      "id": 32,
      "name": "Baby Pink (196u)"
    }, {
      "hex": "ffffe5",
      "id": 33,
      "name": "Cream"
    }, {
      "hex": "ff0000",
      "id": 34,
      "name": "Red (Pms200)"
    }, {
      "hex": "a50021",
      "id": 35,
      "name": "Cranberry (Pms209)"
    }, {
      "hex": "990033",
      "id": 36,
      "name": "Maroon (Pms202)"
    }]
  });
li a {
  width: 50px;
  height: 10px;
  display: inline-block;
  border: 1px solid black;
}
li.active a {
  width: 150px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<ul ng-app="app" ng-controller="Ctrl" class="picker-dropdown list-inline form-control">
  <li ng-repeat="colour in controller.colours.data" ng-class="{'active': controller.team.data.tmp.indexOf(colour.id) > -1}">
    <a href style="background-color: #{{ colour.hex }};" ng-click="controller.setColour(colour)"></a>
  </li>
</ul>

Custom match function

If you don't wish to tamper with the original objects, you can make your own colour compare function and use it instead, for example:

$scope.matchColours = function(colourList, targetCol) {
  for(var i = 0; i < colourList.length; i++) {
      if (colourList[i].id === targetCol.id) {
          return true; // colour match found
      }
  }
  return false;
}

And then your ng-class could look something like this:

ng-class="{'active': matchColours(controller.team.data.colours, colour)}"

See it in action:

angular.module('app', [])
  .controller('Ctrl', function($scope) {
  
    $scope.matchColours = function(colourList, targetCol) {
      for (var i = 0; i < colourList.length; i++) {
        if (colourList[i].id === targetCol.id) {
          return true; // colour match found
        }
      }
      return false;
    }


    $scope.controller = {};
    $scope.controller.team = {
      loading: false,
      data: {
        id: 0,
        name: 'Test',
        sport: '',
        colours: [{
          id: 31,
          name: 'Hot Pink (Pms Magenta)',
          hex: 'd40082'
        }, {
          id: 32,
          name: 'Baby Pink (196u)',
          hex: 'ffc2cc'
        }, {
          id: 33,
          name: 'Cream',
          hex: 'ffffe5'
        }]
      }
    };
    $scope.controller.colours = {};
    $scope.controller.colours.data = [{
      "hex": "000000",
      "id": 1,
      "name": "Black"
    }, {
      "hex": "ffffff",
      "id": 2,
      "name": "White"
    }, {
      "hex": "001444",
      "id": 3,
      "name": "School Navy Blue"
    }, {
      "hex": "000e31",
      "id": 4,
      "name": "Sport Navy Blue Pms 532"
    }, {
      "hex": "003072",
      "id": 5,
      "name": "Royal Blue (Pms286)"
    }, {
      "hex": "83cce4",
      "id": 6,
      "name": "Pale Blue (Pms292)"
    }, {
      "hex": "051667",
      "id": 7,
      "name": "Reflex Blue (Pms Ref Blu)"
    }, {
      "hex": "0080bc",
      "id": 8,
      "name": "Cyan Blue (Process Cyan)"
    }, {
      "hex": "004066",
      "id": 9,
      "name": "Petrol Blue (Pms3035)"
    }, {
      "hex": "ff0000",
      "id": 10,
      "name": "Red (Pms200)"
    }, {
      "hex": "a50021",
      "id": 11,
      "name": "Cranberry (Pms209)"
    }, {
      "hex": "990033",
      "id": 12,
      "name": "Maroon (Pms202)"
    }, {
      "hex": "990000",
      "id": 13,
      "name": "Burgundy (Pms195)"
    }, {
      "hex": "003300",
      "id": 14,
      "name": "School Bottle Green"
    }, {
      "hex": "1d4012",
      "id": 15,
      "name": "Sport Bottle Green (Pms350)"
    }, {
      "hex": "12872b",
      "id": 16,
      "name": "Emerald Green (Pms347u)"
    }, {
      "hex": "336648",
      "id": 17,
      "name": "Sage Green (Pms5545)"
    }, {
      "hex": "089770",
      "id": 18,
      "name": "Leaf Green (Pms569)"
    }, {
      "hex": "e26b0a",
      "id": 19,
      "name": "Orange (Pms021)"
    }, {
      "hex": "ffc000",
      "id": 20,
      "name": "Gold (Pms1375)"
    }, {
      "hex": "ffff00",
      "id": 21,
      "name": "Sunshine (Pms1225c)"
    }, {
      "hex": "ffff66",
      "id": 22,
      "name": "Sunburst Pms115c)"
    }, {
      "hex": "a6a6a6",
      "id": 23,
      "name": "Grey (Pms Cool Grey 6c)"
    }, {
      "hex": "404040",
      "id": 24,
      "name": "Charcoal Pms432)"
    }, {
      "hex": "7030a0",
      "id": 25,
      "name": "Purple (Pms2613)"
    }, {
      "hex": "d40082",
      "id": 26,
      "name": "Hot Pink (Pms Magenta)"
    }, {
      "hex": "ffc2cc",
      "id": 27,
      "name": "Baby Pink (196u)"
    }, {
      "hex": "ffffe5",
      "id": 28,
      "name": "Cream"
    }, {
      "hex": "704626",
      "id": 29,
      "name": "Brown (Pms731)"
    }, {
      "hex": "351f16",
      "id": 30,
      "name": "Chocolate (Pms476)"
    }, {
      "hex": "d40082",
      "id": 31,
      "name": "Hot Pink (Pms Magenta)"
    }, {
      "hex": "ffc2cc",
      "id": 32,
      "name": "Baby Pink (196u)"
    }, {
      "hex": "ffffe5",
      "id": 33,
      "name": "Cream"
    }, {
      "hex": "ff0000",
      "id": 34,
      "name": "Red (Pms200)"
    }, {
      "hex": "a50021",
      "id": 35,
      "name": "Cranberry (Pms209)"
    }, {
      "hex": "990033",
      "id": 36,
      "name": "Maroon (Pms202)"
    }]
  });
li a {
  width: 50px;
  height: 10px;
  display: inline-block;
  border: 1px solid black;
}
li.active a {
  width: 150px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<ul ng-app="app" ng-controller="Ctrl" class="picker-dropdown list-inline form-control">
  <li ng-repeat="colour in controller.colours.data" ng-class="{'active': matchColours(controller.team.data.colours, colour)}">
    <a href style="background-color: #{{ colour.hex }};" ng-click="controller.setColour(colour)"></a>
  </li>
</ul>
Shomz
  • 37,421
  • 4
  • 57
  • 85
  • There is nothing wrong with using objects with `indexOf` – Sulthan Apr 10 '15 at 12:53
  • All right, forgot that javascript uses `===` for comparison. The problem is not with the use of objects though, the problem is the objects are not equal to each other. – Sulthan Apr 10 '15 at 12:57
  • Actually, the nature of JS objects is the problem - although they have exactly the same properties, they are not treated as the same objects in JS. And array indices are integers. – Shomz Apr 10 '15 at 12:58
  • @Shomz the MatchColour method is what I will use. The reason for this is that both colours and team are pulled from the database, so I can't really edit the data (well I could, but I don't want to :)). Anyway, you posted a solution that will work so I have marked your answer. – r3plica Apr 10 '15 at 13:27
  • Well, you could simply iterate the data in your controller, and create that tmp object - it doesn't even have to be under `$scope.controller.team.data`, but simply `$scope.ids` or something... so that way the original object would remain intact... with just a single line of code in a loop (I hardcoded it for snippet simplicity). Both solutions are fine to me, but choose whatever you like more. :) Ideally, your team data should contain only the id or the hex value, no need for the whole object. – Shomz Apr 10 '15 at 13:29