2

What I'm trying to achieve is to check some checkboxes belonging to a ng-repeat loop iteration when I check a "master" checkbox. My code so far in the view:

<div ng-app="CheckAllModule">
    <div ng-controller="checkboxController">
        <ul ng-repeat="s in struct">
            <li><strong>{{s}} item</strong>
                <input type="checkbox" ng-checked="x1 && x2 && x3" ng-model="selectedAll" ng-click="checkAll()" />
            </li>
            <label>Subitem A
                <input type="checkbox" ng-checked="chk" ng-model="x1" />
            </label>
            <label>Subitem B
                <input type="checkbox" ng-checked="chk" ng-model="x2" />
            </label>
            <label>Subitem C
                <input type="checkbox" ng-checked="chk" ng-model="x3" />
            </label>
        </ul>
    </div>
</div>

Where the first checkbox is the "master" and should impose its own state to the "slaves" (the next three checkboxes), no matter what was their previous state.

Regarding to the slave checkboxes, they should be checked & unchecked indepently. But If the three are checked at the same time, the master should be too. Whenever only one of them is not checked, the master shouldn't be as well.

And my controller:

var app = angular.module("CheckAllModule", []);
app.controller("checkboxController", function ($scope) {
    $scope.struct = ['First', 'Second'];
    $scope.checkAll = function () {
        if ($scope.selectedAll) {
            $scope.chk = true;
        } else {
            $scope.chk = false;
        }
    };
});

2 Answers 2

3

This almost certainly doesn't follow best practices but I'm a noob with Angular. It does work though:

http://plnkr.co/edit/oGNC3ZUZHDHrBrMyRKjW?p=preview

var app = angular.module("CheckAllModule", []);
app.controller("checkboxController", function($scope) {
  $scope.struct = ['First', 'Second'];
  $scope.checkAll = function(selected, chkArray) {
    for (var chk in chkArray) {
      chkArray[chk] = selected
    }
  };
});

I made some adjustments to your html to get this working:

<div ng-app="CheckAllModule">
  <div ng-controller="checkboxController">
    <ul ng-repeat="s in struct" data-ng-init="x[1]=false;x[2]=false;x[3]=false">
      <li>
        <strong>{{s}} item</strong>
        <input type="checkbox" ng-checked="x[1] && x[2] && x[3]" ng-model="selectedAll" ng-click="checkAll(selectedAll, x)" />
      </li>
      <label>Subitem A
        <input type="checkbox" ng-model="x[1]" />
      </label>
      <label>Subitem B
        <input type="checkbox" ng-model="x[2]" />
      </label>
      <label>Subitem C
        <input type="checkbox" ng-model="x[3]" />
      </label>
    </ul>
  </div>
</div>

Update

I was thinking about how better to test x1 && x2 && x3 the conversion to an array was the first step but then you can do:

x.indexOf(false)

(Ideally you would use .reduce(function(a,b) { return a && b; }) but reduce is not yet well enough supported and to be fair, it's a bit more clunky) - strangely this is not working yet.

Sign up to request clarification or add additional context in comments.

1 Comment

@luisddm glad to hear it, KreepN's note (below) to use dot notation is worth giving heed to.
2

Working Plunkr Here

As a note, you should always try to bind to something using dot notation.

<ul ng-repeat="s in struct track by $index">
      <li>
        <strong>{{s.Item}} item</strong>
        <input type="checkbox" ng-click="checkAll(s.selectedAll,$index)" ng-model="s.selectedAll" ng-checked="s.x1 && s.x2 && s.x3" />
      </li>
      <label>Subitem A
        <input type="checkbox" ng-checked="s.chk" ng-model="s.x1" />
      </label>
      <label>Subitem B
        <input type="checkbox" ng-checked="s.chk" ng-model="s.x2" />
      </label>
      <label>Subitem C
        <input type="checkbox" ng-checked="s.chk" ng-model="s.x3" />
      </label>
    </ul>

The situation you have here is that you ng-repeat is bound to a list of strings. You should know that when repeating on a collection each item then would have it's own scope and maintain their values independently. This is hard to do since you can not add these values to a string (you need to bind to an object that can be expanded on).

I have made the adjustments that would allow for this particular setup. It should be agreeable as minor changes have been made.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.