How to disable a button when click in ng-repeat?

I want to disable the button when clicked then if clicked to another button the previous disable button will be active then the current button will be disable and so on and so forth

HTML

<div ng-controller="ModalDemoCtrl">
    <button ng-repeat="item in items track by $index" ng-click="test($index);" ng-disabled="dis[$index]">
       {{item.Name}}
    </button>
</div>

CODE

$scope.items = [{ Name: 'apple' }, { Name: 'banana' }, { Name: 'carrot' }, { Name: 'drumstick' }, { Name: 'egg' }];
$scope.test = function(i){
  $scope.dis[i] = true;
}

This code will give me this error

TypeError: Cannot set property '2' of undefined
    at copywriter-angular.js?ver=1.2:1234
    at angular.min.js?ver=4.8:134
    at m.$digest (angular.min.js?ver=4.8:145)
    at m.$apply (angular.min.js?ver=4.8:149)
    at l (angular.min.js?ver=4.8:102)
    at XMLHttpRequest.A.onload (angular.min.js?ver=4.8:107) "Possibly unhandled rejection: {}"

Upvotes: 1

Views: 739

Answers (2)

Aleksey Solovey
Aleksey Solovey

Reputation: 4191

I think you have a wrong logic. Instead of having a separate array to disable the buttons, you need to expand the array of objects with disabled property, e.g. ng-disabled="item.disabled".

But if you want a separate array, here is how you would initialise it, because otherwise it's empty and so you can't access dis[index] to disable the button.

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
  $scope.items = [{
    Name: 'apple'
  }, {
    Name: 'banana'
  }, {
    Name: 'carrot'
  }, {
    Name: 'drumstick'
  }, {
    Name: 'egg'
  }];
  $scope.dis = $scope.items.map((_) => {
    return false;
  });
  $scope.test = function(i) {
    $scope.dis[i] = true;
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>

<div ng-app="myApp" ng-controller="myCtrl">
  <button ng-repeat="item in items track by $index" ng-click="test($index);" ng-disabled="dis[$index]">
    {{item.Name}}
  </button>
</div>

Here is a solution that you should be using instead. This time the object has an additional property that you can easily access.

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
  $scope.items = [{
    Name: 'apple',
    disabled: false
  }, {
    Name: 'banana',
    disabled: false
  }, {
    Name: 'carrot',
    disabled: false
  }, {
    Name: 'drumstick',
    disabled: false
  }, {
    Name: 'egg',
    disabled: false
  }];
  $scope.test = function(i) {
    $scope.items[i].disabled = true;
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>

<div ng-app="myApp" ng-controller="myCtrl">
  <button ng-repeat="item in items track by $index" ng-click="test($index);" ng-disabled="item.disabled">
    {{item.Name}}
  </button>
</div>

Upvotes: 1

Kaustubh Khare
Kaustubh Khare

Reputation: 3510

Just define $scope.dis above test funtion.

$scope.dis= [];
$scope.test = function(i){
  $scope.dis[i] = true;
}

Upvotes: 3

Related Questions