Vishnu Y S
Vishnu Y S

Reputation: 193

Angular ng-change not working for checkboxes

Here is my code below. The ng-change of individual checkboxes is not getting triggered when it is changed by clicking Select All button but it is getting triggered when it's selected individually. I need the itemChecked method to be triggered when the Select All button is clicked.

Here is a Codepen Link for the same

HTML

<div ng-app="Test">
  <div ng-controller="TestController">
    <form>
      <div ng-repeat="item in list track by $index">
        <input type="checkbox" ng-model="item" ng-change="itemChecked($index)">{{$index + 1}}
      </div>
    </form>
    <button ng-click="toggleSelection()">Select all</button>
  </div>
</div>

JavaScript

var app = angular.module("Test", []);
app.controller("TestController", [
  "$scope",
  "$http",
  function($scope, $http) {
    $scope.list = [false, false, false, false, false];

    $scope.itemChecked = function(i) {
      console.log(i);
    };

    $scope.toggleSelection = function() {
      for (var i in $scope.list) {
        $scope.list[i] = true;
      }
    };
  }
]);

Please let me know what I need to change or what I am doing wrong to fix this.

Upvotes: 1

Views: 5747

Answers (3)

Akshay Dorkhande
Akshay Dorkhande

Reputation: 1

Try using ng-click instead of ng-change.

Upvotes: -1

JPS
JPS

Reputation: 2760

What you need is watchCollection method. ngChange works only if the value is changed from HTML. It is not triggered when the value is changed from controller.

app.controller("TestController", [
  "$scope",
  "$http",
  function($scope, $http) {
    $scope.list = [false, false, false, false, false];

    $scope.itemChecked = function(i) {
      console.log(i);
    };

    $scope.toggleSelection = function() {
      for (var i in $scope.list) {
        $scope.list[i] = true;
      }
    };


    /*********************************************************/        
    $scope.$watchCollection('list', function (newVal, oldVal) {   
           console.log('collection changed') });
    }
   /*********************************************************/      

]);

Or If you just want itemChecked method to be called whenever the selectAll button is clicked, Then just call itemChecked inside toggleSelection method.

$scope.toggleSelection = function() {
      for (var i in $scope.list) {
        $scope.list[i] = true;
        $scope.itemChecked(i);
      }
    };

Upvotes: 2

I. Ahmed
I. Ahmed

Reputation: 2534

You have set wrong variable in ng-model. The ng-model section should be:

ng-model="list[$index]"

To listen the collection, you have to use the following:

$scope.$watchCollection

It is working perfectly in the following code, check the code snippet:

var app = angular.module("Test", []);
app.controller("TestController", [
  "$scope",
  "$http",
  function($scope, $http) {
    $scope.list = [false, false, false, false, false];
    $scope.itemChecked = function(i) {
      console.log(i);
      console.log($scope.list[i]);
    };
    $scope.$watchCollection('list', function (oldValue, newValue) {
    //console.log(oldValue);
    //console.log(newValue);
    //console.log($scope.list);
    for(var i = 0; i < oldValue.length;i++){
      if (oldValue[i]!==newValue[i]) {
         $scope.itemChecked(i);
      }
    }
    });
    $scope.toggleSelection = function() {
      for (var i in $scope.list) {
        $scope.list[i] = true;
      }
    };
  }
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="Test">
  <div ng-controller="TestController">
    <form>
      <div ng-repeat="item in list track by $index">
        <input type="checkbox" ng-model="list[$index]" ng-change="itemChecked($index)">{{$index + 1}}
      </div>
    </form>
    <button ng-click="toggleSelection()">Select all</button>
  </div>
</div>

Upvotes: 1

Related Questions