简体   繁体   中英

Select and deselect all check-boxes on click in AngularJs

I am having difficulties in understanding how to find out if some checkbox is selected or not in Angular.

This is the problem:

I have simple HTML table, on ng-change event I am calling one function that need to check if 'select all' checkbox is checked:

This is HTML:

<table class="table table-striped">
    <thead>
        <tr class="table-header">
            <th ng-if="!newTestSessionCtrl.formData.battery.id"><input type="checkbox" ng-model="selectedAll" ng-change="newTestSessionCtrl.isSelectAll()" /></th>
            <th>Test</th>
            <th>Available Time</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="row in newTestSessionCtrl.formData.battery.testDefinitions">
            <td ng-if="!newTestSessionCtrl.formData.battery.id"><input type="checkbox" ng-model="row.selected" ng-change="newTestSessionCtrl.isLabelChecked(); newTestSessionCtrl.validate()" /></td>
            <td>{{row.name}}</td>
            <td>{{(row.duration / 60) | number:0}} minutes</td>
        </tr>
    </tbody>
</table>

The name of model is: selectedAll

I have two functions, first one should be use for select all and deselect:

isSelectAll() {
    let self = this;
    self.model.selectedLabelList = [];
    if(self.selectedAll) {
        self.selectedAll = true;
        for(var i=0; i < self.formData.battery.testDefinitions.length; i++) {
            self.model.selectedLabelList.push(self.formData.battery.testDefinitions[i].name);       
        }
    }
    else { 
        self.selectedAll = false; 
    }
    angular.forEach(self.formData.battery.testDefinitions, function(item) {
        item.selected = self.selectedAll;
    });
}

And the other one for un-checking 'select all' checkbox if one of the check boxes is deselected manual are this:

isLabelChecked() {
    let self = this;
    let _name = this.formData.battery.name;
    if(this.formData.battery.selected) {
        self.model.selectedLabelList.push(_name);
        if(self.model.selectedLabelList.length == self.labelList.length ) {
            self.selectedAll = true;
        }
    }else{
        self.selectedAll = false;
        let index = self.model.selectedLabelList.indexOf(_name);
        self.model.selectedLabelList.splice(index, 1);
    }
}  

The problem is when defining selectedAll in js file.

I have constructor and if I do not define anything in it, selectedAll won't be in scope.

If I do this:

class NewTestSessionController {
    constructor($scope, $state, resources, NewTestSessionService, formats, AuthenticationService, toastr, momentTimezone, _) {
        this.model = {
            selectedLabelList : []
        };

        this.selectedAll;
}

selectedAll will be in scope, but I will get 'false' value always. No matter if I have selected or deselected checkbox. If I assign some value like this this.selectedAll = true it won't be working correctly of course.

I have problem understanding why ng-model="selectedAll" is not visible and how can I make it visible in js file, without using $scope , since the main goal of my practice is to avoid usage of it.

Can someone see where I am making a mistake?

This is a common problem with AngularJS which uses prototypal inheritance between scopes. ng-if directive creates a new scope (call it $scope2) that inherit your controller's $scope. In this new scope you can access selectedAll , but if you assign it (the ng-model directive does), the new value will be set on $scope2, and so $scope2.selectedAll will hide $scope.selectedAll.

Moreover, this.selectedAll; has strictly no effect, you have to assign it to define the property.

To avoid these two issues, put selectedAll in an object, and assign it, like this:

this.model.selectedAll = null; and ng-model="model.selectedAll"

Explanation

The reason why putting it in an object works is because assigning $scope2.model.selectedAll will make JS resolve $scope2.model , which refers to $scope.model because $scope2 has no model property (prototypal inheritance), and then define property selectedAll on that $scope.model .

When you do abcd = x JS resolves abc object, and then assign x to the property d of that object.

Whithout model , $scope2.selectedAll = true defines the selectedAll property on $scope2 , which hides the former $scope.selectedAll .

Click here for best solution.

http://jsfiddle.net/TKVH6/2672/

HTML

<div ng-controller="checkboxController">
Check All
<input type="checkbox" ng-model="selectedAll" ng-click="checkAll()" />
<ul>        
  <li ng-repeat="item in Items">
    <label>{{item.Name}}
      <input type="checkbox" ng-model="item.Selected" />
    </label>
  </li>
</ul>
</div>

Script

angular.module("CheckAllModule", [])
    .controller("checkboxController", function checkboxController($scope) {
    $scope.Items = [{
        Name: "Item one"
    }, {
        Name: "Item two"
    }, {
        Name: "Item three"
    }];
    $scope.checkAll = function () {
        if ($scope.selectedAll) {
            $scope.selectedAll = true;
        } else {
            $scope.selectedAll = false;
        }
        angular.forEach($scope.Items, function (item) {
            item.Selected = $scope.selectedAll;
        });
    };
});

 var myapp = angular.module('sampleapp', []); myapp.controller('samplecontoller', function ($scope) { $scope.labelList = [ { name: 'India' }, { name: 'USA' }, { name: 'Russia' }, { name: 'China' }, { name: 'Australia' }, { name: 'Japan' } ] $scope.model = { selectedLabelList: [] } $scope.isSelectAll = function () { $scope.model.selectedLabelList = []; if ($scope.master) { $scope.master = true; for (var i = 0; i < $scope.labelList.length; i++) { $scope.model.selectedLabelList.push($scope.labelList[i].name); } } else { $scope.master = false; } angular.forEach($scope.labelList, function (item) { item.selected = $scope.master; }); } $scope.isLabelChecked = function () { var _name = this.label.name; if (this.label.selected) { $scope.model.selectedLabelList.push(_name); if ($scope.model.selectedLabelList.length == $scope.labelList.length) { $scope.master = true; } } else { $scope.master = false; var index = $scope.model.selectedLabelList.indexOf(_name); $scope.model.selectedLabelList.splice(index, 1); } } }); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="sampleapp" ng-controller="samplecontoller"> <input type="checkbox" ng-model="master" ng-change="isSelectAll()"><label>All Countries</label><br> <li ng-repeat="label in labelList"> <input type="checkbox" ng-model="label.selected" ng-change="isLabelChecked()"> <label>{{ label.name }}</label> </li> </div> 

This is example just fallow this code .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM