Detected changes on items of observable array

by Jorge Bustos Pereda

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<div data-bind="foreach: vals">
  <div>
    n:<span data-bind="text: n"></span>&nbsp;
    valid:<span data-bind="text: valid"></span> 
  </div>
</div>
<div data-bind="css: {green: allValid, red: !allValid()}"
  style="padding: 5px 5px; margin: 10px 0;">
    <b>All valid:<span data-bind="text: allValid"></span></b>
</div>
<div>
  <input type="text" data-bind="value: n">
  <input type="button" value="Make valid" data-bind="click: make1Valid">
  <input type="button" value="Make not valid" data-bind="click: make1NotValid">
  <br/><br/>
  <input type="button" value="Push valid" data-bind="click: pushValid">   <input type="button" value="Push not valid" data-bind="click: pushNotValid">
  <input type="button" value="Pop" data-bind="click: pop">
</div>

CSS

.green {
  background-color: #55FF55;
}
.red {
  background-color: #FF5555;
}

JavaScript

var vm = {
    vals: ko.observableArray([
        { n: 0, valid: ko.observable(true) }, 
        { n: 1, valid: ko.observable(false) },
        { n: 2, valid: ko.observable(true) }
    ]),
    n: ko.observable(1)
};

vm.allValid = ko.computed(function() {
    var valid = true;
    // make dependen on observable array
    var vals = vm.vals(); 
    // make dependent on all the items
    for (var i = 0; i<vals.length; i++) {
        valid = valid && vals[i].valid();
    }
    return valid;
});

vm.make1Valid = function() {
	vm.vals()[vm.n()].valid(true);
}

vm.make1NotValid = function() {
	vm.vals()[vm.n()].valid(false);
}

vm.pushValid = function() {
  vm.vals.push({n: vm.vals().length, valid:ko.observable(true)});
}

vm.pushNotValid = function() {
  vm.vals.push({n: vm.vals().length, valid:ko.observable(false)});
}

vm.pop = function() {
  vm.vals.pop();
}


ko.applyBindings(vm);