Search code examples
angularjsangular-controller

How to apply CSS active class to an item of three independent lists?


How to apply a CSS active class to one item of three lists? I get a list of objects from server. These objects has a property of type list. Here is a similar object.

[
    {
        name: 'europe',
        countries: ["Englad", "France", "Germany", "Italy"]
    }, {
        name: 'asia',
        countries: ["Japan", "China", "Iran", "Korea"]
    }, {
        name: 'Africa',
        countries: ["Somalia", "Egypt", "Ghana"]
    },
]; 

By default, the first item of the lists is selected. When the user clicks an another item, it should be selected without affecting the items of other lists.

Some information that might help.

  • The object is above is just an example. In future, I may get a list of more than three objects.

  • There is only one controller.

  • Each one of the countries has an 'id', but I have not included.

  • Here is an exmpale of this object on jsfiddle JSFiddle

Thank you so much.


Solution

  • Basically you would create an object to hold the selection, as you mentionned your data is variable the selection object generation should be dynamic. To do so I've taken advantage of the ECMAScript 2015 objects computed property names, there is more info on MDN for Object Initializer.

    Having a default selection requires initialization as well.

    Based on your fiddle, here's the html

    <div ng-app ng-controller="ContinentController">
      <ul>
        <li ng-repeat="continent in continents">
          <h2>{{continent.name}}</h2>
          <ul>
            <li ng-repeat="country in continent.countries">
              <span ng-class="{active: selected[continent.name] === $index}" 
                    ng-click="select(continent.name, $index)">{{country}}</span>
            </li>
          </ul>
        </li>
      </ul>
    </div>
    

    And the controller

    function ContinentController($scope) {
      $scope.continents = [{
        name: 'europe',
        countries: ["Englad", "France", "Germany", "Italy"]
      }, {
        name: 'asia',
        countries: ["Japan", "China", "Iran", "Korea"]
      }, {
        name: 'Africa',
        countries: ["Somalia", "Egypt", "Ghana"]
      }, ];
    
      $scope.selected = {};
      $scope.select = select;
    
      initializeSelection();
    
      function initializeSelection() {
        for (var i = 0; i < $scope.continents.length; i++) {
          $scope.selected[$scope.continents[i].name] = 0;
        }
      }
    
      function select(name, index) {
        $scope.selected[name] = index;
      }
    }
    

    Here's the working fiddle.

    Now this assumes all you names are unique. Since you mentionned you have ids, if they are unique then using them as key instead of the name property would definitely be better.