asdzxcyykk
asdzxcyykk

Reputation: 69

Angularjs remove table row with different background color in odd even selected row

I have a table with different background color in odd even row, also there is different background color for selected row. A button to remove the object in array that bind with the table data.

The problem is when I remove the first row of the table or array, the new first row background color(which is selected) did not change to selected background color (I think it remain the previous css class). But when I remove other row, nothing went wrong, the new selected row has background color as intended.

var app = angular.module("myApp", []);
app.controller("aCtrl", function($scope, $http) {

  $scope.arr_obj = [{
      "num": 1,
      "title": "abc",
    },

    {
      "num": 2,
      "title": "def"
    },

    {
      "num": 3,
      "title": "ghi"
    },

    {
      "num": 4,
      "title": "lmn"
    },

    {
      "num": 5,
      "title": "opq"
    }

  ];

  $scope.selectedId = 0;

  $scope.setindex = function(id) {
    $scope.selectedId = id;

  }

  $scope.remove_click = function() {
    if ($scope.arr_obj.length >= 1) {
      $scope.arr_obj.splice($scope.selectedId, 1);
      if ($scope.arr_obj.length >= 1) {
        if ($scope.selectedId >= 1) {
          $scope.selectedId = $scope.selectedId - 1;
        } else {
          $scope.selectedId = 0;
        }
        console.log($scope.selectedId);
      }
    }
  }


  $scope.ClassOdd = function(id) {
    if (id === $scope.selectedId)
      return "selected";
    else
      return "odd";
  };

  $scope.ClassEven = function(id) {
    if (id === $scope.selectedId)
      return "selected";
    else
      return "even";

  };
});
table,
th,
td {
  border: 1px solid black;
}
.selected {
  background-color: pink;
}
.odd {
  background-color: green;
}
.even {
  background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js">
</script>
<div ng-app="myApp" ng-controller="aCtrl" class="main">

  <div>
    <table>

      <tr>
        <th>title</th>
        <th>checkbox</th>
      </tr>

      <tr ng-repeat="row in arr_obj" ng-click="setindex($index)" ng-class-odd="ClassOdd($index)" ng-class-even="ClassEven($index)">
        <td>{{row.num}}</td>
        <td>{{row.title}}</td>
      </tr>

    </table>
  </div>

  <input type="button" value="Remove" ng-click="remove_click($index)">
  <p>current selectedId = {{selectedId}}
    <p>
</div>

https://jsfiddle.net/jx8ztcum/

May I know how this happens? Is there any solution for this?

Upvotes: 1

Views: 846

Answers (1)

kukkuz
kukkuz

Reputation: 42352

You can solve this by adding the track by expression to your ng-repeat.

Why track by

track by is used to link your data with the DOM made by ng-repeat- this could be useful for paging, filtering, adding/removing from the ng-repeat list.

(without track by angular links the DOM with the collection by injecting a $$hashKey property into the ng-repeat collection, and will regenerate it with any change in the collection)

See demo below and Updated fiddle here:

var app = angular.module("myApp", []);
app.controller("aCtrl", function($scope, $http) {

  $scope.arr_obj = [{"title": "abc"},{"title": "def"},{"title": "ghi"},{"title": "lmn"},{"title": "opq"}];

  $scope.selectedId = 0;

  $scope.setindex = function(id) {
    $scope.selectedId = id;
  }

  $scope.remove_click = function() {
    if ($scope.arr_obj.length >= 1) {
      $scope.arr_obj.splice($scope.selectedId, 1);
      if ($scope.arr_obj.length >= 1) {
        if ($scope.selectedId >= 1) {
          $scope.selectedId = $scope.selectedId - 1;
        } else {
          $scope.selectedId = 0;
        }
        console.log($scope.selectedId);
      }
    }
  }


  $scope.ClassOdd = function(id) {
    if (id === $scope.selectedId)
      return "selected";
    else
      return "odd";
  };

  $scope.ClassEven = function(id) {
    if (id === $scope.selectedId)
      return "selected";
    else
      return "even";
  };
});
table,
th,
td {
  border: 1px solid black;
}
.selected {
  background-color: pink;
}
.odd {
  background-color: green;
}
.even {
  background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="aCtrl" class="main">
  <div>
    <table>
      <tr>
        <th>num</th>
        <th>title</th>
      </tr>
      <tr ng-repeat="row in arr_obj track by $index" ng-click="setindex($index)" ng-class-odd="ClassOdd($index)" ng-class-even="ClassEven($index)">
        <td>{{$index}}</td>
        <td>{{row.title}}</td>
      </tr>
    </table>
  </div>
  <input type="button" value="Remove" ng-click="remove_click($index)">
  <p>current selectedId = {{selectedId}}<p>
</div>

Upvotes: 2

Related Questions